Fix part of CITIZENS-11 (waypoint saving incorrectly)

This commit is contained in:
fullwall 2012-03-12 18:17:28 +08:00
parent 60e65e9343
commit 15ebeab5a9
6 changed files with 69 additions and 63 deletions

View File

@ -16,7 +16,6 @@ import net.citizensnpcs.npc.ai.CitizensAI;
import net.citizensnpcs.trait.CurrentLocation; import net.citizensnpcs.trait.CurrentLocation;
import net.citizensnpcs.util.Messaging; import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.StringHelper; import net.citizensnpcs.util.StringHelper;
import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityLiving;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -26,8 +25,8 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
public abstract class CitizensNPC extends AbstractNPC { public abstract class CitizensNPC extends AbstractNPC {
protected final CitizensAI ai = new CitizensAI(this); private final CitizensAI ai = new CitizensAI(this);
protected final CitizensNPCManager manager; private final CitizensNPCManager manager;
protected EntityLiving mcEntity; protected EntityLiving mcEntity;
private final CitizensTraitManager traitManager; private final CitizensTraitManager traitManager;
@ -139,6 +138,7 @@ public abstract class CitizensNPC extends AbstractNPC {
return true; return true;
} }
@Override
public void update() { public void update() {
super.update(); super.update();
ai.update(); ai.update();

View File

@ -3,8 +3,8 @@ package net.citizensnpcs.npc;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import net.citizensnpcs.api.exception.TraitException;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitFactory; import net.citizensnpcs.api.trait.TraitFactory;
@ -20,6 +20,8 @@ import net.citizensnpcs.trait.Powered;
import net.citizensnpcs.trait.text.Text; import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.trait.waypoint.Waypoints; import net.citizensnpcs.trait.waypoint.Waypoints;
import com.google.common.collect.Maps;
public class CitizensTraitManager implements TraitManager { public class CitizensTraitManager implements TraitManager {
private final Map<String, Class<? extends Trait>> registered = new HashMap<String, Class<? extends Trait>>(); private final Map<String, Class<? extends Trait>> registered = new HashMap<String, Class<? extends Trait>>();
@ -57,52 +59,54 @@ public class CitizensTraitManager implements TraitManager {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends Trait> T getTrait(Class<T> clazz, NPC npc) { public <T extends Trait> T getTrait(Class<T> clazz, NPC npc) {
for (String name : registered.keySet()) for (Entry<String, Class<? extends Trait>> entry : registered.entrySet()) {
if (registered.get(name).equals(clazz)) { if (!entry.getValue().equals(clazz))
Trait t = create(registered.get(name), npc); continue;
try { Trait t = create(entry.getValue(), npc);
if (t.getName() == null) t.setName(entry.getKey());
t.setName(name);
return (T) t; return (T) t;
} catch (TraitException ex) {
ex.printStackTrace();
}
} }
return null; return null;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends Trait> T getTrait(String name, NPC npc) { public <T extends Trait> T getTrait(String name, NPC npc) {
if (!registered.containsKey(name)) // TODO: we could replace NPC with Object... and search for the
// constructor
Class<? extends Trait> clazz = registered.get(name);
if (clazz == null)
return null; return null;
Trait t = getTrait(registered.get(name), npc); Trait t = getTrait(clazz, npc);
try {
if (t.getName() == null)
t.setName(name); t.setName(name);
return (T) t; return (T) t;
} catch (TraitException ex) {
ex.printStackTrace();
}
return null;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T extends Trait> T create(Class<T> trait, NPC npc) { private <T extends Trait> T create(Class<T> trait, NPC npc) {
Constructor<? extends Trait> constructor; Constructor<? extends Trait> constructor;
if (!CACHED_CTORS.containsKey(trait)) {
try { try {
constructor = trait.getConstructor(NPC.class); constructor = trait.getConstructor(NPC.class);
constructor.setAccessible(true); // do we want to allow private
// constructors?
} catch (Exception ex) { } catch (Exception ex) {
constructor = null; constructor = null;
} }
CACHED_CTORS.put(trait, constructor);
} else {
constructor = CACHED_CTORS.get(trait);
}
try { try {
if (npc == null) if (constructor == null || npc == null)
return (T) trait.newInstance(); return trait.newInstance();
return constructor != null ? (T) constructor.newInstance(npc) : (T) trait.newInstance(); return (T) constructor.newInstance(npc);
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
return null; return null;
} }
} }
private final Map<Class<? extends Trait>, Constructor<? extends Trait>> CACHED_CTORS = Maps.newHashMap();
} }

View File

@ -8,7 +8,7 @@ import java.util.List;
import net.citizensnpcs.api.ai.AI; import net.citizensnpcs.api.ai.AI;
import net.citizensnpcs.api.ai.Goal; import net.citizensnpcs.api.ai.Goal;
import net.citizensnpcs.api.ai.NavigationCallback; import net.citizensnpcs.api.ai.NavigationCallback;
import net.citizensnpcs.api.ai.NavigationCallback.PathCancelReason; import net.citizensnpcs.api.ai.NavigationCallback.CancelReason;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.util.Messaging; import net.citizensnpcs.util.Messaging;
@ -44,7 +44,7 @@ public class CitizensAI implements AI {
Iterator<WeakReference<NavigationCallback>> itr = callbacks.iterator(); Iterator<WeakReference<NavigationCallback>> itr = callbacks.iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
NavigationCallback next = itr.next().get(); NavigationCallback next = itr.next().get();
if (next == null || next.onCancel(this, PathCancelReason.CANCEL)) { if (next == null || next.onCancel(this, CancelReason.CANCEL)) {
itr.remove(); itr.remove();
} }
} }
@ -104,7 +104,7 @@ public class CitizensAI implements AI {
Iterator<WeakReference<NavigationCallback>> itr = callbacks.iterator(); Iterator<WeakReference<NavigationCallback>> itr = callbacks.iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
NavigationCallback next = itr.next().get(); NavigationCallback next = itr.next().get();
if (next == null || (replaced && next.onCancel(this, PathCancelReason.REPLACE)) || next.onBegin(this)) { if (next == null || (replaced && next.onCancel(this, CancelReason.REPLACE)) || next.onBegin(this)) {
itr.remove(); itr.remove();
} }
} }
@ -121,7 +121,7 @@ public class CitizensAI implements AI {
Iterator<WeakReference<NavigationCallback>> itr = callbacks.iterator(); Iterator<WeakReference<NavigationCallback>> itr = callbacks.iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
NavigationCallback next = itr.next().get(); NavigationCallback next = itr.next().get();
if (next == null || (replaced && next.onCancel(this, PathCancelReason.REPLACE)) || next.onBegin(this)) { if (next == null || (replaced && next.onCancel(this, CancelReason.REPLACE)) || next.onBegin(this)) {
itr.remove(); itr.remove();
} }
} }

View File

@ -8,8 +8,8 @@ import net.citizensnpcs.api.ai.NavigationCallback;
import org.bukkit.Location; import org.bukkit.Location;
public class GenericWaypointCallback extends NavigationCallback { public class GenericWaypointCallback extends NavigationCallback {
private Location dest;
private AI ai; private AI ai;
private Location dest;
private boolean executing; private boolean executing;
private Iterator<Waypoint> itr; private Iterator<Waypoint> itr;
private final Iterable<Waypoint> provider; private final Iterable<Waypoint> provider;
@ -27,7 +27,7 @@ public class GenericWaypointCallback extends NavigationCallback {
@Override @Override
public void onAttach(AI ai) { public void onAttach(AI ai) {
this.ai = ai; this.ai = ai;
executing = !ai.hasDestination(); executing |= !ai.hasDestination();
if (!executing) if (!executing)
return; return;
if (dest == null) { if (dest == null) {
@ -42,17 +42,17 @@ public class GenericWaypointCallback extends NavigationCallback {
} }
@Override @Override
public boolean onCancel(AI ai, PathCancelReason reason) { public boolean onCancel(AI ai, CancelReason reason) {
if (executing && reason == PathCancelReason.REPLACE) { if (executing && reason == CancelReason.REPLACE) {
executing = false; executing = false;
} else { return false;
}
executing = true; executing = true;
ensureItr(); ensureItr();
if (dest != null) if (dest == null && itr.hasNext())
dest = itr.next().getLocation();
if (dest != null) {
ai.setDestination(dest); ai.setDestination(dest);
else if (itr.hasNext()) {
ai.setDestination(itr.next().getLocation());
}
} }
return false; return false;
} }
@ -60,8 +60,7 @@ public class GenericWaypointCallback extends NavigationCallback {
@Override @Override
public boolean onCompletion(AI ai) { public boolean onCompletion(AI ai) {
if (executing) { // if we're executing, we need to get the next waypoint if (executing) { // if we're executing, we need to get the next waypoint
if (!itr.hasNext()) ensureItr();
itr = provider.iterator();
dest = itr.hasNext() ? itr.next().getLocation() : null; dest = itr.hasNext() ? itr.next().getLocation() : null;
} else { } else {
executing = true; executing = true;

View File

@ -50,8 +50,8 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable<Waypoi
at.getBlockX(), at.getBlockY(), at.getBlockZ())); at.getBlockX(), at.getBlockY(), at.getBlockZ()));
} else if (waypoints.size() > 0) { } else if (waypoints.size() > 0) {
waypoints.remove(waypoints.size() - 1); waypoints.remove(waypoints.size() - 1);
Messaging.send(player, String.format("<e>Removed<a> a waypoint (<e>%d<a> remaining)", waypoints Messaging.send(player,
.size())); String.format("<e>Removed<a> a waypoint (<e>%d<a> remaining)", waypoints.size()));
} }
} }
}; };
@ -80,16 +80,17 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable<Waypoi
@Override @Override
public void save(DataKey key) { public void save(DataKey key) {
key.removeKey("waypoints");
key = key.getRelative("waypoints"); key = key.getRelative("waypoints");
for (int i = 0; i < waypoints.size(); ++i) { for (int i = 0; i < waypoints.size(); ++i) {
Location location = waypoints.get(i).getLocation(); Location location = waypoints.get(i).getLocation();
key = key.getRelative(Integer.toString(i) + ".location"); DataKey root = key.getRelative(Integer.toString(i) + ".location");
key.setString("world", location.getWorld().getName()); root.setString("world", location.getWorld().getName());
key.setDouble("x", location.getX()); root.setDouble("x", location.getX());
key.setDouble("y", location.getY()); root.setDouble("y", location.getY());
key.setDouble("z", location.getZ()); root.setDouble("z", location.getZ());
key.setDouble("yaw", location.getYaw()); root.setDouble("yaw", location.getYaw());
key.setDouble("pitch", location.getPitch()); root.setDouble("pitch", location.getPitch());
} }
} }
} }

View File

@ -2,6 +2,7 @@ package net.citizensnpcs.trait.waypoint;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import net.citizensnpcs.api.exception.NPCLoadException; import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
@ -18,7 +19,6 @@ public class Waypoints extends Trait {
public Waypoints(NPC npc) { public Waypoints(NPC npc) {
this.npc = npc; this.npc = npc;
npc.getAI().registerNavigationCallback(provider.getCallback());
} }
public Editor getEditor(Player player) { public Editor getEditor(Player player) {
@ -27,12 +27,14 @@ public class Waypoints extends Trait {
@Override @Override
public void load(DataKey key) throws NPCLoadException { public void load(DataKey key) throws NPCLoadException {
provider = null;
providerName = key.getString("provider", "linear"); providerName = key.getString("provider", "linear");
for (Class<? extends WaypointProvider> clazz : providers.keySet()) for (Entry<Class<? extends WaypointProvider>, String> entry : providers.entrySet()) {
if (providers.get(clazz).equals(providerName)) { if (entry.getValue().equals(providerName)) {
provider = create(clazz); provider = create(entry.getKey());
break; break;
} }
}
if (provider == null) if (provider == null)
return; return;
provider.load(key.getRelative(providerName)); provider.load(key.getRelative(providerName));