diff --git a/src/main/java/net/citizensnpcs/Citizens.java b/src/main/java/net/citizensnpcs/Citizens.java index 608918c68..e2f209580 100644 --- a/src/main/java/net/citizensnpcs/Citizens.java +++ b/src/main/java/net/citizensnpcs/Citizens.java @@ -64,6 +64,7 @@ public class Citizens extends JavaPlugin { private Storage saves; private final InstanceFactory traitManager = DefaultInstanceFactory.create(Owner.class, Spawned.class, LookClose.class, SpawnLocation.class, Inventory.class, MobType.class, Waypoints.class, Equipment.class); + public InstanceFactory getCharacterManager() { return characterManager; } @@ -236,7 +237,6 @@ public class Citizens extends JavaPlugin { } public void reload() throws NPCLoadException { - getServer().getScheduler().cancelTasks(this); Editor.leaveAll(); config.load(); for (NPC npc : npcManager) diff --git a/src/main/java/net/citizensnpcs/Toggleable.java b/src/main/java/net/citizensnpcs/Toggleable.java new file mode 100644 index 000000000..cfef0d6f5 --- /dev/null +++ b/src/main/java/net/citizensnpcs/Toggleable.java @@ -0,0 +1,9 @@ +package net.citizensnpcs; + +/** + * Represents a two-state entity which can be toggled on and off. + * + */ +public interface Toggleable { + public void toggle(); +} diff --git a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java index 315077278..a64f8418c 100644 --- a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java @@ -38,13 +38,8 @@ public class NPCCommands { characterManager = plugin.getCharacterManager(); } - @Command( - aliases = { "npc" }, - usage = "character [character]", - desc = "Set the character of an NPC", - modifiers = { "character" }, - min = 2, - max = 2) + @Command(aliases = { "npc" }, usage = "character [character]", desc = "Set the character of an NPC", + modifiers = { "character" }, min = 2, max = 2) public void character(CommandContext args, Player player, NPC npc) throws CommandException { String name = args.getString(1).toLowerCase(); Character character = characterManager.getInstance(name, npc); @@ -55,19 +50,13 @@ public class NPCCommands { if (!player.hasPermission("citizens.npc.character." + character.getName()) && !player.hasPermission("citizens.npc.character.*") && !player.hasPermission("citizens.admin")) throw new NoPermissionsException(); - Messaging.send(player, StringHelper.wrap(npc.getName() + "'s") + " character is now '" - + StringHelper.wrap(name) + "'."); + Messaging.send(player, + StringHelper.wrap(npc.getName() + "'s") + " character is now '" + StringHelper.wrap(name) + "'."); npc.setCharacter(character); } - @Command( - aliases = { "npc" }, - usage = "create [name] (--type (type) --char (char))", - desc = "Create a new NPC", - modifiers = { "create" }, - min = 2, - max = 5, - permission = "npc.create") + @Command(aliases = { "npc" }, usage = "create [name] (--type (type) --char (char))", desc = "Create a new NPC", + modifiers = { "create" }, min = 2, max = 5, permission = "npc.create") @Requirements public void create(CommandContext args, Player player, NPC npc) { String name = args.getString(1); @@ -89,8 +78,9 @@ public class NPCCommands { if (args.hasValueFlag("char")) { String character = args.getFlag("char").toLowerCase(); if (characterManager.getInstance(character, create) == null) { - Messaging.sendError(player, "'" + args.getFlag("char") + "' is not a valid character. " - + create.getName() + " was created at your location without a character."); + Messaging.sendError(player, + "'" + args.getFlag("char") + "' is not a valid character. " + create.getName() + + " was created at your location without a character."); success = false; } else { create.setCharacter(characterManager.getInstance(character, create)); @@ -111,29 +101,16 @@ public class NPCCommands { Messaging.send(player, successMsg); } - @Command( - aliases = { "npc" }, - usage = "despawn", - desc = "Despawn an NPC", - modifiers = { "despawn" }, - min = 1, - max = 1, - permission = "npc.despawn") + @Command(aliases = { "npc" }, usage = "despawn", desc = "Despawn an NPC", modifiers = { "despawn" }, min = 1, + max = 1, permission = "npc.despawn") public void despawn(CommandContext args, Player player, NPC npc) { npc.getTrait(Spawned.class).setSpawned(false); npc.despawn(); Messaging.send(player, ChatColor.GREEN + "You despawned " + StringHelper.wrap(npc.getName()) + "."); } - @Command( - aliases = { "npc" }, - usage = "list (page) ((-a) --owner (owner) --type (type) --char (char))", - desc = "List NPCs", - flags = "a", - modifiers = { "list" }, - min = 1, - max = 2, - permission = "npc.list") + @Command(aliases = { "npc" }, usage = "list (page) ((-a) --owner (owner) --type (type) --char (char))", + desc = "List NPCs", flags = "a", modifiers = { "list" }, min = 1, max = 2, permission = "npc.list") @Requirements public void list(CommandContext args, Player player, NPC npc) throws CommandException { List npcs = new ArrayList(); @@ -216,14 +193,8 @@ public class NPCCommands { Messaging.send(player, " Type: " + npc.getTrait(MobType.class).getType()); } - @Command( - aliases = { "npc" }, - usage = "owner [name]", - desc = "Set the owner of an NPC", - modifiers = { "owner" }, - min = 2, - max = 2, - permission = "npc.owner") + @Command(aliases = { "npc" }, usage = "owner [name]", desc = "Set the owner of an NPC", modifiers = { "owner" }, + min = 2, max = 2, permission = "npc.owner") public void owner(CommandContext args, Player player, NPC npc) throws CommandException { String name = args.getString(1); if (npc.getTrait(Owner.class).getOwner().equals(name)) @@ -233,14 +204,9 @@ public class NPCCommands { + "."); } - @Command( - aliases = { "npc" }, - usage = "remove (all)", - desc = "Remove an NPC", - modifiers = { "remove" }, - min = 1, - max = 2) - @Requirements + @Command(aliases = { "npc" }, usage = "remove (all)", desc = "Remove an NPC", modifiers = { "remove" }, min = 1, + max = 2) + @Requirements(selected = true) public void remove(CommandContext args, Player player, NPC npc) throws CommandException { if (args.argsLength() == 2) { if (!args.getString(1).equals("all")) @@ -251,8 +217,6 @@ public class NPCCommands { Messaging.send(player, "You permanently removed all NPCs."); return; } - if (npc == null) - throw new CommandException("You must have an NPC selected to execute that command."); if (!npc.getTrait(Owner.class).getOwner().equals(player.getName()) && !player.hasPermission("citizens.admin")) throw new CommandException("You must be the owner of this NPC to execute that command."); if (!player.hasPermission("citizens.npc.remove") && !player.hasPermission("citizens.admin")) @@ -261,14 +225,8 @@ public class NPCCommands { Messaging.send(player, "You permanently removed " + StringHelper.wrap(npc.getName()) + "."); } - @Command( - aliases = { "npc" }, - usage = "rename [name]", - desc = "Rename an NPC", - modifiers = { "rename" }, - min = 2, - max = 2, - permission = "npc.rename") + @Command(aliases = { "npc" }, usage = "rename [name]", desc = "Rename an NPC", modifiers = { "rename" }, min = 2, + max = 2, permission = "npc.rename") public void rename(CommandContext args, Player player, NPC npc) { String oldName = npc.getName(); String newName = args.getString(1); @@ -277,18 +235,13 @@ public class NPCCommands { newName = newName.substring(0, 15); } npc.setName(newName); - Messaging.send(player, ChatColor.GREEN + "You renamed " + StringHelper.wrap(oldName) + " to " - + StringHelper.wrap(newName) + "."); + Messaging.send(player, + ChatColor.GREEN + "You renamed " + StringHelper.wrap(oldName) + " to " + StringHelper.wrap(newName) + + "."); } - @Command( - aliases = { "npc" }, - usage = "select [id]", - desc = "Select an NPC with the given ID", - modifiers = { "select" }, - min = 2, - max = 2, - permission = "npc.select") + @Command(aliases = { "npc" }, usage = "select [id]", desc = "Select an NPC with the given ID", + modifiers = { "select" }, min = 2, max = 2, permission = "npc.select") @Requirements(ownership = true) public void select(CommandContext args, Player player, NPC npc) throws CommandException { NPC toSelect = npcManager.getNPC(args.getInteger(1)); @@ -300,14 +253,8 @@ public class NPCCommands { Messaging.sendWithNPC(player, Setting.SELECTION_MESSAGE.asString(), toSelect); } - @Command( - aliases = { "npc" }, - usage = "spawn [id]", - desc = "Spawn an existing NPC", - modifiers = { "spawn" }, - min = 2, - max = 2, - permission = "npc.spawn") + @Command(aliases = { "npc" }, usage = "spawn [id]", desc = "Spawn an existing NPC", modifiers = { "spawn" }, + min = 2, max = 2, permission = "npc.spawn") @Requirements public void spawn(CommandContext args, Player player, NPC npc) throws CommandException { NPC respawn = npcManager.getNPC(args.getInteger(1)); @@ -326,14 +273,8 @@ public class NPCCommands { + " Use '/npc tphere' to teleport the NPC to your location."); } - @Command( - aliases = { "npc" }, - usage = "tp", - desc = "Teleport to an NPC", - modifiers = { "tp", "teleport" }, - min = 1, - max = 1, - permission = "npc.tp") + @Command(aliases = { "npc" }, usage = "tp", desc = "Teleport to an NPC", modifiers = { "tp", "teleport" }, min = 1, + max = 1, permission = "npc.tp") public void tp(CommandContext args, Player player, NPC npc) { // Spawn the NPC if it isn't spawned to prevent NPEs if (!npc.isSpawned()) @@ -342,14 +283,8 @@ public class NPCCommands { Messaging.send(player, ChatColor.GREEN + "You teleported to " + StringHelper.wrap(npc.getName()) + "."); } - @Command( - aliases = { "npc" }, - usage = "tphere", - desc = "Teleport an NPC to your location", - modifiers = { "tphere" }, - min = 1, - max = 1, - permission = "npc.tphere") + @Command(aliases = { "npc" }, usage = "tphere", desc = "Teleport an NPC to your location", + modifiers = { "tphere" }, min = 1, max = 1, permission = "npc.tphere") public void tphere(CommandContext args, Player player, NPC npc) { // Spawn the NPC if it isn't spawned to prevent NPEs if (!npc.isSpawned()) diff --git a/src/main/java/net/citizensnpcs/editor/Editor.java b/src/main/java/net/citizensnpcs/editor/Editor.java index 0a2039904..643a8e0b9 100644 --- a/src/main/java/net/citizensnpcs/editor/Editor.java +++ b/src/main/java/net/citizensnpcs/editor/Editor.java @@ -18,8 +18,8 @@ public abstract class Editor implements Listener { private static void enter(Player player, Editor editor) { editor.begin(); - player.getServer().getPluginManager().registerEvents(editor, - player.getServer().getPluginManager().getPlugin("Citizens")); + player.getServer().getPluginManager() + .registerEvents(editor, player.getServer().getPluginManager().getPlugin("Citizens")); editing.put(player.getName(), editor); } diff --git a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java index 1d04a9ff1..815d6f053 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java @@ -81,12 +81,6 @@ public abstract class CitizensNPC extends AbstractNPC { return getHandle() != null; } - @Override - public void move(int x, int y, int z) { - if (mcEntity != null) - mcEntity.move(x, y, z); - } - @Override public void remove() { manager.remove(this); diff --git a/src/main/java/net/citizensnpcs/npc/CitizensNPCManager.java b/src/main/java/net/citizensnpcs/npc/CitizensNPCManager.java index 01ec49f26..71e3d4461 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensNPCManager.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensNPCManager.java @@ -109,23 +109,30 @@ public class CitizensNPCManager implements NPCManager { if (Bukkit.getPlayer(value.asString()) != null) Bukkit.getPlayer(value.asString()).removeMetadata("selected", plugin); npc.removeMetadata("selectors", plugin); + // TODO: merge this and removeAll(); } public void removeAll() { - while (iterator().hasNext()) { - NPC npc = iterator().next(); + Iterator itr = iterator(); + while (itr.hasNext()) { + NPC npc = itr.next(); saves.getKey("npc").removeKey(String.valueOf(npc.getId())); // Remove metadata from selectors - if (npc.hasMetadata("selectors")) - for (MetadataValue value : npc.getMetadata("selectors")) - if (Bukkit.getPlayer(value.asString()) != null) + if (npc.hasMetadata("selectors")) { + for (MetadataValue value : npc.getMetadata("selectors")) { + if (Bukkit.getPlayer(value.asString()) != null) { Bukkit.getPlayer(value.asString()).removeMetadata("selected", plugin); - npc.removeMetadata("selectors", plugin); + } + } + npc.removeMetadata("selectors", plugin); + } - if (npc.isSpawned()) + if (npc.isSpawned()) { npc.getBukkitEntity().remove(); - iterator().remove(); + } + + itr.remove(); } } diff --git a/src/main/java/net/citizensnpcs/npc/ai/MoveStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/MoveStrategy.java index 97b8b7f0b..002d330de 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/MoveStrategy.java +++ b/src/main/java/net/citizensnpcs/npc/ai/MoveStrategy.java @@ -4,7 +4,6 @@ import java.lang.reflect.Field; import java.util.Random; import net.citizensnpcs.npc.CitizensNPC; -import net.citizensnpcs.util.Messaging; import net.minecraft.server.EntityLiving; import net.minecraft.server.MathHelper; import net.minecraft.server.PathEntity; @@ -58,7 +57,7 @@ public class MoveStrategy implements PathStrategy { @Override public boolean update() { - if (handle.dead) + if (handle.dead || path == null) return true; Vec3D vector = getVector(); if (vector == null) @@ -68,8 +67,10 @@ public class MoveStrategy implements PathStrategy { boolean onFire = handle.fireTicks > 0; double diffX = vector.a - handle.locX; double diffZ = vector.c - handle.locZ; + float diffYaw = getYawDifference(diffZ, diffX); + handle.yaw += diffYaw; + // handle.X += diffYaw; - handle.yaw += getYawDifference(diffZ, diffX); if (vector.b - yHeight > 0.0D) jump(); if (cachedSpeed == null) { @@ -77,12 +78,14 @@ public class MoveStrategy implements PathStrategy { cachedSpeed = SPEED_FIELD.getFloat(handle); } catch (IllegalArgumentException e) { e.printStackTrace(); + cachedSpeed = 0.7F; } catch (IllegalAccessException e) { e.printStackTrace(); + cachedSpeed = 0.7F; } } - Messaging.log(cachedSpeed); handle.e(cachedSpeed); + handle.e(); // handle.walk(); if (handle.positionChanged) diff --git a/src/main/java/net/citizensnpcs/trait/LookClose.java b/src/main/java/net/citizensnpcs/trait/LookClose.java index 771084b9a..8158f32a3 100644 --- a/src/main/java/net/citizensnpcs/trait/LookClose.java +++ b/src/main/java/net/citizensnpcs/trait/LookClose.java @@ -1,8 +1,6 @@ package net.citizensnpcs.trait; -import org.bukkit.Location; -import org.bukkit.entity.Entity; - +import net.citizensnpcs.Toggleable; import net.citizensnpcs.api.exception.NPCLoadException; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.trait.SaveId; @@ -11,8 +9,11 @@ import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.npc.CitizensNPC; import net.minecraft.server.EntityLiving; +import org.bukkit.Location; +import org.bukkit.entity.Entity; + @SaveId("look-close") -public class LookClose extends Trait implements Runnable { +public class LookClose extends Trait implements Runnable, Toggleable { private final NPC npc; private boolean shouldLookClose; @@ -69,10 +70,11 @@ public class LookClose extends Trait implements Runnable { return shouldLookClose; } + @Override public void toggle() { shouldLookClose = !shouldLookClose; } - + @Override public String toString() { return "LookClose{" + shouldLookClose + "}"; diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/GenericWaypointCallback.java b/src/main/java/net/citizensnpcs/trait/waypoint/GenericWaypointCallback.java index 6025ce1c8..baae6463d 100644 --- a/src/main/java/net/citizensnpcs/trait/waypoint/GenericWaypointCallback.java +++ b/src/main/java/net/citizensnpcs/trait/waypoint/GenericWaypointCallback.java @@ -4,6 +4,7 @@ import java.util.Iterator; import net.citizensnpcs.api.ai.AI; import net.citizensnpcs.api.ai.NavigationCallback; +import net.citizensnpcs.util.Messaging; import org.bukkit.Location; @@ -16,10 +17,6 @@ public class GenericWaypointCallback extends NavigationCallback { public GenericWaypointCallback(Iterable provider) { this.provider = provider; - this.itr = provider.iterator(); - if (itr.hasNext()) { - dest = itr.next().getLocation(); - } } private void ensureItr() { @@ -64,6 +61,7 @@ public class GenericWaypointCallback extends NavigationCallback { public boolean onCompletion(AI ai) { if (executing) { // if we're executing, we need to get the next waypoint dest = itr.hasNext() ? itr.next().getLocation() : null; + Messaging.log("fetched next"); } else { executing = true; // we're free to return to our waypoints! diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java b/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java index 487796026..062db0adb 100644 --- a/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java +++ b/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java @@ -1,5 +1,6 @@ package net.citizensnpcs.trait.waypoint; +import net.citizensnpcs.api.ai.AI; import net.citizensnpcs.api.ai.NavigationCallback; import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.editor.Editor; @@ -7,12 +8,36 @@ import net.citizensnpcs.editor.Editor; import org.bukkit.entity.Player; public interface WaypointProvider { - + /** + * Creates an {@link Editor} with the given {@link Player}. + * + * @param player + * The player to link the editor with + * @return The editor + */ public Editor createEditor(Player player); + /** + * Returns the {@link NavigationCallback} linked to this provider. This will + * be linked to the NPC's {@link AI}. + * + * @return The callback in use + */ public NavigationCallback getCallback(); + /** + * Loads from the specified {@link DataKey}. + * + * @param key + * The key to load from + */ public void load(DataKey key); + /** + * Saves to the specified {@link DataKey}. + * + * @param key + * The key to save to + */ public void save(DataKey key); } \ No newline at end of file diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java index 19a23773d..892528708 100644 --- a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java +++ b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java @@ -44,13 +44,32 @@ public class Waypoints extends Trait { key.setString("provider", providerName); } - public void setWaypointProvider(WaypointProvider provider, String name) { - this.provider = provider; - providerName = name; + /** + * Sets the current {@link WaypointProvider} by using the given name. The + * name should have been registered using + * {@link Waypoints#registerWaypointProvider(Class, String)}. + * + * @param provider + * @param name + */ + public void setWaypointProvider(String name) { + this.provider = providers.getInstance(name); + if (this.provider != null) { + providerName = name; + } } private static final InstanceFactory providers = DefaultInstanceFactory.create(); + /** + * Registers a {@link WaypointProvider}, which can be subsequently used by + * NPCs. + * + * @param clazz + * The class of the waypoint provider + * @param name + * The name of the waypoint provider + */ public static void registerWaypointProvider(Class clazz, String name) { providers.register(clazz, name); }