From 35a7e022d35350ab5fa7e62fa8bdae65a17c0853 Mon Sep 17 00:00:00 2001 From: mcmonkey Date: Fri, 9 Nov 2018 01:26:12 -0800 Subject: [PATCH] initial attach_to offset support --- .../aufdemrand/denizen/nms/NMSHandler.java | 3 +- .../aufdemrand/denizen/objects/dEntity.java | 15 +++++-- .../denizen/nms/Handler_v1_12_R1.java | 11 +++-- .../DenizenNetworkManager_v1_12_R1.java | 43 +++++++++++++++++++ .../denizen/nms/Handler_v1_13_R2.java | 11 +++-- .../DenizenNetworkManager_v1_13_R2.java | 43 +++++++++++++++++++ 6 files changed, 116 insertions(+), 10 deletions(-) diff --git a/nmshandler/src/main/java/net/aufdemrand/denizen/nms/NMSHandler.java b/nmshandler/src/main/java/net/aufdemrand/denizen/nms/NMSHandler.java index 2d035825d2..09baaf983e 100644 --- a/nmshandler/src/main/java/net/aufdemrand/denizen/nms/NMSHandler.java +++ b/nmshandler/src/main/java/net/aufdemrand/denizen/nms/NMSHandler.java @@ -16,6 +16,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; import java.util.Map; @@ -115,7 +116,7 @@ public static JavaPlugin getJavaPlugin() { public abstract int getPort(); - public void forceAttachMove(Entity a, Entity b) { + public void forceAttachMove(Entity a, Entity b, Vector offset) { throw new RuntimeException("Unsupported forceAttachMove!"); } } diff --git a/plugin/src/main/java/net/aufdemrand/denizen/objects/dEntity.java b/plugin/src/main/java/net/aufdemrand/denizen/objects/dEntity.java index 9d33e11d6b..db45ee5103 100644 --- a/plugin/src/main/java/net/aufdemrand/denizen/objects/dEntity.java +++ b/plugin/src/main/java/net/aufdemrand/denizen/objects/dEntity.java @@ -10,6 +10,7 @@ import net.aufdemrand.denizen.objects.properties.entity.EntityTame; import net.aufdemrand.denizen.scripts.containers.core.EntityScriptContainer; import net.aufdemrand.denizen.scripts.containers.core.EntityScriptHelper; +import net.aufdemrand.denizen.tags.BukkitTagContext; import net.aufdemrand.denizen.utilities.DenizenAPI; import net.aufdemrand.denizen.utilities.MaterialCompat; import net.aufdemrand.denizen.utilities.entity.AreaEffectCloudHelper; @@ -2843,17 +2844,25 @@ public void adjust(Mechanism mechanism) { // <--[mechanism] // @object dEntity // @name attach_to - // @input dEntity + // @input dEntity(|dLocation) // @description // Attaches this entity's client-visible motion to another entity. + // Optionally, specify an offset vector as well. + // Note that because this is client-visible motion, it does not take effect server-side. You may wish to occasionally teleport the entity to its attachment. + // Tracking may be a bit off with a large (8 blocks is large in this context) offset on a rotating entity. // Run with no value to disable attachment. // --> if (mechanism.matches("attach_to")) { if (mechanism.hasValue()) { - NMSHandler.getInstance().forceAttachMove(entity, mechanism.getValue().asType(dEntity.class).getBukkitEntity()); + dList list = mechanism.getValue().asType(dList.class); + Vector offset = null; + if (list.size() > 1) { + offset = dLocation.valueOf(list.get(1)).toVector(); + } + NMSHandler.getInstance().forceAttachMove(entity, dEntity.valueOf(list.get(0)).getBukkitEntity(), offset); } else { - NMSHandler.getInstance().forceAttachMove(entity, null); + NMSHandler.getInstance().forceAttachMove(entity, null, null); } } diff --git a/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/Handler_v1_12_R1.java b/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/Handler_v1_12_R1.java index a3cca2faad..cbff654aed 100644 --- a/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/Handler_v1_12_R1.java +++ b/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/Handler_v1_12_R1.java @@ -30,6 +30,7 @@ import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import java.util.HashMap; import java.util.Map; @@ -221,19 +222,23 @@ public BiomeNMS getBiomeNMS(Biome biome) { return new BiomeNMS_v1_12_R1(biome); } - public HashMap attachmentsA = new HashMap(); - public HashMap attachments2 = new HashMap(); + public HashMap attachmentsA = new HashMap(); // Key follows value + public HashMap attachments2 = new HashMap(); // Value follows key + public HashMap attachmentOffsets = new HashMap<>(); + public HashMap visiblePositions = new HashMap<>(); @Override - public void forceAttachMove(Entity a, Entity b) { + public void forceAttachMove(Entity a, Entity b, Vector offset) { if (attachmentsA.containsKey(a.getUniqueId())) { attachments2.remove(attachmentsA.get(a.getUniqueId())); attachmentsA.remove(a.getUniqueId()); + attachmentOffsets.remove(a.getUniqueId()); } if (b == null) { return; } attachmentsA.put(a.getUniqueId(), b.getUniqueId()); attachments2.put(b.getUniqueId(), a.getUniqueId()); + attachmentOffsets.put(a.getUniqueId(), offset); } } diff --git a/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/impl/packets/handlers/DenizenNetworkManager_v1_12_R1.java b/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/impl/packets/handlers/DenizenNetworkManager_v1_12_R1.java index d89f715b58..eb4fad9a31 100644 --- a/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/impl/packets/handlers/DenizenNetworkManager_v1_12_R1.java +++ b/v1_12_R1/src/main/java/net/aufdemrand/denizen/nms/impl/packets/handlers/DenizenNetworkManager_v1_12_R1.java @@ -23,6 +23,7 @@ import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.entity.*; +import org.bukkit.util.Vector; import javax.crypto.SecretKey; import java.lang.reflect.Field; @@ -87,6 +88,12 @@ public void setPacketListener(PacketListener packetlistener) { public static Field ENTITY_ID_PACKENT = ReflectionHelper.getFields(PacketPlayOutEntity.class).get("a"); public static Field ENTITY_ID_PACKVELENT = ReflectionHelper.getFields(PacketPlayOutEntityVelocity.class).get("a"); public static Field ENTITY_ID_PACKTELENT = ReflectionHelper.getFields(PacketPlayOutEntityTeleport.class).get("a"); + public static Field POS_X_PACKTELENT = ReflectionHelper.getFields(PacketPlayOutEntityTeleport.class).get("b"); + public static Field POS_Y_PACKTELENT = ReflectionHelper.getFields(PacketPlayOutEntityTeleport.class).get("c"); + public static Field POS_Z_PACKTELENT = ReflectionHelper.getFields(PacketPlayOutEntityTeleport.class).get("d"); + public static Field POS_X_PACKENT = ReflectionHelper.getFields(PacketPlayOutEntity.class).get("b"); + public static Field POS_Y_PACKENT = ReflectionHelper.getFields(PacketPlayOutEntity.class).get("c"); + public static Field POS_Z_PACKENT = ReflectionHelper.getFields(PacketPlayOutEntity.class).get("d"); public static Object duplo(Object a) { try { @@ -137,6 +144,33 @@ else if (packet instanceof PacketPlayOutEntity) { if (target != null) { Packet pNew = (Packet) duplo(packet); ENTITY_ID_PACKENT.setInt(pNew, target.getEntityId()); + Vector offset = ((Handler_v1_12_R1) NMSHandler.getInstance()).attachmentOffsets.get(att); + if (offset != null && (packet instanceof PacketPlayOutEntity.PacketPlayOutRelEntityMove || packet instanceof PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook)) { + Vector goalPosition = new Vector(e.locX, e.locY, e.locZ).add(offset); + Vector oldPos = ((Handler_v1_12_R1) NMSHandler.getInstance()).visiblePositions.get(target.getUniqueId()); + if (oldPos == null) { + oldPos = target.getLocation().toVector(); + } + Vector moveNeeded = goalPosition.clone().subtract(oldPos); + ((Handler_v1_12_R1) NMSHandler.getInstance()).visiblePositions.put(target.getUniqueId(), goalPosition.clone()); + int offX = (int) (moveNeeded.getX() * (32 * 128)); + int offY = (int) (moveNeeded.getY() * (32 * 128)); + int offZ = (int) (moveNeeded.getZ() * (32 * 128)); + if (offX < Short.MIN_VALUE || offX > Short.MAX_VALUE + || offY < Short.MIN_VALUE || offY > Short.MAX_VALUE + || offZ < Short.MIN_VALUE || offZ > Short.MAX_VALUE) { + PacketPlayOutEntityTeleport newTeleportPacket = new PacketPlayOutEntityTeleport(e); + ENTITY_ID_PACKTELENT.setInt(newTeleportPacket, target.getEntityId()); + POS_X_PACKTELENT.setDouble(newTeleportPacket, goalPosition.getX()); + POS_Y_PACKTELENT.setDouble(newTeleportPacket, goalPosition.getY()); + POS_Z_PACKTELENT.setDouble(newTeleportPacket, goalPosition.getZ()); + oldManager.sendPacket(newTeleportPacket); + return; + } + POS_X_PACKENT.setInt(pNew, MathHelper.clamp(offX, Short.MIN_VALUE, Short.MAX_VALUE)); + POS_Y_PACKENT.setInt(pNew, MathHelper.clamp(offY, Short.MIN_VALUE, Short.MAX_VALUE)); + POS_Z_PACKENT.setInt(pNew, MathHelper.clamp(offZ, Short.MIN_VALUE, Short.MAX_VALUE)); + } oldManager.sendPacket(pNew); } } @@ -191,6 +225,15 @@ else if (packet instanceof PacketPlayOutEntityTeleport) { if (target != null) { Packet pNew = (Packet) duplo(packet); ENTITY_ID_PACKTELENT.setInt(pNew, target.getEntityId()); + Vector offset = ((Handler_v1_12_R1) NMSHandler.getInstance()).attachmentOffsets.get(att); + Vector resultPos = new Vector(POS_X_PACKTELENT.getDouble(pNew), POS_Y_PACKTELENT.getDouble(pNew), POS_Z_PACKTELENT.getDouble(pNew)); + if (offset != null) { + POS_X_PACKTELENT.setDouble(pNew, POS_X_PACKTELENT.getDouble(pNew) + offset.getX()); + POS_Y_PACKTELENT.setDouble(pNew, POS_Y_PACKTELENT.getDouble(pNew) + offset.getY()); + POS_Z_PACKTELENT.setDouble(pNew, POS_Z_PACKTELENT.getDouble(pNew) + offset.getZ()); + resultPos.add(offset); + } + ((Handler_v1_12_R1) NMSHandler.getInstance()).visiblePositions.put(target.getUniqueId(), resultPos); oldManager.sendPacket(pNew); } } diff --git a/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/Handler_v1_13_R2.java b/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/Handler_v1_13_R2.java index f30e8b65b6..2b30552a4f 100644 --- a/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/Handler_v1_13_R2.java +++ b/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/Handler_v1_13_R2.java @@ -30,6 +30,7 @@ import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import java.util.HashMap; import java.util.Map; @@ -221,19 +222,23 @@ public BiomeNMS getBiomeNMS(Biome biome) { return new BiomeNMS_v1_13_R2(biome); } - public HashMap attachmentsA = new HashMap(); - public HashMap attachments2 = new HashMap(); + public HashMap attachmentsA = new HashMap(); // Key follows value + public HashMap attachments2 = new HashMap(); // Value follows key + public HashMap attachmentOffsets = new HashMap<>(); + public HashMap visiblePositions = new HashMap<>(); @Override - public void forceAttachMove(Entity a, Entity b) { + public void forceAttachMove(Entity a, Entity b, Vector offset) { if (attachmentsA.containsKey(a.getUniqueId())) { attachments2.remove(attachmentsA.get(a.getUniqueId())); attachmentsA.remove(a.getUniqueId()); + attachmentOffsets.remove(a.getUniqueId()); } if (b == null) { return; } attachmentsA.put(a.getUniqueId(), b.getUniqueId()); attachments2.put(b.getUniqueId(), a.getUniqueId()); + attachmentOffsets.put(a.getUniqueId(), offset); } } diff --git a/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/impl/packets/handlers/DenizenNetworkManager_v1_13_R2.java b/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/impl/packets/handlers/DenizenNetworkManager_v1_13_R2.java index 71a9086c2a..014ed97b03 100644 --- a/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/impl/packets/handlers/DenizenNetworkManager_v1_13_R2.java +++ b/v1_13_R2/src/main/java/net/aufdemrand/denizen/nms/impl/packets/handlers/DenizenNetworkManager_v1_13_R2.java @@ -22,6 +22,7 @@ import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import javax.crypto.SecretKey; import java.lang.reflect.Field; @@ -92,6 +93,12 @@ public void setPacketListener(PacketListener packetlistener) { public static Field ENTITY_ID_PACKENT = ReflectionHelper.getFields(PacketPlayOutEntity.class).get("a"); public static Field ENTITY_ID_PACKVELENT = ReflectionHelper.getFields(PacketPlayOutEntityVelocity.class).get("a"); public static Field ENTITY_ID_PACKTELENT = ReflectionHelper.getFields(PacketPlayOutEntityTeleport.class).get("a"); + public static Field POS_X_PACKTELENT = ReflectionHelper.getFields(PacketPlayOutEntityTeleport.class).get("b"); + public static Field POS_Y_PACKTELENT = ReflectionHelper.getFields(PacketPlayOutEntityTeleport.class).get("c"); + public static Field POS_Z_PACKTELENT = ReflectionHelper.getFields(PacketPlayOutEntityTeleport.class).get("d"); + public static Field POS_X_PACKENT = ReflectionHelper.getFields(PacketPlayOutEntity.class).get("b"); + public static Field POS_Y_PACKENT = ReflectionHelper.getFields(PacketPlayOutEntity.class).get("c"); + public static Field POS_Z_PACKENT = ReflectionHelper.getFields(PacketPlayOutEntity.class).get("d"); public static Object duplo(Object a) { try { @@ -148,6 +155,33 @@ else if (packet instanceof PacketPlayOutEntity) { if (target != null) { Packet pNew = (Packet) duplo(packet); ENTITY_ID_PACKENT.setInt(pNew, target.getEntityId()); + Vector offset = ((Handler_v1_13_R2) NMSHandler.getInstance()).attachmentOffsets.get(att); + if (offset != null && (packet instanceof PacketPlayOutEntity.PacketPlayOutRelEntityMove || packet instanceof PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook)) { + Vector goalPosition = new Vector(e.locX, e.locY, e.locZ).add(offset); + Vector oldPos = ((Handler_v1_13_R2) NMSHandler.getInstance()).visiblePositions.get(target.getUniqueId()); + if (oldPos == null) { + oldPos = target.getLocation().toVector(); + } + Vector moveNeeded = goalPosition.clone().subtract(oldPos); + ((Handler_v1_13_R2) NMSHandler.getInstance()).visiblePositions.put(target.getUniqueId(), goalPosition.clone()); + int offX = (int) (moveNeeded.getX() * (32 * 128)); + int offY = (int) (moveNeeded.getY() * (32 * 128)); + int offZ = (int) (moveNeeded.getZ() * (32 * 128)); + if (offX < Short.MIN_VALUE || offX > Short.MAX_VALUE + || offY < Short.MIN_VALUE || offY > Short.MAX_VALUE + || offZ < Short.MIN_VALUE || offZ > Short.MAX_VALUE) { + PacketPlayOutEntityTeleport newTeleportPacket = new PacketPlayOutEntityTeleport(e); + ENTITY_ID_PACKTELENT.setInt(newTeleportPacket, target.getEntityId()); + POS_X_PACKTELENT.setDouble(newTeleportPacket, goalPosition.getX()); + POS_Y_PACKTELENT.setDouble(newTeleportPacket, goalPosition.getY()); + POS_Z_PACKTELENT.setDouble(newTeleportPacket, goalPosition.getZ()); + oldManager.sendPacket(newTeleportPacket); + return; + } + POS_X_PACKENT.setInt(pNew, MathHelper.clamp(offX, Short.MIN_VALUE, Short.MAX_VALUE)); + POS_Y_PACKENT.setInt(pNew, MathHelper.clamp(offY, Short.MIN_VALUE, Short.MAX_VALUE)); + POS_Z_PACKENT.setInt(pNew, MathHelper.clamp(offZ, Short.MIN_VALUE, Short.MAX_VALUE)); + } oldManager.sendPacket(pNew); } } @@ -202,6 +236,15 @@ else if (packet instanceof PacketPlayOutEntityTeleport) { if (target != null) { Packet pNew = (Packet) duplo(packet); ENTITY_ID_PACKTELENT.setInt(pNew, target.getEntityId()); + Vector offset = ((Handler_v1_13_R2) NMSHandler.getInstance()).attachmentOffsets.get(att); + Vector resultPos = new Vector(POS_X_PACKTELENT.getDouble(pNew), POS_Y_PACKTELENT.getDouble(pNew), POS_Z_PACKTELENT.getDouble(pNew)); + if (offset != null) { + POS_X_PACKTELENT.setDouble(pNew, POS_X_PACKTELENT.getDouble(pNew) + offset.getX()); + POS_Y_PACKTELENT.setDouble(pNew, POS_Y_PACKTELENT.getDouble(pNew) + offset.getY()); + POS_Z_PACKTELENT.setDouble(pNew, POS_Z_PACKTELENT.getDouble(pNew) + offset.getZ()); + resultPos.add(offset); + } + ((Handler_v1_13_R2) NMSHandler.getInstance()).visiblePositions.put(target.getUniqueId(), resultPos); oldManager.sendPacket(pNew); } }