mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-11-22 10:36:10 +01:00
Implement destinationTeleportMargin. Tweak pathfinding in an attempt to fix minecraft navigation issues with players. Expect changes.
This commit is contained in:
parent
cbfd57e9c0
commit
5c3878d2f8
@ -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),
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user