From 65cde9b271841fc052d367034a96e2e6c7d1a003 Mon Sep 17 00:00:00 2001 From: BillyGalbreath Date: Sat, 22 Sep 2018 00:33:08 -0500 Subject: [PATCH] Add LivingEntity#getTargetEntity diff --git a/src/main/java/net/minecraft/server/AxisAlignedBB.java b/src/main/java/net/minecraft/server/AxisAlignedBB.java index c5e541985f..d6a5c74079 100644 --- a/src/main/java/net/minecraft/server/AxisAlignedBB.java +++ b/src/main/java/net/minecraft/server/AxisAlignedBB.java @@ -95,6 +95,7 @@ public class AxisAlignedBB { return new AxisAlignedBB(d3, d4, d5, d6, d7, d8); } + public AxisAlignedBB expand(double x, double y, double z) { return b(x, y, z); } // Paper - OBFHELPER public AxisAlignedBB b(double d0, double d1, double d2) { double d3 = this.minX; double d4 = this.minY; @@ -124,6 +125,12 @@ public class AxisAlignedBB { return new AxisAlignedBB(d3, d4, d5, d6, d7, d8); } + // Paper start + public AxisAlignedBB grow(double d0) { + return grow(d0, d0, d0); + } + // Paper end + public AxisAlignedBB grow(double d0, double d1, double d2) { double d3 = this.minX - d0; double d4 = this.minY - d1; @@ -181,6 +188,7 @@ public class AxisAlignedBB { return this.minX < d3 && this.maxX > d0 && this.minY < d4 && this.maxY > d1 && this.minZ < d5 && this.maxZ > d2; } + public boolean contains(Vec3D vec3d) { return b(vec3d); } // Paper - OBFHELPER public boolean b(Vec3D vec3d) { return this.e(vec3d.x, vec3d.y, vec3d.z); } @@ -205,6 +213,7 @@ public class AxisAlignedBB { return this.g(-d0); } + public MovingObjectPosition calculateIntercept(Vec3D vec3d, Vec3D vec3d1) { return b(vec3d, vec3d1); } // Paper - OBFHELPER @Nullable public MovingObjectPosition b(Vec3D vec3d, Vec3D vec3d1) { return this.a(vec3d, vec3d1, (BlockPosition) null); diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 66947e3071..2f27af7f6e 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -1533,6 +1533,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return new Vec3D((double) (f5 * f6), (double) (-f7), (double) (f4 * f6)); } + public Vec3D getEyePosition(float partialTicks) { return i(partialTicks); } // Paper - OBFHELPER public Vec3D i(float f) { if (f == 1.0F) { return new Vec3D(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ); @@ -2196,10 +2197,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.bP().size() < 1; } + public float getCollisionBorderSize() { return aM(); } // Paper - OBFHELPER public float aM() { return 0.0F; } + public Vec3D getLookVec() { return aN(); } // Paper - OBFHELPER public Vec3D aN() { return this.d(this.pitch, this.yaw); } diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index 60aaf05475..710ad8b176 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -3,6 +3,8 @@ package net.minecraft.server; import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; import com.google.common.base.Objects; import com.google.common.collect.Maps; + +import java.util.Arrays; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Iterator; @@ -16,6 +18,8 @@ import org.apache.logging.log4j.Logger; // CraftBukkit start import java.util.ArrayList; +import java.util.stream.Collectors; + import com.google.common.base.Function; import com.google.common.collect.Lists; import org.bukkit.Location; @@ -2862,6 +2866,36 @@ public abstract class EntityLiving extends Entity { return world.rayTrace(start, end, fluidCollisionOption); } + public MovingObjectPosition getTargetEntity(int maxDistance) { + if (maxDistance < 1 || maxDistance > 120) { + throw new IllegalArgumentException("maxDistance must be between 1-120"); + } + + Vec3D start = getEyePosition(1.0F); + Vec3D direction = getLookVec(); + Vec3D end = start.add(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance); + + List entityList = world.getEntities(this, getBoundingBox().expand(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance).grow(1.0D, 1.0D, 1.0D), IEntitySelector.notSpectator().and(Entity::isInteractable)); + + double distance = 0.0D; + MovingObjectPosition rayTraceResult = null; + + for (Entity entity : entityList) { + AxisAlignedBB aabb = entity.getBoundingBox().grow((double) entity.getCollisionBorderSize()); + MovingObjectPosition rayTrace = aabb.calculateIntercept(start, end); + + if (rayTrace != null) { + double distanceTo = start.distanceSquared(rayTrace.pos); + if (distanceTo < distance || distance == 0.0D) { + rayTraceResult = new MovingObjectPosition(entity, rayTrace.pos); + distance = distanceTo; + } + } + } + + return rayTraceResult; + } + public int shieldBlockingDelay = world.paperConfig.shieldBlockingDelay; public int getShieldBlockingDelay() { diff --git a/src/main/java/net/minecraft/server/IEntitySelector.java b/src/main/java/net/minecraft/server/IEntitySelector.java index f6916fd455..71f08d53c7 100644 --- a/src/main/java/net/minecraft/server/IEntitySelector.java +++ b/src/main/java/net/minecraft/server/IEntitySelector.java @@ -19,6 +19,7 @@ public final class IEntitySelector { public static final Predicate e = (entity) -> { return !(entity instanceof EntityHuman) || !((EntityHuman) entity).isSpectator() && !((EntityHuman) entity).u(); }; + public static Predicate notSpectator() { return f; } // Paper - OBFHELPER public static final Predicate f = (entity) -> { return !(entity instanceof EntityHuman) || !((EntityHuman) entity).isSpectator(); }; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index eeab59379a..d6a4bc64ae 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -186,6 +186,33 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { net.minecraft.server.MovingObjectPosition rayTrace = getHandle().getRayTrace(maxDistance, net.minecraft.server.MCUtil.getNMSFluidCollisionOption(fluidMode)); return rayTrace == null ? null : new com.destroystokyo.paper.block.TargetBlockInfo(org.bukkit.craftbukkit.block.CraftBlock.at(getHandle().world, rayTrace.getBlockPosition()), net.minecraft.server.MCUtil.toBukkitBlockFace(rayTrace.direction)); } + + public Entity getTargetEntity(int maxDistance, boolean ignoreBlocks) { + net.minecraft.server.MovingObjectPosition rayTrace = rayTraceEntity(maxDistance, ignoreBlocks); + return rayTrace == null ? null : rayTrace.entity.getBukkitEntity(); + } + + public com.destroystokyo.paper.entity.TargetEntityInfo getTargetEntityInfo(int maxDistance, boolean ignoreBlocks) { + net.minecraft.server.MovingObjectPosition rayTrace = rayTraceEntity(maxDistance, ignoreBlocks); + return rayTrace == null ? null : new com.destroystokyo.paper.entity.TargetEntityInfo(rayTrace.entity.getBukkitEntity(), new org.bukkit.util.Vector(rayTrace.pos.x, rayTrace.pos.y, rayTrace.pos.z)); + } + + public net.minecraft.server.MovingObjectPosition rayTraceEntity(int maxDistance, boolean ignoreBlocks) { + net.minecraft.server.MovingObjectPosition rayTrace = getHandle().getTargetEntity(maxDistance); + if (rayTrace == null) { + return null; + } + if (!ignoreBlocks) { + net.minecraft.server.MovingObjectPosition rayTraceBlocks = getHandle().getRayTrace(maxDistance, net.minecraft.server.FluidCollisionOption.NEVER); + if (rayTraceBlocks != null) { + net.minecraft.server.Vec3D eye = getHandle().getEyePosition(1.0F); + if (eye.distanceSquared(rayTraceBlocks.pos) <= eye.distanceSquared(rayTrace.pos)) { + return null; + } + } + } + return rayTrace; + } // Paper end public List getLastTwoTargetBlocks(Set transparent, int maxDistance) { -- 2.20.1