diff --git a/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/EntityHelper.java b/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/EntityHelper.java index 462eca05d5..6df016273e 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/EntityHelper.java +++ b/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/EntityHelper.java @@ -4,9 +4,12 @@ import com.denizenscript.denizen.nms.util.jnbt.CompoundTag; import com.denizenscript.denizen.objects.EntityTag; import com.denizenscript.denizen.objects.LocationTag; +import com.denizenscript.denizencore.objects.core.ElementTag; +import com.denizenscript.denizencore.objects.core.MapTag; import com.denizenscript.denizencore.utilities.debugging.Debug; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.BlockFace; import org.bukkit.block.CreatureSpawner; @@ -16,6 +19,8 @@ import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.MapMeta; +import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; import java.util.*; @@ -107,15 +112,99 @@ public abstract void follow(final Entity target, final Entity follower, final do // Taken from C2 NMS class for less dependency on C2 public abstract void look(Entity entity, float yaw, float pitch); - public static class MapTraceResult { - public Location hitLocation; - public BlockFace angle; + public MapTag mapTrace(LivingEntity inputEntity) { + double range = 200; + Location start = inputEntity.getEyeLocation(); + Vector startVec = start.toVector(); + Vector direction = start.getDirection(); + double bestDist = Double.MAX_VALUE; + ItemFrame best = null; + Vector bestHitPos = null; + BlockFace bestHitFace = null; + for (Entity entity : start.getWorld().getNearbyEntities(start.clone().add(direction.clone().multiply(50)), 100, 100, 100, (e) -> e instanceof ItemFrame && ((ItemFrame) e).getItem().getType() == Material.FILLED_MAP)) { + double centerDist = entity.getLocation().distanceSquared(start); + if (centerDist > bestDist) { + continue; + } + ItemFrame frame = (ItemFrame) entity; + double EXP_RATE = 0.125; + double expandX = 0, expandY = 0, expandZ = 0; + BlockFace face = frame.getFacing(); + switch (face) { + case SOUTH: case NORTH: expandX = EXP_RATE; expandY = EXP_RATE; break; + case EAST: case WEST: expandZ = EXP_RATE; expandY = EXP_RATE; break; + case UP: case DOWN: expandX = EXP_RATE; expandZ = EXP_RATE; break; + } + RayTraceResult traced = frame.getBoundingBox().expand(expandX, expandY, expandZ).rayTrace(startVec, direction, range); + if (traced == null || traced.getHitBlockFace() == null || traced.getHitBlockFace() != face) { + continue; + } + bestDist = centerDist; + best = frame; + bestHitPos = traced.getHitPosition(); + bestHitFace = face; + } + if (best == null) { + return null; + } + double x = 0; + double y = 0; + double basex = bestHitPos.getX() - Math.floor(bestHitPos.getX()); + double basey = bestHitPos.getY() - Math.floor(bestHitPos.getY()); + double basez = bestHitPos.getZ() - Math.floor(bestHitPos.getZ()); + switch (bestHitFace) { + case NORTH: + x = 128f - (basex * 128f); + y = 128f - (basey * 128f); + break; + case SOUTH: + x = basex * 128f; + y = 128f - (basey * 128f); + break; + case WEST: + x = basez * 128f; + y = 128f - (basey * 128f); + break; + case EAST: + x = 128f - (basez * 128f); + y = 128f - (basey * 128f); + break; + case UP: + x = basex * 128f; + y = basez * 128f; + break; + case DOWN: + x = basex * 128f; + y = 128f - (basez * 128f); + break; + } + MapMeta map = (MapMeta) best.getItem().getItemMeta(); + switch (best.getRotation()) { + case CLOCKWISE_45: case FLIPPED_45: // 90 deg + double origX = x; + x = y; + y = 128f - origX; + break; + case CLOCKWISE: case COUNTER_CLOCKWISE: // 180 deg + x = 128f - x; + y = 128f - y; + break; + case CLOCKWISE_135: case COUNTER_CLOCKWISE_45: // 270 deg + double origX2 = x; + x = 128f - y; + y = origX2; + break; + } + MapTag result = new MapTag(); + result.putObject("x", new ElementTag(Math.round(x))); + result.putObject("y", new ElementTag(Math.round(y))); + result.putObject("entity", new EntityTag(best)); + result.putObject("map", new ElementTag(map.hasMapId() ? map.getMapId() : 0)); + return result; } public abstract boolean canTrace(World world, Vector start, Vector end); - public abstract MapTraceResult mapTrace(LivingEntity from, double range); - public Location faceLocation(Location from, Location at) { Vector direction = from.toVector().subtract(at.toVector()).normalize(); Location newLocation = from.clone(); diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/EntityTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/EntityTag.java index 49cdaa0f78..df134c4f87 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/EntityTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/EntityTag.java @@ -45,6 +45,7 @@ import org.bukkit.entity.*; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.inventory.*; +import org.bukkit.inventory.meta.MapMeta; import org.bukkit.loot.LootTable; import org.bukkit.loot.Lootable; import org.bukkit.potion.*; @@ -1522,38 +1523,36 @@ else if (object.getLivingEntity() instanceof Steerable) { // LOCATION ATTRIBUTES ///////////////// + // <--[tag] + // @attribute + // @returns MapTag + // @group location + // @description + // Returns information at the framed item of a filled map that an entity is currently looking at, if any. + // The map contains key "x" and "y" as coordinates in the range of 0 to 128. These will automatically correct for rotation, if the framed item is rotated. + // The map contains "entity" as the EntityTag of the item frame. + // The map also contains "map" as the ID of the targeted map. + // Returns null if the entity is not looking at an item_frame holding a filled_map. + // --> + registerSpawnedOnlyTag(MapTag.class, "trace_framed_map", (attribute, object) -> { + return NMSHandler.entityHelper.mapTrace(object.getLivingEntity()); + }); + // <--[tag] // @attribute // @returns LocationTag // @group location + // @deprecated use EntityTag.trace_framed_map // @description - // Returns a 2D location indicating where on the map the entity's looking at. - // Each coordinate is in the range of 0 to 128. + // Deprecated in favor of <@link tag EntityTag.trace_framed_map> // --> registerSpawnedOnlyTag(LocationTag.class, "map_trace", (attribute, object) -> { - EntityHelper.MapTraceResult mtr = NMSHandler.entityHelper.mapTrace(object.getLivingEntity(), 200); - if (mtr != null) { - double x = 0; - double y; - double basex = mtr.hitLocation.getX() - Math.floor(mtr.hitLocation.getX()); - double basey = mtr.hitLocation.getY() - Math.floor(mtr.hitLocation.getY()); - double basez = mtr.hitLocation.getZ() - Math.floor(mtr.hitLocation.getZ()); - if (mtr.angle == BlockFace.NORTH) { - x = 128f - (basex * 128f); - } - else if (mtr.angle == BlockFace.SOUTH) { - x = basex * 128f; - } - else if (mtr.angle == BlockFace.WEST) { - x = basez * 128f; - } - else if (mtr.angle == BlockFace.EAST) { - x = 128f - (basez * 128f); - } - y = 128f - (basey * 128f); - return new LocationTag(null, Math.round(x), Math.round(y)); + BukkitImplDeprecations.entityMapTraceTag.warn(attribute.context); + MapTag result = NMSHandler.entityHelper.mapTrace(object.getLivingEntity()); + if (result == null) { + return null; } - return null; + return new LocationTag(null, result.getElement("x").asDouble(), result.getElement("y").asDouble()); }); // <--[tag] diff --git a/plugin/src/main/java/com/denizenscript/denizen/utilities/BukkitImplDeprecations.java b/plugin/src/main/java/com/denizenscript/denizen/utilities/BukkitImplDeprecations.java index 9ee1d7922c..50aba33e3e 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/utilities/BukkitImplDeprecations.java +++ b/plugin/src/main/java/com/denizenscript/denizen/utilities/BukkitImplDeprecations.java @@ -263,6 +263,9 @@ public class BukkitImplDeprecations { // Added 2021/06/17, deprecate officially by 2024. public static Warning debugBlockAlpha = new FutureWarning("debugBlockAlpha", "The 'alpha' argument for the 'debugblock' command is deprecated: put the alpha in the color input instead."); + // Added 2021/06/19, deprecate officially by 2024. + public static Warning entityMapTraceTag = new FutureWarning("entityMapTraceTag", "The tag 'EntityTag.map_trace' is deprecated in favor of EntityTag.trace_framed_map"); + // ==================== PAST deprecations of things that are already gone but still have a warning left behind ==================== // Added on 2019/10/13 diff --git a/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/helpers/EntityHelperImpl.java b/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/helpers/EntityHelperImpl.java index 755d917ffd..072c362d99 100644 --- a/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/helpers/EntityHelperImpl.java +++ b/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/helpers/EntityHelperImpl.java @@ -14,7 +14,6 @@ import org.bukkit.World; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; -import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.v1_16_R3.CraftWorld; import org.bukkit.craftbukkit.v1_16_R3.block.CraftBlock; import org.bukkit.craftbukkit.v1_16_R3.entity.*; @@ -521,41 +520,6 @@ public boolean canTrace(World world, Vector start, Vector end) { return pos.getType() == MovingObjectPosition.EnumMovingObjectType.MISS; } - @Override - public MapTraceResult mapTrace(LivingEntity from, double range) { - Location start = from.getEyeLocation(); - Vector startVec = start.toVector(); - double xzLen = Math.cos((start.getPitch() % 360) * (Math.PI / 180)); - double nx = xzLen * Math.sin(-start.getYaw() * (Math.PI / 180)); - double ny = Math.sin(start.getPitch() * (Math.PI / 180)); - double nz = xzLen * Math.cos(start.getYaw() * (Math.PI / 180)); - Vector endVec = startVec.clone().add(new Vector(nx, -ny, nz).multiply(range)); - MovingObjectPosition l = rayTrace(start.getWorld(), startVec, endVec); - if (!(l instanceof MovingObjectPositionBlock) || l.getPos() == null) { - return null; - } - Vector finalVec = new Vector(l.getPos().x, l.getPos().y, l.getPos().z); - MapTraceResult mtr = new MapTraceResult(); - switch (((MovingObjectPositionBlock) l).getDirection()) { - case NORTH: - mtr.angle = BlockFace.NORTH; - break; - case SOUTH: - mtr.angle = BlockFace.SOUTH; - break; - case EAST: - mtr.angle = BlockFace.EAST; - break; - case WEST: - mtr.angle = BlockFace.WEST; - break; - } - // wallPosition - ((end - start).normalize() * 0.072) - Vector hit = finalVec.clone().subtract((endVec.clone().subtract(startVec)).normalize().multiply(0.072)); - mtr.hitLocation = new Location(start.getWorld(), hit.getX(), hit.getY(), hit.getZ()); - return mtr; - } - @Override public void snapPositionTo(Entity entity, Vector vector) { ((CraftEntity) entity).getHandle().setPositionRaw(vector.getX(), vector.getY(), vector.getZ()); diff --git a/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/helpers/EntityHelperImpl.java b/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/helpers/EntityHelperImpl.java index cfb8e9f0c3..ab0a431942 100644 --- a/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/helpers/EntityHelperImpl.java +++ b/v1_17/src/main/java/com/denizenscript/denizen/nms/v1_17/helpers/EntityHelperImpl.java @@ -46,7 +46,6 @@ import org.bukkit.World; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; -import org.bukkit.block.BlockFace; import org.bukkit.block.CreatureSpawner; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; @@ -557,41 +556,6 @@ public boolean canTrace(World world, Vector start, Vector end) { return pos.getType() == HitResult.Type.MISS; } - @Override - public MapTraceResult mapTrace(LivingEntity from, double range) { - Location start = from.getEyeLocation(); - Vector startVec = start.toVector(); - double xzLen = Math.cos((start.getPitch() % 360) * (Math.PI / 180)); - double nx = xzLen * Math.sin(-start.getYaw() * (Math.PI / 180)); - double ny = Math.sin(start.getPitch() * (Math.PI / 180)); - double nz = xzLen * Math.cos(start.getYaw() * (Math.PI / 180)); - Vector endVec = startVec.clone().add(new Vector(nx, -ny, nz).multiply(range)); - HitResult l = rayTrace(start.getWorld(), startVec, endVec); - if (!(l instanceof BlockHitResult) || l.getLocation() == null) { - return null; - } - Vector finalVec = new Vector(l.getLocation().x, l.getLocation().y, l.getLocation().z); - MapTraceResult mtr = new MapTraceResult(); - switch (((BlockHitResult) l).getDirection()) { - case NORTH: - mtr.angle = BlockFace.NORTH; - break; - case SOUTH: - mtr.angle = BlockFace.SOUTH; - break; - case EAST: - mtr.angle = BlockFace.EAST; - break; - case WEST: - mtr.angle = BlockFace.WEST; - break; - } - // wallPosition - ((end - start).normalize() * 0.072) - Vector hit = finalVec.clone().subtract((endVec.clone().subtract(startVec)).normalize().multiply(0.072)); - mtr.hitLocation = new Location(start.getWorld(), hit.getX(), hit.getY(), hit.getZ()); - return mtr; - } - @Override public void snapPositionTo(Entity entity, Vector vector) { ((CraftEntity) entity).getHandle().setPosRaw(vector.getX(), vector.getY(), vector.getZ()); diff --git a/v1_18/src/main/java/com/denizenscript/denizen/nms/v1_18/helpers/EntityHelperImpl.java b/v1_18/src/main/java/com/denizenscript/denizen/nms/v1_18/helpers/EntityHelperImpl.java index e33cc0d6c1..2d28aa5932 100644 --- a/v1_18/src/main/java/com/denizenscript/denizen/nms/v1_18/helpers/EntityHelperImpl.java +++ b/v1_18/src/main/java/com/denizenscript/denizen/nms/v1_18/helpers/EntityHelperImpl.java @@ -53,7 +53,6 @@ import org.bukkit.World; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; -import org.bukkit.block.BlockFace; import org.bukkit.block.CreatureSpawner; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; @@ -591,41 +590,6 @@ public boolean canTrace(World world, Vector start, Vector end) { return pos.getType() == HitResult.Type.MISS; } - @Override - public MapTraceResult mapTrace(LivingEntity from, double range) { - Location start = from.getEyeLocation(); - Vector startVec = start.toVector(); - double xzLen = Math.cos((start.getPitch() % 360) * (Math.PI / 180)); - double nx = xzLen * Math.sin(-start.getYaw() * (Math.PI / 180)); - double ny = Math.sin(start.getPitch() * (Math.PI / 180)); - double nz = xzLen * Math.cos(start.getYaw() * (Math.PI / 180)); - Vector endVec = startVec.clone().add(new Vector(nx, -ny, nz).multiply(range)); - HitResult l = rayTrace(start.getWorld(), startVec, endVec); - if (!(l instanceof BlockHitResult) || l.getLocation() == null) { - return null; - } - Vector finalVec = new Vector(l.getLocation().x, l.getLocation().y, l.getLocation().z); - MapTraceResult mtr = new MapTraceResult(); - switch (((BlockHitResult) l).getDirection()) { - case NORTH: - mtr.angle = BlockFace.NORTH; - break; - case SOUTH: - mtr.angle = BlockFace.SOUTH; - break; - case EAST: - mtr.angle = BlockFace.EAST; - break; - case WEST: - mtr.angle = BlockFace.WEST; - break; - } - // wallPosition - ((end - start).normalize() * 0.072) - Vector hit = finalVec.clone().subtract((endVec.clone().subtract(startVec)).normalize().multiply(0.072)); - mtr.hitLocation = new Location(start.getWorld(), hit.getX(), hit.getY(), hit.getZ()); - return mtr; - } - @Override public void snapPositionTo(Entity entity, Vector vector) { ((CraftEntity) entity).getHandle().setPosRaw(vector.getX(), vector.getY(), vector.getZ()); diff --git a/v1_19/src/main/java/com/denizenscript/denizen/nms/v1_19/helpers/EntityHelperImpl.java b/v1_19/src/main/java/com/denizenscript/denizen/nms/v1_19/helpers/EntityHelperImpl.java index 4b0d7ad4e1..667e8f4d08 100644 --- a/v1_19/src/main/java/com/denizenscript/denizen/nms/v1_19/helpers/EntityHelperImpl.java +++ b/v1_19/src/main/java/com/denizenscript/denizen/nms/v1_19/helpers/EntityHelperImpl.java @@ -54,7 +54,6 @@ import org.bukkit.World; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; -import org.bukkit.block.BlockFace; import org.bukkit.block.CreatureSpawner; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; @@ -592,41 +591,6 @@ public boolean canTrace(World world, Vector start, Vector end) { return pos.getType() == HitResult.Type.MISS; } - @Override - public MapTraceResult mapTrace(LivingEntity from, double range) { - Location start = from.getEyeLocation(); - Vector startVec = start.toVector(); - double xzLen = Math.cos((start.getPitch() % 360) * (Math.PI / 180)); - double nx = xzLen * Math.sin(-start.getYaw() * (Math.PI / 180)); - double ny = Math.sin(start.getPitch() * (Math.PI / 180)); - double nz = xzLen * Math.cos(start.getYaw() * (Math.PI / 180)); - Vector endVec = startVec.clone().add(new Vector(nx, -ny, nz).multiply(range)); - HitResult l = rayTrace(start.getWorld(), startVec, endVec); - if (!(l instanceof BlockHitResult) || l.getLocation() == null) { - return null; - } - Vector finalVec = new Vector(l.getLocation().x, l.getLocation().y, l.getLocation().z); - MapTraceResult mtr = new MapTraceResult(); - switch (((BlockHitResult) l).getDirection()) { - case NORTH: - mtr.angle = BlockFace.NORTH; - break; - case SOUTH: - mtr.angle = BlockFace.SOUTH; - break; - case EAST: - mtr.angle = BlockFace.EAST; - break; - case WEST: - mtr.angle = BlockFace.WEST; - break; - } - // wallPosition - ((end - start).normalize() * 0.072) - Vector hit = finalVec.clone().subtract((endVec.clone().subtract(startVec)).normalize().multiply(0.072)); - mtr.hitLocation = new Location(start.getWorld(), hit.getX(), hit.getY(), hit.getZ()); - return mtr; - } - @Override public void snapPositionTo(Entity entity, Vector vector) { ((CraftEntity) entity).getHandle().setPosRaw(vector.getX(), vector.getY(), vector.getZ());