Refactor CancelReason event firing, NPCs should teleport if no path can be found

This commit is contained in:
fullwall 2012-09-04 21:11:45 +08:00
parent 47fc78469b
commit 86f953e503
4 changed files with 44 additions and 12 deletions

View File

@ -25,8 +25,10 @@ public class CitizensNavigator implements Navigator {
.range(Setting.DEFAULT_PATHFINDING_RANGE.asFloat())
.stationaryTicks(Setting.DEFAULT_STATIONARY_TICKS.asInt());
private PathStrategy executing;
int lastX, lastY, lastZ;
private NavigatorParameters localParams = defaultParams;
private final CitizensNPC npc;
private int stationaryTicks;
private boolean updatedAvoidWater = false;
@ -37,9 +39,7 @@ public class CitizensNavigator implements Navigator {
@Override
public void cancelNavigation() {
if (isNavigating())
Bukkit.getPluginManager().callEvent(new NavigationCancelEvent(this, CancelReason.PLUGIN));
stopNavigating();
stopNavigating(CancelReason.PLUGIN);
}
@Override
@ -138,6 +138,18 @@ public class CitizensNavigator implements Navigator {
stationaryTicks = 0;
}
private void stopNavigating(CancelReason reason) {
if (!isNavigating())
return;
if (reason == CancelReason.STUCK) {
StuckAction action = localParams.stuckAction();
if (action != null)
action.run(npc, this);
}
Bukkit.getPluginManager().callEvent(new NavigationCancelEvent(this, reason));
stopNavigating();
}
private void switchStrategyTo(PathStrategy newStrategy) {
if (executing != null)
Bukkit.getPluginManager().callEvent(new NavigationReplaceEvent(this));
@ -150,7 +162,11 @@ public class CitizensNavigator implements Navigator {
if (!isNavigating() || !npc.isSpawned() || updateStationaryStatus())
return;
boolean finished = executing.update();
if (finished) {
if (!finished)
return;
if (executing.getCancelReason() != null)
stopNavigating(executing.getCancelReason());
else {
Bukkit.getPluginManager().callEvent(new NavigationCompleteEvent(this));
stopNavigating();
}
@ -160,19 +176,13 @@ public class CitizensNavigator implements Navigator {
NMS.updatePathfindingRange(npc, localParams.range());
}
int lastX, lastY, lastZ;
private boolean updateStationaryStatus() {
if (localParams.stationaryTicks() < 0)
localParams.stationaryTicks(100);// return false;
EntityLiving handle = npc.getHandle();
if (lastX == (int) handle.locX && lastY == (int) handle.locY && lastZ == (int) handle.locZ) {
if (++stationaryTicks >= localParams.stationaryTicks()) {
StuckAction action = localParams.stuckAction();
if (action != null)
action.run(npc, this);
Bukkit.getPluginManager().callEvent(new NavigationCancelEvent(this, CancelReason.STUCK));
stopNavigating();
stopNavigating(CancelReason.STUCK);
return true;
}
} else

View File

@ -2,6 +2,7 @@ package net.citizensnpcs.npc.ai;
import net.citizensnpcs.api.ai.NavigatorParameters;
import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.api.ai.event.CancelReason;
import net.citizensnpcs.npc.CitizensNPC;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.Navigation;
@ -9,6 +10,7 @@ import net.minecraft.server.Navigation;
import org.bukkit.Location;
public class MCNavigationStrategy implements PathStrategy {
private CancelReason cancelReason;
private final Navigation navigation;
private final NavigatorParameters parameters;
private final Location target;
@ -25,6 +27,12 @@ public class MCNavigationStrategy implements PathStrategy {
navigation = npc.getHandle().getNavigation();
navigation.a(parameters.avoidWater());
navigation.a(dest.getX(), dest.getY(), dest.getZ(), parameters.speed());
if (navigation.f())
cancelReason = CancelReason.STUCK;
}
public CancelReason getCancelReason() {
return cancelReason;
}
@Override

View File

@ -3,6 +3,7 @@ package net.citizensnpcs.npc.ai;
import net.citizensnpcs.api.ai.EntityTarget;
import net.citizensnpcs.api.ai.NavigatorParameters;
import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.api.ai.event.CancelReason;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.util.Util;
import net.minecraft.server.EntityLiving;
@ -18,6 +19,7 @@ import org.bukkit.entity.LivingEntity;
public class MCTargetStrategy implements PathStrategy, EntityTarget {
private final boolean aggro;
private int attackTicks;
private CancelReason cancelReason;
private final EntityLiving handle, target;
private final Navigation navigation;
private final NavigatorParameters parameters;
@ -41,6 +43,11 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
return handle.getBukkitEntity().getLocation().distanceSquared(target.getBukkitEntity().getLocation());
}
@Override
public CancelReason getCancelReason() {
return cancelReason;
}
@Override
public LivingEntity getTarget() {
return (LivingEntity) target.getBukkitEntity();
@ -68,8 +75,12 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
@Override
public boolean update() {
if (target == null || target.dead)
if (target == null)
return true;
if (target.dead) {
cancelReason = CancelReason.TARGET_DIED;
return true;
}
navigation.a(target, parameters.speed());
handle.getControllerLook().a(target, 10.0F, handle.bf());
if (aggro && canAttack()) {

View File

@ -1,10 +1,13 @@
package net.citizensnpcs.npc.ai;
import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.api.ai.event.CancelReason;
import org.bukkit.Location;
public interface PathStrategy {
CancelReason getCancelReason();
Location getTargetAsLocation();
TargetType getTargetType();