Waypoint work

This commit is contained in:
fullwall 2012-02-27 19:16:01 +08:00
parent 55ec6d374e
commit 965277121d
7 changed files with 178 additions and 6 deletions

View File

@ -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();

View File

@ -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<NavigationCallback>(callback));
callback.onAttach(this);
}
}
@Override

View File

@ -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<Waypoint> 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;
}
}
};
}

View File

@ -8,4 +8,8 @@ public class Waypoint {
public Waypoint(Location location) {
this.location = location;
}
public Location getLocation() {
return location;
}
}

View File

@ -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);

View File

@ -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<? extends WaypointProvider> clazz, String name) {
public static void registerWaypointProvider(Class<? extends WaypointProvider> clazz, String name) {
providers.register(clazz, name);
}

View File

@ -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());
}
}