diff --git a/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java b/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java index 32c55ef31..066fc063a 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java @@ -134,8 +134,7 @@ public boolean update() { if (getCancelReason() != null || plan == null || plan.isComplete()) { return true; } - Location currLoc = npc.getEntity().getLocation(NPC_LOCATION); - Vector destVector = new Vector(vector.getX() + 0.5, vector.getY(), vector.getZ() + 0.5); + Location loc = npc.getEntity().getLocation(NPC_LOCATION); /* Proper door movement - gets stuck on corners at times Block block = currLoc.getWorld().getBlockAt(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); @@ -147,9 +146,11 @@ public boolean update() { destVector.setZ(vector.getZ() + targetFace.getModZ()); } }*/ - double dX = destVector.getX() - currLoc.getX(); - double dZ = destVector.getZ() - currLoc.getZ(); - double dY = destVector.getY() - currLoc.getY(); + Location dest = Util.getCenterLocation( + new Location(loc.getWorld(), vector.getX(), vector.getY(), vector.getZ()).getBlock()); + double dX = dest.getX() - loc.getX(); + double dZ = dest.getZ() - loc.getZ(); + double dY = dest.getY() - loc.getY(); double xzDistance = dX * dX + dZ * dZ; if ((dY * dY) < 1 && xzDistance <= params.distanceMargin()) { plan.update(npc); @@ -160,23 +161,21 @@ public boolean update() { return false; } if (params.debug()) { - npc.getEntity().getWorld().playEffect(destVector.toLocation(npc.getEntity().getWorld()), - Effect.ENDER_SIGNAL, 0); + npc.getEntity().getWorld().playEffect(dest, Effect.ENDER_SIGNAL, 0); } double distance = xzDistance + dY * dY; if (npc.getEntity() instanceof LivingEntity && !npc.getEntity().getType().name().contains("ARMOR_STAND")) { - NMS.setDestination(npc.getEntity(), destVector.getX(), destVector.getY(), destVector.getZ(), - params.speed()); + NMS.setDestination(npc.getEntity(), dest.getX(), dest.getY(), dest.getZ(), params.speed()); } else { - Vector dir = destVector.subtract(npc.getEntity().getLocation().toVector()).normalize().multiply(0.2); + Vector dir = dest.toVector().subtract(npc.getEntity().getLocation().toVector()).normalize().multiply(0.2); Block in = npc.getEntity().getLocation().getBlock(); if (distance > 0 && dY >= 1 && xzDistance <= 2.75 || (dY >= 0.2 && MinecraftBlockExaminer.isLiquidOrInLiquid(in))) { dir.add(new Vector(0, 0.75, 0)); } npc.getEntity().setVelocity(dir); - Util.faceLocation(npc.getEntity(), destVector.toLocation(npc.getEntity().getWorld())); + Util.faceLocation(npc.getEntity(), dest); } params.run(); plan.run(npc); diff --git a/main/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java b/main/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java index 784746e14..eb2b77071 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java @@ -15,8 +15,10 @@ import net.citizensnpcs.api.astar.pathfinder.MinecraftBlockExaminer; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.util.NMS; +import net.citizensnpcs.util.Util; public class MCNavigationStrategy extends AbstractPathStrategy { + private Location centerLocation; private final Entity handle; private final MCNavigator navigator; private final NavigatorParameters parameters; @@ -59,6 +61,7 @@ public TargetType getTargetType() { @Override public void stop() { + centerLocation = null; navigator.stop(); } @@ -74,12 +77,15 @@ public boolean update() { } if (getCancelReason() != null) return true; + if (centerLocation == null) { + centerLocation = Util.getCenterLocation(target.getBlock()); + } boolean wasFinished = navigator.update(); parameters.run(); Location loc = handle.getLocation(HANDLE_LOCATION); - double dX = target.getBlockX() + 0.5 - loc.getX(); - double dZ = target.getBlockZ() + 0.5 - loc.getZ(); - double dY = target.getY() - loc.getY(); + double dX = centerLocation.getX() - loc.getX(); + double dZ = centerLocation.getZ() - loc.getZ(); + double dY = centerLocation.getY() - loc.getY(); double xzDistance = dX * dX + dZ * dZ; if ((dY * dY) < 1 && xzDistance <= parameters.distanceMargin()) { stop(); diff --git a/main/src/main/java/net/citizensnpcs/util/NMS.java b/main/src/main/java/net/citizensnpcs/util/NMS.java index 6447fd88c..46b9dc9b0 100644 --- a/main/src/main/java/net/citizensnpcs/util/NMS.java +++ b/main/src/main/java/net/citizensnpcs/util/NMS.java @@ -9,6 +9,7 @@ import java.util.List; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Enderman; import org.bukkit.entity.Entity; @@ -77,6 +78,9 @@ public static BoundingBox getBoundingBox(org.bukkit.entity.Entity handle) { } public static BoundingBox getCollisionBox(Block block) { + if (block.getType() == Material.AIR) { + return new BoundingBox(0, 0, 0, 0, 0, 0); + } return BRIDGE.getCollisionBox(block).add(block.getX(), block.getY(), block.getZ()); } diff --git a/main/src/main/java/net/citizensnpcs/util/Util.java b/main/src/main/java/net/citizensnpcs/util/Util.java index 9833f1848..ea68e0c7e 100644 --- a/main/src/main/java/net/citizensnpcs/util/Util.java +++ b/main/src/main/java/net/citizensnpcs/util/Util.java @@ -28,6 +28,7 @@ import net.citizensnpcs.api.event.NPCCollisionEvent; import net.citizensnpcs.api.event.NPCPushEvent; import net.citizensnpcs.api.npc.NPC; +import net.citizensnpcs.api.util.BoundingBox; import net.citizensnpcs.api.util.SpigotUtil; import net.citizensnpcs.npc.ai.NPCHolder; @@ -116,6 +117,17 @@ public static void generateTeamFor(NPC npc, String name, String teamName) { sendTeamPacketToOnlinePlayers(team, mode); } + public static Location getCenterLocation(Block block) { + Location bloc = block.getLocation(); + Location center = new Location(bloc.getWorld(), bloc.getBlockX() + 0.5, bloc.getBlockY(), + bloc.getBlockZ() + 0.5); + BoundingBox bb = NMS.getCollisionBox(block); + if (bb != null) { + center.setY(center.getY() + bb.maxY); + } + return center; + } + public static Scoreboard getDummyScoreboard() { return DUMMY_SCOREBOARD; }