diff --git a/Spigot-API-Patches/Add-more-line-of-sight-methods.patch b/Spigot-API-Patches/Add-more-line-of-sight-methods.patch
new file mode 100644
index 0000000000..e6e7e114ac
--- /dev/null
+++ b/Spigot-API-Patches/Add-more-line-of-sight-methods.patch
@@ -0,0 +1,49 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: TwoLeggedCat <80929284+TwoLeggedCat@users.noreply.github.com>
+Date: Sat, 29 May 2021 14:33:18 -0500
+Subject: [PATCH] Add more line of sight methods
+
+
+diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/World.java
++++ b/src/main/java/org/bukkit/World.java
+@@ -0,0 +0,0 @@ public interface World extends PluginMessageRecipient, Metadatable, net.kyori.ad
+      */
+     @NotNull
+     io.papermc.paper.world.MoonPhase getMoonPhase();
++
++    /**
++     * Tell whether a line of sight exists between the given locations
++     * @param from Location to start at
++     * @param to target Location
++     * @return whether a line of sight exists between {@code from} and {@code to}
++     */
++    public boolean lineOfSightExists(@NotNull Location from, @NotNull Location to);
+     // Paper end
+ 
+     /**
+diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/entity/LivingEntity.java
++++ b/src/main/java/org/bukkit/entity/LivingEntity.java
+@@ -0,0 +0,0 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
+      */
+     public boolean hasLineOfSight(@NotNull Entity other);
+ 
++    // Paper start
++    /**
++     * Checks whether the living entity has block line of sight to the given block.
++     * <p>
++     * This uses the same algorithm that hostile mobs use to find the closest
++     * player.
++     *
++     * @param location the location to determine line of sight to
++     * @return true if there is a line of sight, false if not
++     */
++    public boolean hasLineOfSight(@NotNull Location location);
++    // Paper end
++
+     /**
+      * Returns if the living entity despawns when away from players or not.
+      * <p>
diff --git a/Spigot-Server-Patches/Add-more-line-of-sight-methods.patch b/Spigot-Server-Patches/Add-more-line-of-sight-methods.patch
new file mode 100644
index 0000000000..a4a2c44f60
--- /dev/null
+++ b/Spigot-Server-Patches/Add-more-line-of-sight-methods.patch
@@ -0,0 +1,62 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: TwoLeggedCat <80929284+TwoLeggedCat@users.noreply.github.com>
+Date: Sat, 29 May 2021 14:33:25 -0500
+Subject: [PATCH] Add more line of sight methods
+
+
+diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
++++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
+@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
+         Vec3D vec3d = new Vec3D(this.locX(), this.getHeadY(), this.locZ());
+         Vec3D vec3d1 = new Vec3D(entity.locX(), entity.getHeadY(), entity.locZ());
+ 
++        // Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
+         return this.world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS;
+     }
+ 
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+@@ -0,0 +0,0 @@ public class CraftWorld implements World {
+     public io.papermc.paper.world.MoonPhase getMoonPhase() {
+         return io.papermc.paper.world.MoonPhase.getPhase(getFullTime() / 24000L);
+     }
++
++    @Override
++    public boolean lineOfSightExists(Location from, Location to) {
++        Validate.notNull(from, "from parameter in lineOfSightExists cannot be null");
++        Validate.notNull(to, "to parameter in lineOfSightExists cannot be null");
++        if (from.getWorld() != to.getWorld()) return false;
++        Vec3D vec3d = new Vec3D(from.getX(), from.getY(), from.getZ());
++        Vec3D vec3d1 = new Vec3D(to.getX(), to.getY(), to.getZ());
++
++        return this.getHandle().rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, null)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS;
++    }
+     // Paper end
+ 
+     private static final Random rand = new Random();
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
+         return getHandle().hasLineOfSight(((CraftEntity) other).getHandle());
+     }
+ 
++    // Paper start
++    @Override
++    public boolean hasLineOfSight(Location loc) {
++        if (this.getHandle().world != ((CraftWorld) loc.getWorld()).getHandle()) return false;
++        Vec3D vec3d = new Vec3D(this.getHandle().locX(), this.getHandle().getHeadY(), this.getHandle().locZ());
++        Vec3D vec3d1 = new Vec3D(loc.getX(), loc.getY(), loc.getZ());
++
++        return this.getHandle().world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this.getHandle())).getType() == MovingObjectPosition.EnumMovingObjectType.MISS;
++    }
++    // Paper end
++
+     @Override
+     public boolean getRemoveWhenFarAway() {
+         return getHandle() instanceof EntityInsentient && !((EntityInsentient) getHandle()).persistent;