Rename JeebissFinder to Guided and make it work

This commit is contained in:
fullwall 2013-10-01 12:16:20 +08:00
parent 42172100ab
commit b8b89c43a5
4 changed files with 72 additions and 27 deletions

View File

@ -18,6 +18,10 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persist; import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging; import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.prtree.DistanceResult;
import net.citizensnpcs.api.util.prtree.PRTree;
import net.citizensnpcs.api.util.prtree.Region3D;
import net.citizensnpcs.api.util.prtree.SimplePointND;
import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
@ -29,29 +33,31 @@ import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
public class JeebissFindingWaypointProvider implements WaypointProvider { public class GuidedWaypointProvider implements WaypointProvider {
@Persist("availablewaypoints") @Persist("availablewaypoints")
private final List<Waypoint> available = Lists.newArrayList(); private final List<Waypoint> available = Lists.newArrayList();
private JeebissFindingWaypointProviderGoal currentGoal; private GuidedFindingWaypointProviderGoal currentGoal;
@Persist("helperwaypoints") @Persist("helperwaypoints")
private final List<Waypoint> helpers = Lists.newArrayList(); private final List<Waypoint> helpers = Lists.newArrayList();
private NPC npc; private NPC npc;
private boolean paused; private boolean paused;
private final PRTree<Region3D<Waypoint>> tree = PRTree.create(new Region3D.Converter<Waypoint>(), 30);
@Override @Override
public WaypointEditor createEditor(final Player player, CommandContext args) { public WaypointEditor createEditor(final Player player, CommandContext args) {
return new WaypointEditor() { return new WaypointEditor() {
WaypointMarkers markers = new WaypointMarkers(player.getWorld()); private final WaypointMarkers markers = new WaypointMarkers(player.getWorld());
@Override @Override
public void begin() { public void begin() {
showPath(); showPath();
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_BEGIN); Messaging.sendTr(player, Messages.GUIDED_WAYPOINT_EDITOR_BEGIN);
} }
private void createWaypointMarkerWithData(Waypoint element) { private void createWaypointMarkerWithData(Waypoint element) {
@ -64,7 +70,8 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
@Override @Override
public void end() { public void end() {
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_END); Messaging.sendTr(player, Messages.GUIDED_WAYPOINT_EDITOR_END);
markers.destroyWaypointMarkers();
} }
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
@ -83,6 +90,7 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
helpers.add(element); helpers.add(element);
} }
createWaypointMarkerWithData(element); createWaypointMarkerWithData(element);
rebuildTree();
} }
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
@ -114,18 +122,31 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
@Override @Override
public void load(DataKey key) { public void load(DataKey key) {
rebuildTree();
} }
@Override @Override
public void onSpawn(NPC npc) { public void onSpawn(NPC npc) {
this.npc = npc; this.npc = npc;
if (currentGoal == null) { if (currentGoal == null) {
currentGoal = new JeebissFindingWaypointProviderGoal(); currentGoal = new GuidedFindingWaypointProviderGoal();
CitizensAPI.registerEvents(currentGoal); CitizensAPI.registerEvents(currentGoal);
npc.getDefaultGoalController().addGoal(currentGoal, 1); npc.getDefaultGoalController().addGoal(currentGoal, 1);
} }
} }
private void rebuildTree() {
tree.load(Lists.newArrayList(Iterables.transform(Iterables.<Waypoint> concat(available, helpers),
new Function<Waypoint, Region3D<Waypoint>>() {
@Override
public Region3D<Waypoint> apply(Waypoint arg0) {
Location loc = arg0.getLocation();
Vector root = new Vector(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
return new Region3D<Waypoint>(root, root, arg0);
}
})));
}
@Override @Override
public void save(DataKey key) { public void save(DataKey key) {
} }
@ -135,8 +156,8 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
this.paused = paused; this.paused = paused;
} }
private class JeebissFindingWaypointProviderGoal implements Goal { private class GuidedFindingWaypointProviderGoal implements Goal {
JeebissPlan plan; private GuidedPlan plan;
@Override @Override
public void reset() { public void reset() {
@ -149,6 +170,9 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
selector.finish(); selector.finish();
return; return;
} }
if (npc.getNavigator().isNavigating()) {
return;
}
Waypoint current = plan.getCurrentWaypoint(); Waypoint current = plan.getCurrentWaypoint();
npc.getNavigator().setTarget(current.getLocation()); npc.getNavigator().setTarget(current.getLocation());
npc.getNavigator().getLocalParameters().addSingleUseCallback(new NavigatorCallback() { npc.getNavigator().getLocalParameters().addSingleUseCallback(new NavigatorCallback() {
@ -161,48 +185,56 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
@Override @Override
public boolean shouldExecute(GoalSelector selector) { public boolean shouldExecute(GoalSelector selector) {
if (paused || available.size() == 0 || !npc.isSpawned() || npc.getNavigator().isNavigating()) if (paused || available.size() == 0 || !npc.isSpawned() || npc.getNavigator().isNavigating()) {
return false; return false;
}
Waypoint target = available.get(Util.getFastRandom().nextInt(available.size())); Waypoint target = available.get(Util.getFastRandom().nextInt(available.size()));
ASTAR.runFully(new JeebissGoal(target), null); plan = ASTAR.runFully(new GuidedGoal(target), new GuidedNode(new Waypoint(npc.getStoredLocation())));
if (plan == null) {
return false;
}
return true; return true;
} }
} }
private static class JeebissGoal implements AStarGoal<JeebissNode> { private static class GuidedGoal implements AStarGoal<GuidedNode> {
private final Waypoint dest; private final Waypoint dest;
public JeebissGoal(Waypoint dest) { public GuidedGoal(Waypoint dest) {
this.dest = dest; this.dest = dest;
} }
@Override @Override
public float g(JeebissNode from, JeebissNode to) { public float g(GuidedNode from, GuidedNode to) {
return (float) from.distance(to.waypoint); return (float) from.distance(to.waypoint);
} }
@Override @Override
public float getInitialCost(JeebissNode node) { public float getInitialCost(GuidedNode node) {
return h(node); return h(node);
} }
@Override @Override
public float h(JeebissNode from) { public float h(GuidedNode from) {
return (float) from.distance(dest); return (float) from.distance(dest);
} }
@Override @Override
public boolean isFinished(JeebissNode node) { public boolean isFinished(GuidedNode node) {
return node.waypoint.equals(dest); return node.waypoint.equals(dest);
} }
} }
private static class JeebissNode extends AStarNode { private class GuidedNode extends AStarNode {
private Waypoint waypoint; private final Waypoint waypoint;
public GuidedNode(Waypoint waypoint) {
this.waypoint = waypoint;
}
@Override @Override
public Plan buildPlan() { public Plan buildPlan() {
return new JeebissPlan(this.<JeebissNode> getParents()); return new GuidedPlan(this.<GuidedNode> getParents());
} }
public double distance(Waypoint dest) { public double distance(Waypoint dest) {
@ -217,7 +249,7 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
if (obj == null || getClass() != obj.getClass()) { if (obj == null || getClass() != obj.getClass()) {
return false; return false;
} }
JeebissNode other = (JeebissNode) obj; GuidedNode other = (GuidedNode) obj;
if (waypoint == null) { if (waypoint == null) {
if (other.waypoint != null) { if (other.waypoint != null) {
return false; return false;
@ -230,7 +262,16 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
@Override @Override
public Iterable<AStarNode> getNeighbours() { public Iterable<AStarNode> getNeighbours() {
return null; List<DistanceResult<Region3D<Waypoint>>> res = tree.nearestNeighbour(Region3D
.<Waypoint> distanceCalculator(), Region3D.<Waypoint> alwaysAcceptNodeFilter(), 20,
new SimplePointND(waypoint.getLocation().getBlockX(), waypoint.getLocation().getBlockY(), waypoint
.getLocation().getBlockZ()));
return Iterables.transform(res, new Function<DistanceResult<Region3D<Waypoint>>, AStarNode>() {
@Override
public AStarNode apply(DistanceResult<Region3D<Waypoint>> arg0) {
return new GuidedNode(arg0.get().getData());
}
});
} }
@Override @Override
@ -239,14 +280,14 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
} }
} }
private static class JeebissPlan implements Plan { private static class GuidedPlan implements Plan {
private int index = 0; private int index = 0;
private final Waypoint[] path; private final Waypoint[] path;
public JeebissPlan(Iterable<JeebissNode> path) { public GuidedPlan(Iterable<GuidedNode> path) {
this.path = Iterables.toArray(Iterables.transform(path, new Function<JeebissNode, Waypoint>() { this.path = Iterables.toArray(Iterables.transform(path, new Function<GuidedNode, Waypoint>() {
@Override @Override
public Waypoint apply(JeebissNode to) { public Waypoint apply(GuidedNode to) {
return to.waypoint; return to.waypoint;
} }
}), Waypoint.class); }), Waypoint.class);
@ -267,5 +308,5 @@ public class JeebissFindingWaypointProvider implements WaypointProvider {
} }
} }
private static final AStarMachine<JeebissNode, JeebissPlan> ASTAR = AStarMachine.createWithDefaultStorage(); private static final AStarMachine<GuidedNode, GuidedPlan> ASTAR = AStarMachine.createWithDefaultStorage();
} }

View File

@ -134,6 +134,6 @@ public class Waypoints extends Trait {
static { static {
providers.put("linear", LinearWaypointProvider.class); providers.put("linear", LinearWaypointProvider.class);
providers.put("wander", WanderWaypointProvider.class); providers.put("wander", WanderWaypointProvider.class);
providers.put("jeebissfinding", JeebissFindingWaypointProvider.class); providers.put("guided", GuidedWaypointProvider.class);
} }
} }

View File

@ -77,6 +77,8 @@ public class Messages {
public static final String GAMEMODE_SET = "citizens.commands.npc.gamemode.set"; 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_DISABLED = "citizens.commands.npc.gravity.disabled";
public static final String GRAVITY_ENABLED = "citizens.commands.npc.gravity.enabled"; public static final String GRAVITY_ENABLED = "citizens.commands.npc.gravity.enabled";
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"; public static final String HORSE_CHEST_SET = "citizens.commands.npc.horse.chest-set";
public static final String HORSE_CHEST_UNSET = "citizens.commands.npc.horse.chest-unset"; public static final String HORSE_CHEST_UNSET = "citizens.commands.npc.horse.chest-unset";
public static final String HORSE_COLOR_SET = "citizens.commands.npc.horse.color-set"; public static final String HORSE_COLOR_SET = "citizens.commands.npc.horse.color-set";

View File

@ -171,6 +171,8 @@ citizens.editors.text.remove-prompt=Enter the index of the entry you wish to rem
citizens.editors.text.removed-entry=[[Removed]] entry at index [[{0}]]. citizens.editors.text.removed-entry=[[Removed]] entry at index [[{0}]].
citizens.editors.text.start-prompt=Type [[add]] to add an entry, [[edit]] to edit entries, [[remove]] to remove entries, [[close]] to toggle the NPC as a close talker, [[item]] to set the item in hand pattern, [[range]] to set the talking range, and [[random]] to toggle the NPC as a random talker. Type [[help]] to show this again. citizens.editors.text.start-prompt=Type [[add]] to add an entry, [[edit]] to edit entries, [[remove]] to remove entries, [[close]] to toggle the NPC as a close talker, [[item]] to set the item in hand pattern, [[range]] to set the talking range, and [[random]] to toggle the NPC as a random talker. Type [[help]] to show this again.
citizens.editors.text.talk-item-set=[[Talk item pattern]] set to [[{0}]]. 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.linear.added-waypoint=[[Added]] a waypoint at ({0}) ([[{1}]], [[{2}]]) 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.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}). citizens.editors.waypoints.linear.edit-slot-set=Editing slot set to [[{0}]] ({1}).