From 75e718033afd0f47b7899e29c34a8588854f7f6d Mon Sep 17 00:00:00 2001 From: fullwall Date: Mon, 27 Feb 2012 19:16:01 +0800 Subject: [PATCH] Waypoint work --- .../java/net/citizensnpcs/editor/Editor.java | 4 +- .../net/citizensnpcs/npc/ai/CitizensAI.java | 4 +- .../waypoint/LinearWaypointProvider.java | 133 ++++++++++++++++++ .../citizensnpcs/trait/waypoint/Waypoint.java | 4 + .../trait/waypoint/WaypointProvider.java | 1 - .../trait/waypoint/Waypoints.java | 6 +- .../net/citizensnpcs/util/StorageUtils.java | 32 +++++ 7 files changed, 178 insertions(+), 6 deletions(-) create mode 100644 src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java create mode 100644 src/main/java/net/citizensnpcs/util/StorageUtils.java diff --git a/src/main/java/net/citizensnpcs/editor/Editor.java b/src/main/java/net/citizensnpcs/editor/Editor.java index d13348107..42c77b24e 100644 --- a/src/main/java/net/citizensnpcs/editor/Editor.java +++ b/src/main/java/net/citizensnpcs/editor/Editor.java @@ -1,6 +1,8 @@ package net.citizensnpcs.editor; -public abstract class Editor { +import org.bukkit.event.Listener; + +public abstract class Editor implements Listener { public abstract void begin(); diff --git a/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java b/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java index aaa9ef658..d0f92ecc6 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java +++ b/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java @@ -56,8 +56,10 @@ public class CitizensAI implements AI { @Override public void registerNavigationCallback(NavigationCallback callback) { - if (!callbacks.contains(callback)) + if (!callbacks.contains(callback)) { callbacks.add(new WeakReference(callback)); + callback.onAttach(this); + } } @Override diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java b/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java new file mode 100644 index 000000000..c6790bf88 --- /dev/null +++ b/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java @@ -0,0 +1,133 @@ +package net.citizensnpcs.trait.waypoint; + +import java.util.List; + +import net.citizensnpcs.api.ai.AI; +import net.citizensnpcs.api.ai.NavigationCallback; +import net.citizensnpcs.api.util.DataKey; +import net.citizensnpcs.editor.Editor; +import net.citizensnpcs.util.StorageUtils; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; + +import com.google.common.collect.Lists; + +public class LinearWaypointProvider implements WaypointProvider { + private final List waypoints = Lists.newArrayList(); + + @Override + public Editor createEditor(final Player player) { + return new Editor() { + @Override + public void begin() { + player.sendMessage(ChatColor.GREEN + "Entered the linear waypoint editor!"); + player.sendMessage(ChatColor.GREEN + "Left click to add waypoint, right click to remove."); + } + + @Override + public void end() { + player.sendMessage(ChatColor.GREEN + "Exited linear waypoint editor."); + } + + @EventHandler + @SuppressWarnings("unused") + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.getAction() == Action.LEFT_CLICK_BLOCK) { + waypoints.add(new Waypoint(event.getClickedBlock().getLocation())); + player.sendMessage(ChatColor.GREEN + "Added a waypoint."); + } else if (waypoints.size() > 0) { + waypoints.remove(waypoints.size() - 1); + player.sendMessage(ChatColor.GREEN + + String.format("Removed a waypoint ({0} remaining)", waypoints.size())); + } + } + }; + } + + @Override + public void load(DataKey key) { + waypoints.clear(); + for (DataKey root : key.getRelative("waypoints").getIntegerSubKeys()) { + waypoints.add(new Waypoint(StorageUtils.loadLocation(root))); + } + } + + @Override + public void save(DataKey key) { + key = key.getRelative("waypoints"); + for (int i = 0; i < waypoints.size(); ++i) { + StorageUtils.saveLocation(key.getRelative(Integer.toString(i)), waypoints.get(i).getLocation()); + } + } + + @Override + public NavigationCallback getCallback() { + return callback; + } + + private final NavigationCallback callback = new NavigationCallback() { + private boolean executing; + private int currentIndex; + private AI attached; + + @Override + public boolean onCancel(AI ai, PathCancelReason reason) { + if (executing) { + executing = false; + } else { + executing = true; + if (currentIndex == -1 && waypoints.size() > 0) + currentIndex = 0; + if (currentIndex != -1) { + ai.setDestination(waypoints.get(currentIndex).getLocation()); + } + } + return false; + } + + @Override + public void onAttach(AI ai) { + if (attached != null && attached != ai) { + executing = false; + currentIndex = -1; + cycle(); + if (currentIndex != -1) { + ai.setDestination(waypoints.get(currentIndex).getLocation()); + } + } + } + + @Override + public boolean onCompletion(AI ai) { + if (executing) { + cycle(); // if we're executing, we need to get the next index + } else { + executing = true; // we're free to return to our waypoints! + if (currentIndex == -1 && waypoints.size() > 0) + currentIndex = 0; + } + if (currentIndex != -1) { + ai.setDestination(waypoints.get(currentIndex).getLocation()); + } + return false; + } + + // TODO: problem with only 1 waypoint. Waypoint instantly completes, + // possibly causes lag.... + + private void cycle() { + if (waypoints.size() == 0) { + currentIndex = -1; + return; + } + currentIndex++; + if (currentIndex >= waypoints.size()) { + currentIndex = 0; + } + } + }; +} diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoint.java b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoint.java index dd1141d61..b86c604a8 100644 --- a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoint.java +++ b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoint.java @@ -8,4 +8,8 @@ public class Waypoint { public Waypoint(Location location) { this.location = location; } + + public Location getLocation() { + return location; + } } \ No newline at end of file diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java b/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java index f517325ed..5553b36c5 100644 --- a/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java +++ b/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java @@ -7,7 +7,6 @@ import net.citizensnpcs.editor.Editor; import org.bukkit.entity.Player; public interface WaypointProvider { - public Editor createEditor(Player player); public void load(DataKey key); diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java index a34e8d15e..450496386 100644 --- a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java +++ b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java @@ -29,7 +29,7 @@ public class Waypoints extends Trait { if (provider == null) return; } - provider.load(key); + provider.load(key.getRelative(providerName)); npc.getAI().registerNavigationCallback(provider.getCallback()); } @@ -37,7 +37,7 @@ public class Waypoints extends Trait { public void save(DataKey key) { if (provider == null) return; - provider.save(key); + provider.save(key.getRelative(providerName)); key.setString("provider", providerName); } @@ -45,7 +45,7 @@ public class Waypoints extends Trait { return provider.createEditor(player); } - public void registerWaypointProvider(Class clazz, String name) { + public static void registerWaypointProvider(Class clazz, String name) { providers.register(clazz, name); } diff --git a/src/main/java/net/citizensnpcs/util/StorageUtils.java b/src/main/java/net/citizensnpcs/util/StorageUtils.java new file mode 100644 index 000000000..d5bdf6272 --- /dev/null +++ b/src/main/java/net/citizensnpcs/util/StorageUtils.java @@ -0,0 +1,32 @@ +package net.citizensnpcs.util; + +import net.citizensnpcs.api.util.DataKey; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +public class StorageUtils { + public static Location loadLocation(DataKey root) { + root = root.getRelative("location"); + return new Location(Bukkit.getWorld(root.getString("world")), root.getDouble("x"), root.getDouble("y"), + root.getDouble("z"), (float) root.getDouble("yaw", 0), (float) root.getDouble("pitch", 0)); + } + + public static ItemStack loadItemStack(DataKey root) { + root = root.getRelative("item"); + return new ItemStack(Material.matchMaterial(root.getString("id")), root.getInt("amount"), + (short) (root.keyExists("data") ? root.getInt("data") : 0)); + } + + public static void saveLocation(DataKey key, Location location) { + key = key.getRelative("location"); + key.setString("world", location.getWorld().getName()); + key.setDouble("x", location.getX()); + key.setDouble("y", location.getY()); + key.setDouble("z", location.getZ()); + key.setDouble("yaw", location.getYaw()); + key.setDouble("pitch", location.getPitch()); + } +}