Skip to content

Commit

Permalink
EntityTag.trace_framed_map
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Jun 19, 2022
1 parent b84c2a8 commit ef0c37b
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 173 deletions.
Expand Up @@ -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;
Expand All @@ -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.*;
Expand Down Expand Up @@ -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();
Expand Down
Expand Up @@ -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.*;
Expand Down Expand Up @@ -1522,38 +1523,36 @@ else if (object.getLivingEntity() instanceof Steerable) {
// LOCATION ATTRIBUTES
/////////////////

// <--[tag]
// @attribute <EntityTag.trace_framed_map>
// @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 <EntityTag.map_trace>
// @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]
Expand Down
Expand Up @@ -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
Expand Down
Expand Up @@ -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.*;
Expand Down Expand Up @@ -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());
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down

0 comments on commit ef0c37b

Please sign in to comment.