From b1b6a6c4e2fb53b50a3768cb4dee35213957b4a2 Mon Sep 17 00:00:00 2001 From: BillyGalbreath Date: Mon, 8 Oct 2018 20:14:55 -0500 Subject: [PATCH] Add LivingEntity#getTargetEntity (#1467) --- ...160-Add-LivingEntity-getTargetEntity.patch | 105 ++++++++++ ...387-Add-LivingEntity-getTargetEntity.patch | 184 ++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100644 Spigot-API-Patches/0160-Add-LivingEntity-getTargetEntity.patch create mode 100644 Spigot-Server-Patches/0387-Add-LivingEntity-getTargetEntity.patch diff --git a/Spigot-API-Patches/0160-Add-LivingEntity-getTargetEntity.patch b/Spigot-API-Patches/0160-Add-LivingEntity-getTargetEntity.patch new file mode 100644 index 000000000..fd7ca0a0c --- /dev/null +++ b/Spigot-API-Patches/0160-Add-LivingEntity-getTargetEntity.patch @@ -0,0 +1,105 @@ +From cd531bb730c2417a5715286b82d97394382314d8 Mon Sep 17 00:00:00 2001 +From: BillyGalbreath +Date: Sat, 22 Sep 2018 00:32:53 -0500 +Subject: [PATCH] Add LivingEntity#getTargetEntity + + +diff --git a/src/main/java/com/destroystokyo/paper/entity/TargetEntityInfo.java b/src/main/java/com/destroystokyo/paper/entity/TargetEntityInfo.java +new file mode 100644 +index 000000000..5df8eed23 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/entity/TargetEntityInfo.java +@@ -0,0 +1,35 @@ ++package com.destroystokyo.paper.entity; ++ ++import org.bukkit.entity.Entity; ++import org.bukkit.util.Vector; ++ ++/** ++ * Represents information about a targeted entity ++ */ ++public class TargetEntityInfo { ++ private final Entity entity; ++ private final Vector hitVec; ++ ++ public TargetEntityInfo(Entity entity, Vector hitVec) { ++ this.entity = entity; ++ this.hitVec = hitVec; ++ } ++ ++ /** ++ * Get the entity that is targeted ++ * ++ * @return Targeted entity ++ */ ++ public Entity getEntity() { ++ return entity; ++ } ++ ++ /** ++ * Get the position the entity is targeted at ++ * ++ * @return Targeted position ++ */ ++ public Vector getHitVector() { ++ return hitVec; ++ } ++} +diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java +index 62e45eda2..a556586eb 100644 +--- a/src/main/java/org/bukkit/entity/LivingEntity.java ++++ b/src/main/java/org/bukkit/entity/LivingEntity.java +@@ -140,6 +140,50 @@ public interface LivingEntity extends Attributable, Entity, Damageable, Projecti + */ + @Nullable + public com.destroystokyo.paper.block.TargetBlockInfo getTargetBlockInfo(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode); ++ ++ /** ++ * Gets information about the entity being targeted ++ * ++ * @param maxDistance this is the maximum distance to scan ++ * @return entity being targeted, or null if no entity is targeted ++ */ ++ @Nullable ++ public default Entity getTargetEntity(int maxDistance) { ++ return getTargetEntity(maxDistance, false); ++ } ++ ++ /** ++ * Gets information about the entity being targeted ++ * ++ * @param maxDistance this is the maximum distance to scan ++ * @param ignoreBlocks true to scan through blocks ++ * @return entity being targeted, or null if no entity is targeted ++ */ ++ @Nullable ++ public Entity getTargetEntity(int maxDistance, boolean ignoreBlocks); ++ ++ /** ++ * Gets information about the entity being targeted ++ * ++ * @param maxDistance this is the maximum distance to scan ++ * @return TargetEntityInfo about the entity being targeted, ++ * or null if no entity is targeted ++ */ ++ @Nullable ++ public default com.destroystokyo.paper.entity.TargetEntityInfo getTargetEntityInfo(int maxDistance) { ++ return getTargetEntityInfo(maxDistance, false); ++ } ++ ++ /** ++ * Gets information about the entity being targeted ++ * ++ * @param maxDistance this is the maximum distance to scan ++ * @param ignoreBlocks true to scan through blocks ++ * @return TargetEntityInfo about the entity being targeted, ++ * or null if no entity is targeted ++ */ ++ @Nullable ++ public com.destroystokyo.paper.entity.TargetEntityInfo getTargetEntityInfo(int maxDistance, boolean ignoreBlocks); + // Paper end + + /** +-- +2.19.1 + diff --git a/Spigot-Server-Patches/0387-Add-LivingEntity-getTargetEntity.patch b/Spigot-Server-Patches/0387-Add-LivingEntity-getTargetEntity.patch new file mode 100644 index 000000000..49a387462 --- /dev/null +++ b/Spigot-Server-Patches/0387-Add-LivingEntity-getTargetEntity.patch @@ -0,0 +1,184 @@ +From 96d979c78c204068aa3d62522aac958bc544a4a9 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 624f0e3956..4cc11d0ee2 100644 +--- a/src/main/java/net/minecraft/server/AxisAlignedBB.java ++++ b/src/main/java/net/minecraft/server/AxisAlignedBB.java +@@ -102,6 +102,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.a; + double d4 = this.b; +@@ -130,6 +131,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.a - d0; + double d4 = this.b - d1; +@@ -184,6 +191,7 @@ public class AxisAlignedBB { + return this.a < d3 && this.d > d0 && this.b < d4 && this.e > d1 && this.c < d5 && this.f > 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); + } +@@ -207,6 +215,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 0c18405a8d..22fce6c362 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -1518,6 +1518,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); +@@ -2181,10 +2182,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 13dd555491..2c4b3f9c9f 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; +@@ -2859,6 +2863,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 b1d05220bf..a0c6c346b6 100644 +--- a/src/main/java/net/minecraft/server/IEntitySelector.java ++++ b/src/main/java/net/minecraft/server/IEntitySelector.java +@@ -17,6 +17,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 028495700f..b8ff4f182a 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +@@ -184,6 +184,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.19.1 +