From 0000000000000000000000000000000000000000 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/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index fc64814fd2db9e0eb2b54fd79c049c01e523c97d..6506626389e5dac0907747868b210f07d0a961d0 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -2362,6 +2362,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n this.setYHeadRot(yaw); } + public final float getCollisionBorderSize() { return getPickRadius(); } // Paper - OBFHELPER public float getPickRadius() { return 0.0F; } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java index 252a935db848a1001c6109b582886a98d21941cb..8d11a803516ae711a10e9b3af7f6704f59d40874 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java @@ -116,6 +116,7 @@ import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.PlayerTeam; @@ -3729,6 +3730,38 @@ public abstract class LivingEntity extends Entity { return level.clip(raytrace); } + public EntityHitResult getTargetEntity(int maxDistance) { + if (maxDistance < 1 || maxDistance > 120) { + throw new IllegalArgumentException("maxDistance must be between 1-120"); + } + + Vec3 start = this.getEyePosition(1.0F); + Vec3 direction = this.getLookAngle(); + Vec3 end = start.add(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance); + + List entityList = level.getEntities(this, getBoundingBox().expandTowards(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance).inflate(1.0D, 1.0D, 1.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR.and(Entity::isPickable)); + + double distance = 0.0D; + EntityHitResult result = null; + + for (Entity entity : entityList) { + final double inflationAmount = (double) entity.getCollisionBorderSize(); + AABB aabb = entity.getBoundingBox().inflate(inflationAmount, inflationAmount, inflationAmount); + Optional rayTraceResult = aabb.clip(start, end); + + if (rayTraceResult.isPresent()) { + Vec3 rayTrace = rayTraceResult.get(); + double distanceTo = start.distanceToSqr(rayTrace); + if (distanceTo < distance || distance == 0.0D) { + result = new EntityHitResult(entity, rayTrace); + distance = distanceTo; + } + } + } + + return result; + } + public int shieldBlockingDelay = level.paperConfig.shieldBlockingDelay; public int getShieldBlockingDelay() { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index 05e962ed9269db4cfa170960507b10d7b7d13741..e2e76c5de41666ef3a7132e376a3e4257bb13109 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.entity; +import com.destroystokyo.paper.entity.TargetEntityInfo; import com.google.common.base.Preconditions; import com.google.common.collect.Sets; import java.util.ArrayList; @@ -210,6 +211,33 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { new com.destroystokyo.paper.block.TargetBlockInfo(org.bukkit.craftbukkit.block.CraftBlock.at(getHandle().level, ((net.minecraft.world.phys.BlockHitResult)rayTrace).getBlockPos()), net.minecraft.server.MCUtil.toBukkitBlockFace(((net.minecraft.world.phys.BlockHitResult)rayTrace).getDirection())); } + + public Entity getTargetEntity(int maxDistance, boolean ignoreBlocks) { + net.minecraft.world.phys.EntityHitResult rayTrace = rayTraceEntity(maxDistance, ignoreBlocks); + return rayTrace == null ? null : rayTrace.getEntity().getBukkitEntity(); + } + + public TargetEntityInfo getTargetEntityInfo(int maxDistance, boolean ignoreBlocks) { + net.minecraft.world.phys.EntityHitResult rayTrace = rayTraceEntity(maxDistance, ignoreBlocks); + return rayTrace == null ? null : new TargetEntityInfo(rayTrace.getEntity().getBukkitEntity(), new org.bukkit.util.Vector(rayTrace.getLocation().x, rayTrace.getLocation().y, rayTrace.getLocation().z)); + } + + public net.minecraft.world.phys.EntityHitResult rayTraceEntity(int maxDistance, boolean ignoreBlocks) { + net.minecraft.world.phys.EntityHitResult rayTrace = getHandle().getTargetEntity(maxDistance); + if (rayTrace == null) { + return null; + } + if (!ignoreBlocks) { + net.minecraft.world.phys.HitResult rayTraceBlocks = getHandle().getRayTrace(maxDistance, net.minecraft.world.level.ClipContext.Fluid.NONE); + if (rayTraceBlocks != null) { + net.minecraft.world.phys.Vec3 eye = getHandle().getEyePosition(1.0F); + if (eye.distanceToSqr(rayTraceBlocks.getLocation()) <= eye.distanceToSqr(rayTrace.getLocation())) { + return null; + } + } + } + return rayTrace; + } // Paper end @Override