Fix some bugs in the new guided finder based on testing with Jeebiss

This commit is contained in:
fullwall 2013-10-03 00:00:36 +08:00
parent d59cdddc2f
commit cac5a5387d
4 changed files with 79 additions and 13 deletions

View File

@ -15,7 +15,7 @@ import net.citizensnpcs.api.astar.Agent;
import net.citizensnpcs.api.astar.Plan;
import net.citizensnpcs.api.command.CommandContext;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.persistence.PersistenceLoader;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.prtree.DistanceResult;
@ -25,6 +25,7 @@ import net.citizensnpcs.api.util.prtree.SimplePointND;
import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Util;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
@ -40,14 +41,12 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
public class GuidedWaypointProvider implements WaypointProvider {
@Persist("availablewaypoints")
private final List<Waypoint> available = Lists.newArrayList();
private GuidedFindingWaypointProviderGoal currentGoal;
@Persist("helperwaypoints")
private GuidedAIGoal currentGoal;
private final List<Waypoint> helpers = Lists.newArrayList();
private NPC npc;
private boolean paused;
private final PRTree<Region3D<Waypoint>> tree = PRTree.create(new Region3D.Converter<Waypoint>(), 30);
private PRTree<Region3D<Waypoint>> tree = PRTree.create(new Region3D.Converter<Waypoint>(), 30);
@Override
public WaypointEditor createEditor(final Player player, CommandContext args) {
@ -86,8 +85,10 @@ public class GuidedWaypointProvider implements WaypointProvider {
Waypoint element = new Waypoint(at);
if (player.isSneaking()) {
available.add(element);
Messaging.send(player, Messages.GUIDED_WAYPOINT_EDITOR_ADDED_AVAILABLE);
} else {
helpers.add(element);
Messaging.send(player, Messages.GUIDED_WAYPOINT_EDITOR_ADDED_GUIDE);
}
createWaypointMarkerWithData(element);
rebuildTree();
@ -122,6 +123,18 @@ public class GuidedWaypointProvider implements WaypointProvider {
@Override
public void load(DataKey key) {
for (DataKey root : key.getRelative("availablewaypoints").getIntegerSubKeys()) {
Waypoint waypoint = PersistenceLoader.load(Waypoint.class, root);
if (waypoint == null)
continue;
available.add(waypoint);
}
for (DataKey root : key.getRelative("helperwaypoints").getIntegerSubKeys()) {
Waypoint waypoint = PersistenceLoader.load(Waypoint.class, root);
if (waypoint == null)
continue;
helpers.add(waypoint);
}
rebuildTree();
}
@ -129,13 +142,14 @@ public class GuidedWaypointProvider implements WaypointProvider {
public void onSpawn(NPC npc) {
this.npc = npc;
if (currentGoal == null) {
currentGoal = new GuidedFindingWaypointProviderGoal();
currentGoal = new GuidedAIGoal();
CitizensAPI.registerEvents(currentGoal);
npc.getDefaultGoalController().addGoal(currentGoal, 1);
}
}
private void rebuildTree() {
tree = PRTree.create(new Region3D.Converter<Waypoint>(), 30);
tree.load(Lists.newArrayList(Iterables.transform(Iterables.<Waypoint> concat(available, helpers),
new Function<Waypoint, Region3D<Waypoint>>() {
@Override
@ -149,6 +163,16 @@ public class GuidedWaypointProvider implements WaypointProvider {
@Override
public void save(DataKey key) {
key.removeKey("availablewaypoints");
DataKey root = key.getRelative("availablewaypoints");
for (int i = 0; i < available.size(); ++i) {
PersistenceLoader.save(available.get(i), root.getRelative(i));
}
key.removeKey("helperwaypoints");
root = key.getRelative("helperwaypoints");
for (int i = 0; i < helpers.size(); ++i) {
PersistenceLoader.save(helpers.get(i), root.getRelative(i));
}
}
@Override
@ -156,25 +180,31 @@ public class GuidedWaypointProvider implements WaypointProvider {
this.paused = paused;
}
private class GuidedFindingWaypointProviderGoal implements Goal {
private class GuidedAIGoal implements Goal {
private GuidedPlan plan;
@Override
public void reset() {
plan = null;
System.err.println("Reset");
}
@Override
public void run(GoalSelector selector) {
if (plan.isComplete()) {
selector.finish();
System.err.println("Complete");
return;
}
if (npc.getNavigator().isNavigating()) {
return;
}
System.err.println("Updating target");
Waypoint current = plan.getCurrentWaypoint();
npc.getNavigator().setTarget(current.getLocation());
for (int i = 0; i < 5; i++)
current.getLocation().getWorld()
.playEffect(current.getLocation().clone().add(0, 1, 0), Effect.STEP_SOUND, 1);
npc.getNavigator().getLocalParameters().addSingleUseCallback(new NavigatorCallback() {
@Override
public void onCompletion(CancelReason cancelReason) {
@ -190,10 +220,9 @@ public class GuidedWaypointProvider implements WaypointProvider {
}
Waypoint target = available.get(Util.getFastRandom().nextInt(available.size()));
plan = ASTAR.runFully(new GuidedGoal(target), new GuidedNode(new Waypoint(npc.getStoredLocation())));
if (plan == null) {
return false;
}
return true;
if (plan == null)
System.err.println("No path");
return plan != null;
}
}
@ -263,7 +292,7 @@ public class GuidedWaypointProvider implements WaypointProvider {
@Override
public Iterable<AStarNode> getNeighbours() {
List<DistanceResult<Region3D<Waypoint>>> res = tree.nearestNeighbour(Region3D
.<Waypoint> distanceCalculator(), Region3D.<Waypoint> alwaysAcceptNodeFilter(), 20,
.<Waypoint> distanceCalculator(), Region3D.<Waypoint> alwaysAcceptNodeFilter(), 15,
new SimplePointND(waypoint.getLocation().getBlockX(), waypoint.getLocation().getBlockY(), waypoint
.getLocation().getBlockZ()));
return Iterables.transform(res, new Function<DistanceResult<Region3D<Waypoint>>, AStarNode>() {

View File

@ -39,6 +39,32 @@ public class Waypoint {
return location.distance(dest.location);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Waypoint other = (Waypoint) obj;
if (location == null) {
if (other.location != null) {
return false;
}
} else if (!location.equals(other.location)) {
return false;
}
if (triggers == null) {
if (other.triggers != null) {
return false;
}
} else if (!triggers.equals(other.triggers)) {
return false;
}
return true;
}
public Location getLocation() {
return location;
}
@ -48,6 +74,13 @@ public class Waypoint {
return triggers == null ? Collections.EMPTY_LIST : triggers;
}
@Override
public int hashCode() {
final int prime = 31;
int result = prime + ((location == null) ? 0 : location.hashCode());
return prime * result + ((triggers == null) ? 0 : triggers.hashCode());
}
public void onReach(NPC npc) {
if (triggers == null)
return;

View File

@ -77,6 +77,8 @@ public class Messages {
public static final String GAMEMODE_SET = "citizens.commands.npc.gamemode.set";
public static final String GRAVITY_DISABLED = "citizens.commands.npc.gravity.disabled";
public static final String GRAVITY_ENABLED = "citizens.commands.npc.gravity.enabled";
public static final String GUIDED_WAYPOINT_EDITOR_ADDED_AVAILABLE = "citizens.editors.waypoints.guided.added-available";
public static final String GUIDED_WAYPOINT_EDITOR_ADDED_GUIDE = "citizens.editors.waypoints.guided.added-guide";
public static final String GUIDED_WAYPOINT_EDITOR_BEGIN = "citizens.editors.waypoints.guided.begin";
public static final String GUIDED_WAYPOINT_EDITOR_END = "citizens.editors.waypoints.guided.end";
public static final String HORSE_CHEST_SET = "citizens.commands.npc.horse.chest-set";

View File

@ -173,6 +173,8 @@ citizens.editors.text.start-prompt=Type [[add]] to add an entry, [[edit]] to edi
citizens.editors.text.talk-item-set=[[Talk item pattern]] set to [[{0}]].
citizens.editors.waypoints.guided.begin=<b>Entered the guided waypoint editor!<br> [[Left click]] to add a waypoint guide, [[right click]] an existing waypoint to remove.<br> [[Sneak]] while left clicking to add a destination waypoint.
citizens.editors.waypoints.guided.end=Exited the guided waypoint editor.
citizens.editors.waypoints.guided.added-guide=Added a [[guide]] waypoint. This will guide NPCs to their destination.
citizens.editors.waypoints.guided.added-available=Added a [[destination]] waypoint. This will be available for NPCs to path to.
citizens.editors.waypoints.linear.added-waypoint=[[Added]] a waypoint at ({0}) ([[{1}]], [[{2}]])
citizens.editors.waypoints.linear.begin=<b>Entered the linear waypoint editor!<br> [[Left click]] to add a waypoint, [[right click]] to remove.<br> Type [[toggle path]] to toggle showing entities at waypoints, [[triggers]] to enter the trigger editor and [[clear]] to clear all waypoints.
citizens.editors.waypoints.linear.edit-slot-set=Editing slot set to [[{0}]] ({1}).
@ -199,7 +201,7 @@ citizens.editors.waypoints.triggers.remove.prompt=Enter in the index of the trig
citizens.editors.waypoints.triggers.remove.removed=Successfully removed trigger {0}.
citizens.editors.waypoints.triggers.teleport.invalid-format=Invalid location given. Format is [[world]]:[[x]]:[[y]]:[[z]].
citizens.editors.waypoints.triggers.teleport.prompt=Enter the destination in the format world:x:y:z. Type [[here]] to use your current location. Type [[back]] to return to the edit prompt.
citizens.limits.over-npc-limt=Over the NPC limit of {0}.
citizens.limits.over-npc-limit=Over the NPC limit of {0}.
citizens.load-task-error=NPC load task couldn''t be scheduled, disabling...
citizens.nms-errors.clearing-goals=Could not clear goals: {0}.
citizens.nms-errors.error-setting-persistent=Could not set NPC as persistent: {0}. NPC entity may despawn.