Implement destinationTeleportMargin. Tweak pathfinding in an attempt to fix minecraft navigation issues with players. Expect changes.

This commit is contained in:
fullwall 2022-01-29 14:56:29 +08:00
parent cbfd57e9c0
commit 5c3878d2f8
11 changed files with 52 additions and 36 deletions

View File

@ -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),

View File

@ -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));
}

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}

View File

@ -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()) {

View File

@ -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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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) {

View File

@ -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) {