PaperMC/Spigot-Server-Patches/0382-Add-LivingEntity-getTargetEntity.patch
Zach Brown db6d9b0522
Update armorstand pose and equipment w/ no tick option
This change allows ArmorStands with ticking disabled to visually update
their equipment and pose properly.

Given the wide range of usage of ArmorStands, I have not changed
their tick loop when their tick is enabled as usual. Doing so may
likely gains in the future, though additional testing would be
needed to ensure nothing breaks.

Fixes GH-1593
2018-11-07 21:27:41 -05:00

184 lines
8.7 KiB
Diff

From e43e19ddbebb2d46b4c2a09a850c958beba89093 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <Blake.Galbreath@GMail.com>
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 19819b134..49228a884 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.minX;
double d4 = this.minY;
@@ -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.minX - d0;
double d4 = this.minY - d1;
@@ -184,6 +191,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);
}
@@ -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 dd96b09e6..d60dab95f 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -1519,6 +1519,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);
@@ -2182,10 +2183,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 83d648fff..a845856af 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;
@@ -2861,6 +2865,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<Entity> 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 42b3d3fc5..61806bbc4 100644
--- a/src/main/java/net/minecraft/server/IEntitySelector.java
+++ b/src/main/java/net/minecraft/server/IEntitySelector.java
@@ -18,6 +18,7 @@ public final class IEntitySelector {
public static final Predicate<Entity> e = (entity) -> {
return !(entity instanceof EntityHuman) || !((EntityHuman)entity).isSpectator() && !((EntityHuman)entity).u();
};
+ public static Predicate<Entity> notSpectator() { return f; } // Paper - OBFHELPER
public static final Predicate<Entity> 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 eeab59379..d6a4bc64a 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<Block> getLastTwoTargetBlocks(Set<Material> transparent, int maxDistance) {
--
2.19.1