diff --git a/main/src/main/java/net/citizensnpcs/Settings.java b/main/src/main/java/net/citizensnpcs/Settings.java index a09cfd999..1de58dfa2 100644 --- a/main/src/main/java/net/citizensnpcs/Settings.java +++ b/main/src/main/java/net/citizensnpcs/Settings.java @@ -79,6 +79,7 @@ public class Settings { DEBUG_MODE("general.debug-mode", false), DEBUG_PATHFINDING("general.debug-pathfinding", false), DEFAULT_CACHE_WAYPOINT_PATHS("npc.default.waypoints.cache-paths", false), + DEFAULT_DESTINATION_TELEPORT_MARGIN("npc.pathfinding.defaults.destination-teleport-margin", -1), DEFAULT_DISTANCE_MARGIN("npc.pathfinding.default-distance-margin", 2), DEFAULT_LOOK_CLOSE("npc.default.look-close.enabled", false), DEFAULT_LOOK_CLOSE_RANGE("npc.default.look-close.range", 5), 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 066fc063a..710fa088b 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/AStarNavigationStrategy.java @@ -136,7 +136,7 @@ public class AStarNavigationStrategy extends AbstractPathStrategy { } 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()); if (MinecraftBlockExaminer.isDoor(block.getType())) { Door door = (Door) block.getState().getData(); @@ -152,7 +152,7 @@ public class AStarNavigationStrategy extends AbstractPathStrategy { 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()) { + if (Math.abs(dY) < 1 && Math.sqrt(xzDistance) <= params.distanceMargin()) { plan.update(npc); if (plan.isComplete()) { return true; @@ -163,14 +163,13 @@ public class AStarNavigationStrategy extends AbstractPathStrategy { if (params.debug()) { 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(), dest.getX(), dest.getY(), dest.getZ(), params.speed()); } else { 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 + if ((dY >= 1 && Math.sqrt(xzDistance) <= 0.4) || (dY >= 0.2 && MinecraftBlockExaminer.isLiquidOrInLiquid(in))) { dir.add(new Vector(0, 0.75, 0)); } diff --git a/main/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java b/main/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java index 9b590b3fa..606bfd907 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java @@ -10,6 +10,7 @@ import org.bukkit.Location; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.util.Vector; import com.google.common.collect.Iterables; @@ -50,7 +51,8 @@ public class CitizensNavigator implements Navigator, Runnable { .pathDistanceMargin(Setting.DEFAULT_PATH_DISTANCE_MARGIN.asDouble()) .stationaryTicks(Setting.DEFAULT_STATIONARY_TICKS.asInt()).stuckAction(TeleportStuckAction.INSTANCE) .examiner(new MinecraftBlockExaminer()).useNewPathfinder(Setting.USE_NEW_PATHFINDER.asBoolean()) - .straightLineTargetingDistance(Setting.DEFAULT_STRAIGHT_LINE_TARGETING_DISTANCE.asFloat()); + .straightLineTargetingDistance(Setting.DEFAULT_STRAIGHT_LINE_TARGETING_DISTANCE.asFloat()) + .destinationTeleportMargin(Setting.DEFAULT_DESTINATION_TELEPORT_MARGIN.asDouble()); private PathStrategy executing; private int lastX, lastY, lastZ; private NavigatorParameters localParams = defaultParams; @@ -129,6 +131,9 @@ public class CitizensNavigator implements Navigator, Runnable { if (root.keyExists("distancemargin")) { defaultParams.distanceMargin(root.getDouble("distancemargin")); } + if (root.keyExists("destinationteleportmargin")) { + defaultParams.destinationTeleportMargin(root.getDouble("destinationteleportmargin")); + } if (root.keyExists("updatepathrate")) { defaultParams.updatePathRate(root.getInt("updatepathrate")); } @@ -155,7 +160,8 @@ public class CitizensNavigator implements Navigator, Runnable { updateMountedStatus(); if (!isNavigating() || !npc.isSpawned() || isPaused()) return; - if (!npc.getStoredLocation().getWorld().equals(getTargetAsLocation().getWorld()) + Location npcLoc = npc.getStoredLocation(); + if (!npcLoc.getWorld().equals(getTargetAsLocation().getWorld()) || Math.pow(localParams.range(), 2) < npc.getStoredLocation().distanceSquared(getTargetAsLocation())) { stopNavigating(CancelReason.STUCK); return; @@ -167,7 +173,7 @@ public class CitizensNavigator implements Navigator, Runnable { if (localParams.lookAtFunction() != null) { Util.faceLocation(npc.getEntity(), localParams.lookAtFunction().apply(this), true, true); Entity entity = npc.getEntity().getPassenger(); - Location npcLoc = npc.getEntity().getLocation(); + npcLoc = npc.getEntity().getLocation(); while (entity != null) { Location loc = entity.getLocation(STATIONARY_LOCATION); loc.setYaw(npcLoc.getYaw()); @@ -175,6 +181,12 @@ public class CitizensNavigator implements Navigator, Runnable { entity = entity.getPassenger(); } } + if (localParams.destinationTeleportMargin() > 0 + && npcLoc.distance(getTargetAsLocation()) < localParams.destinationTeleportMargin()) { + // TODO: easing? + npc.teleport(getTargetAsLocation(), TeleportCause.PLUGIN); + finished = true; + } if (!finished) { return; } @@ -201,6 +213,11 @@ public class CitizensNavigator implements Navigator, Runnable { } else { root.removeKey("stationaryticks"); } + if (defaultParams.destinationTeleportMargin() != Setting.DEFAULT_DESTINATION_TELEPORT_MARGIN.asDouble()) { + root.setDouble("destinationteleportmargin", defaultParams.destinationTeleportMargin()); + } else { + root.removeKey("destinationteleportmargin"); + } if (defaultParams.distanceMargin() != Setting.DEFAULT_DISTANCE_MARGIN.asDouble()) { root.setDouble("distancemargin", defaultParams.distanceMargin()); } else { diff --git a/main/src/main/java/net/citizensnpcs/npc/ai/FlyingAStarNavigationStrategy.java b/main/src/main/java/net/citizensnpcs/npc/ai/FlyingAStarNavigationStrategy.java index abd8ddc96..032531901 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/FlyingAStarNavigationStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/FlyingAStarNavigationStrategy.java @@ -131,7 +131,7 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy { return true; } Location current = npc.getEntity().getLocation(NPC_LOCATION); - if (current.toVector().distanceSquared(vector) <= parameters.distanceMargin()) { + if (current.toVector().distance(vector) <= parameters.distanceMargin()) { plan.update(npc); if (plan.isComplete()) { return true; 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 12623cecf..f87f4852b 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java @@ -82,7 +82,7 @@ public class MCNavigationStrategy extends AbstractPathStrategy { double dZ = target.getZ() - loc.getZ(); double dY = target.getY() - loc.getY(); double xzDistance = dX * dX + dZ * dZ; - if ((dY * dY) < 1 && xzDistance <= parameters.distanceMargin()) { + if (Math.abs(dY) < 1 && Math.sqrt(xzDistance) <= parameters.distanceMargin()) { stop(); return true; } diff --git a/main/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java b/main/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java index 53356ea16..71f728b48 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java @@ -42,7 +42,7 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget { private boolean canAttack() { BoundingBox handleBB = NMS.getBoundingBox(handle), targetBB = NMS.getBoundingBox(target); return attackTicks <= 0 && (handleBB.maxY > targetBB.minY && handleBB.minY < targetBB.maxY) - && closeEnough(distanceSquared()) && hasLineOfSight(); + && closeEnough(distance()) && hasLineOfSight(); } @Override @@ -54,8 +54,8 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget { return distance <= parameters.attackRange(); } - private double distanceSquared() { - return handle.getLocation(HANDLE_LOCATION).distanceSquared(target.getLocation(TARGET_LOCATION)); + private double distance() { + return handle.getLocation(HANDLE_LOCATION).distance(target.getLocation(TARGET_LOCATION)); } @Override @@ -118,7 +118,7 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget { if (parameters.straightLineTargetingDistance() > 0 && !(targetNavigator instanceof StraightLineTargeter)) { targetNavigator = new StraightLineTargeter(targetNavigator); } - if (!aggro && distanceSquared() <= parameters.distanceMargin()) { + if (!aggro && distance() <= parameters.distanceMargin()) { stop(); return false; } else if (updateCounter == -1 || updateCounter++ > parameters.updatePathRate()) { diff --git a/main/src/main/java/net/citizensnpcs/npc/ai/StraightLineNavigationStrategy.java b/main/src/main/java/net/citizensnpcs/npc/ai/StraightLineNavigationStrategy.java index 042bf1694..39321c7e3 100644 --- a/main/src/main/java/net/citizensnpcs/npc/ai/StraightLineNavigationStrategy.java +++ b/main/src/main/java/net/citizensnpcs/npc/ai/StraightLineNavigationStrategy.java @@ -65,19 +65,19 @@ public class StraightLineNavigationStrategy extends AbstractPathStrategy { } Vector destVector = npc.getStoredLocation().toVector() .add(destination.toVector().subtract(npc.getStoredLocation().toVector()).normalize()); - Location point = destVector.toLocation(destination.getWorld()); + Location destLoc = destVector.toLocation(destination.getWorld()); if (!npc.isFlyable() && destVector.getBlockY() > currLoc.getBlockY()) { - Block block = point.getBlock(); + Block block = destLoc.getBlock(); while (block.getY() > currLoc.getBlockY() && !MinecraftBlockExaminer.canStandOn(block.getRelative(BlockFace.DOWN))) { block = block.getRelative(BlockFace.DOWN); if (block.getY() <= 0) { - block = point.getBlock(); + block = destLoc.getBlock(); break; } } - point = block.getLocation(); - destVector = point.toVector(); + destLoc = block.getLocation(); + destVector = destLoc.toVector(); } double dX = destVector.getX() - currLoc.getX(); double dZ = destVector.getZ() - currLoc.getZ(); @@ -111,13 +111,13 @@ public class StraightLineNavigationStrategy extends AbstractPathStrategy { NMS.setDestination(npc.getEntity(), destVector.getX(), destVector.getY(), destVector.getZ(), params.speed()); } else { - Vector dir = destVector.subtract(npc.getEntity().getLocation().toVector()).normalize().multiply(0.2); - Block in = npc.getEntity().getLocation().getBlock(); + Vector dir = destVector.subtract(currLoc.toVector()).normalize().multiply(0.2); + Block in = currLoc.getBlock(); if (distance > 0 && dY >= 1 && xzDistance <= 2.75 || (dY >= 0.2 && MinecraftBlockExaminer.isLiquidOrInLiquid(in))) { dir.add(new Vector(0, 0.75, 0)); } - Util.faceLocation(npc.getEntity(), destVector.toLocation(npc.getEntity().getWorld())); + Util.faceLocation(npc.getEntity(), destLoc); npc.getEntity().setVelocity(dir); } params.run(); diff --git a/main/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java b/main/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java index d4ba5d13c..86c09802c 100644 --- a/main/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java +++ b/main/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java @@ -530,8 +530,8 @@ public class LinearWaypointProvider implements EnumerableWaypointProvider { this.selector = selector; Waypoint next = itr.next(); final Location npcLoc = npc.getEntity().getLocation(cachedLocation); - if (npcLoc.getWorld() != next.getLocation().getWorld() || npcLoc.distanceSquared(next.getLocation()) < npc - .getNavigator().getLocalParameters().distanceMargin()) { + if (npcLoc.getWorld() != next.getLocation().getWorld() + || npcLoc.distance(next.getLocation()) < npc.getNavigator().getLocalParameters().distanceMargin()) { return false; } currentDestination = next; diff --git a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerMoveControl.java b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerMoveControl.java index 48e8d91cc..6ce6f7f41 100644 --- a/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerMoveControl.java +++ b/v1_17_R1/src/main/java/net/citizensnpcs/nms/v1_17_R1/util/PlayerMoveControl.java @@ -111,7 +111,7 @@ public class PlayerMoveControl extends MoveControl { double dZ = this.tz - this.entity.getZ(); double dY = this.ty - this.entity.getY(); double dXZ = dX * dX + dZ * dZ; - if (dY * dY < 1.0 && dXZ < 0.0075) { + if (Math.abs(dY) < 1.0 && dXZ < 0.0075) { this.entity.zza = 0.0F; return; } diff --git a/v1_18_R1/src/main/java/net/citizensnpcs/nms/v1_18_R1/util/PlayerMoveControl.java b/v1_18_R1/src/main/java/net/citizensnpcs/nms/v1_18_R1/util/PlayerMoveControl.java index 8d1d7bc4b..63a1a1e27 100644 --- a/v1_18_R1/src/main/java/net/citizensnpcs/nms/v1_18_R1/util/PlayerMoveControl.java +++ b/v1_18_R1/src/main/java/net/citizensnpcs/nms/v1_18_R1/util/PlayerMoveControl.java @@ -110,12 +110,12 @@ public class PlayerMoveControl extends MoveControl { double dX = this.tx - this.entity.getX(); double dZ = this.tz - this.entity.getZ(); double dY = this.ty - this.entity.getY(); - double dXZ = dX * dX + dZ * dZ; - if (dY * dY < 1.0 && dXZ < 0.01) { + double dXZ = Math.sqrt(dX * dX + dZ * dZ); + if (Math.abs(dY) < 1.0 && dXZ < 0.025) { // this.entity.zza = 0.0F; return; } - float f = (float) (Mth.atan2(dZ, dX) * 57.2957763671875D) - 90.0F; + float f = (float) Math.toDegrees(Mth.atan2(dZ, dX)) - 90.0F; this.entity.setYRot(rotlerp(this.entity.getYRot(), f, 90.0F)); NMS.setHeadYaw(entity.getBukkitEntity(), this.entity.getYRot()); AttributeInstance speed = this.entity.getAttribute(Attributes.MOVEMENT_SPEED); @@ -123,7 +123,7 @@ public class PlayerMoveControl extends MoveControl { float movement = (float) (this.speed * speed.getValue()); this.entity.setSpeed(movement); this.entity.zza = movement; - if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 1.0D)) { + if (shouldJump() || (dY >= NMS.getStepHeight(entity.getBukkitEntity()) && dXZ < 0.4D)) { this.jumpTicks = jumpTicks(); this.jumpTicks /= 3; if (this.entity instanceof EntityHumanNPC) { diff --git a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/PlayerControllerMove.java b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/PlayerControllerMove.java index d670b3dac..c5fa6c41b 100644 --- a/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/PlayerControllerMove.java +++ b/v1_8_R3/src/main/java/net/citizensnpcs/nms/v1_8_R3/util/PlayerControllerMove.java @@ -77,14 +77,13 @@ public class PlayerControllerMove extends ControllerMove { this.a.ba = 0F; if (this.f) { this.f = false; - int i = MathHelper.floor(this.a.getBoundingBox().b + 0.5D); - double d0 = this.b - this.a.locX; - double d1 = this.d - this.a.locZ; - double d2 = this.c - i; - double d3 = d0 * d0 + d2 * d2 + d1 * d1; - if (d3 < 2.500000277905201E-007D) + double dX = this.b - this.a.locX; + double dZ = this.d - this.a.locZ; + double dY = this.c - this.a.locY; + double dXZ = Math.sqrt(dX * dX + dZ * dZ); + if (Math.abs(dY) < 1.0 && dXZ < 0.025) return; - float f = (float) Math.toDegrees(Math.atan2(d1, d0)) - 90.0F; + float f = (float) Math.toDegrees(Math.atan2(dZ, dX)) - 90.0F; this.a.yaw = a(this.a.yaw, f, 90.0F); NMS.setHeadYaw(a.getBukkitEntity(), this.a.yaw); AttributeInstance speed = this.a.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); @@ -92,7 +91,7 @@ public class PlayerControllerMove extends ControllerMove { float movement = (float) (this.e * speed.getValue()) * 10; this.a.k(movement); this.a.ba = movement; - if (shouldSlimeJump() || ((d2 >= NMS.getStepHeight(a.getBukkitEntity())) && (d0 * d0 + d1 * d1 < 1.0D))) { + if (shouldSlimeJump() || ((dY >= NMS.getStepHeight(a.getBukkitEntity())) && dXZ < 0.4)) { this.h = cg(); this.h /= 3; if (this.a instanceof EntityHumanNPC) {