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] Line Of Sight Changes


diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index fd2d5e274a3bf889b954bed17d286d1157cd208e..709ca3f249a5c4d3a405e94ca353864df349ffcd 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3449,7 +3449,8 @@ public abstract class LivingEntity extends Entity {
             Vec3 vec3d = new Vec3(this.getX(), this.getEyeY(), this.getZ());
             Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ());
 
-            return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS;
+            // Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
+            return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - use distanceToSqr
         }
     }
 
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 5e09816bf1aa9444df4d5480e37516623f8ce26c..8d91f0b8aee459c331ab3777e5e27c9584ff90bd 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -200,6 +200,18 @@ public class CraftWorld extends CraftRegionAccessor 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;
+        Vec3 vec3d = new Vec3(from.getX(), from.getY(), from.getZ());
+        Vec3 vec3d1 = new Vec3(to.getX(), to.getY(), to.getZ());
+        if (vec3d1.distanceToSqr(vec3d) > 128D * 128D) return false; //Return early if the distance is greater than 128 blocks
+
+        return this.getHandle().clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null)).getType() == HitResult.Type.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 8fe1f5deddfee329c020d93c990dc686fe2b458e..ca176b9331345e343c19a02b6ba2ea886d20962d 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -29,6 +29,9 @@ import net.minecraft.world.entity.projectile.ThrownEgg;
 import net.minecraft.world.entity.projectile.ThrownEnderpearl;
 import net.minecraft.world.entity.projectile.ThrownExperienceBottle;
 import net.minecraft.world.entity.projectile.ThrownTrident;
+import net.minecraft.world.level.ClipContext;
+import net.minecraft.world.phys.HitResult;
+import net.minecraft.world.phys.Vec3;
 import org.apache.commons.lang.Validate;
 import org.bukkit.FluidCollisionMode;
 import org.bukkit.Location;
@@ -557,6 +560,18 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
         return this.getHandle().hasLineOfSight(((CraftEntity) other).getHandle());
     }
 
+    // Paper start
+    @Override
+    public boolean hasLineOfSight(Location loc) {
+        if (this.getHandle().level != ((CraftWorld) loc.getWorld()).getHandle()) return false;
+        Vec3 vec3d = new Vec3(this.getHandle().getX(), this.getHandle().getEyeY(), this.getHandle().getZ());
+        Vec3 vec3d1 = new Vec3(loc.getX(), loc.getY(), loc.getZ());
+        if (vec3d1.distanceToSqr(vec3d) > 128D * 128D) return false; //Return early if the distance is greater than 128 blocks
+
+        return this.getHandle().level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this.getHandle())).getType() == HitResult.Type.MISS;
+    }
+    // Paper end
+
     @Override
     public boolean getRemoveWhenFarAway() {
         return this.getHandle() instanceof Mob && !((Mob) this.getHandle()).isPersistenceRequired();
