From 3ef703bdcd9aeca046aa12a1f5f7869c83f7fb4a Mon Sep 17 00:00:00 2001 From: fullwall Date: Fri, 8 Nov 2013 00:08:50 +0800 Subject: [PATCH] Allow /npc spawn and /npc despawn to use names as well instead of ids --- .../commands/NPCCommandSelector.java | 123 ++++++++++++++++ .../citizensnpcs/commands/NPCCommands.java | 139 ++++++++---------- .../commands/SelectionPrompt.java | 63 -------- 3 files changed, 187 insertions(+), 138 deletions(-) create mode 100644 src/main/java/net/citizensnpcs/commands/NPCCommandSelector.java delete mode 100644 src/main/java/net/citizensnpcs/commands/SelectionPrompt.java diff --git a/src/main/java/net/citizensnpcs/commands/NPCCommandSelector.java b/src/main/java/net/citizensnpcs/commands/NPCCommandSelector.java new file mode 100644 index 000000000..a6bdf0b5d --- /dev/null +++ b/src/main/java/net/citizensnpcs/commands/NPCCommandSelector.java @@ -0,0 +1,123 @@ +package net.citizensnpcs.commands; + +import java.util.List; + +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.command.CommandContext; +import net.citizensnpcs.api.command.CommandMessages; +import net.citizensnpcs.api.command.exception.CommandException; +import net.citizensnpcs.api.command.exception.CommandUsageException; +import net.citizensnpcs.api.command.exception.ServerCommandException; +import net.citizensnpcs.api.command.exception.UnhandledCommandException; +import net.citizensnpcs.api.command.exception.WrappedCommandException; +import net.citizensnpcs.api.npc.NPC; +import net.citizensnpcs.api.npc.NPCRegistry; +import net.citizensnpcs.api.util.Messaging; +import net.citizensnpcs.util.Messages; +import net.citizensnpcs.util.Util; + +import org.bukkit.command.CommandSender; +import org.bukkit.conversations.Conversable; +import org.bukkit.conversations.Conversation; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.ConversationFactory; +import org.bukkit.conversations.NumericPrompt; +import org.bukkit.conversations.Prompt; + +import com.google.common.collect.Lists; + +public class NPCCommandSelector extends NumericPrompt { + private final Callback callback; + private final List choices; + + public NPCCommandSelector(Callback callback, List possible) { + this.callback = callback; + this.choices = possible; + } + + @Override + protected Prompt acceptValidatedInput(ConversationContext context, Number input) { + boolean found = false; + for (NPC npc : choices) { + if (input.intValue() == npc.getId()) { + found = true; + break; + } + } + CommandSender sender = (CommandSender) context.getForWhom(); + if (!found) { + Messaging.sendErrorTr(sender, Messages.SELECTION_PROMPT_INVALID_CHOICE, input); + return this; + } + NPC toSelect = CitizensAPI.getNPCRegistry().getById(input.intValue()); + try { + callback.run(toSelect); + } catch (ServerCommandException ex) { + Messaging.sendTr(sender, CommandMessages.MUST_BE_INGAME); + } catch (CommandUsageException ex) { + Messaging.sendError(sender, ex.getMessage()); + Messaging.sendError(sender, ex.getUsage()); + } catch (UnhandledCommandException ex) { + ex.printStackTrace(); + } catch (WrappedCommandException ex) { + ex.getCause().printStackTrace(); + } catch (CommandException ex) { + Messaging.sendError(sender, ex.getMessage()); + } catch (NumberFormatException ex) { + Messaging.sendErrorTr(sender, CommandMessages.INVALID_NUMBER); + } + return null; + } + + @Override + public String getPromptText(ConversationContext context) { + String text = Messaging.tr(Messages.SELECTION_PROMPT); + for (NPC npc : choices) { + text += "\n - " + npc.getId(); + } + return text; + } + + public static interface Callback { + public void run(NPC npc) throws CommandException; + } + + public static void start(Callback callback, Conversable player, List possible) { + final Conversation conversation = new ConversationFactory(CitizensAPI.getPlugin()).withLocalEcho(false) + .withEscapeSequence("exit").withModality(false) + .withFirstPrompt(new NPCCommandSelector(callback, possible)).buildConversation(player); + conversation.begin(); + } + + public static void startWithCallback(Callback callback, NPCRegistry npcRegistry, CommandSender sender, + CommandContext args, String raw) throws CommandException { + try { + int id = Integer.parseInt(raw); + callback.run(npcRegistry.getById(id)); + return; + } catch (NumberFormatException ex) { + String name = args.getString(1); + List possible = Lists.newArrayList(); + double range = -1; + if (args.hasValueFlag("r")) { + range = Math.abs(args.getFlagDouble("r")); + } + for (NPC test : npcRegistry) { + if (test.getName().equalsIgnoreCase(name)) { + if (range > 0 + && test.isSpawned() + && !Util.locationWithinRange(args.getSenderLocation(), test.getEntity().getLocation(), + range)) + continue; + possible.add(test); + } + } + if (possible.size() == 1) { + callback.run(possible.get(0)); + } else if (possible.size() > 1) { + NPCCommandSelector.start(callback, (Conversable) sender, possible); + return; + } + } + } +} diff --git a/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/src/main/java/net/citizensnpcs/commands/NPCCommands.java index e5afd472f..3e1a9b34b 100644 --- a/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -62,7 +62,6 @@ import org.bukkit.World; import org.bukkit.command.BlockCommandSender; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.conversations.Conversable; import org.bukkit.entity.Ageable; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -78,7 +77,6 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import com.google.common.base.Splitter; import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; @Requirements(selected = true, ownership = true) public class NPCCommands { @@ -406,18 +404,26 @@ public class NPCCommands { max = 2, permission = "citizens.npc.despawn") @Requirements - public void despawn(CommandContext args, CommandSender sender, NPC npc) throws CommandException { + public void despawn(final CommandContext args, final CommandSender sender, NPC npc) throws CommandException { + NPCCommandSelector.Callback callback = new NPCCommandSelector.Callback() { + @Override + public void run(NPC npc) throws CommandException { + if (npc == null) { + throw new CommandException(Messages.NO_NPC_WITH_ID_FOUND, args.getString(1)); + } + npc.getTrait(Spawned.class).setSpawned(false); + npc.despawn(DespawnReason.REMOVAL); + Messaging.sendTr(sender, Messages.NPC_DESPAWNED, npc.getName()); + } + }; if (npc == null || args.argsLength() == 2) { - if (args.argsLength() < 2) + if (args.argsLength() < 2) { throw new CommandException(Messages.COMMAND_MUST_HAVE_SELECTED); - int id = args.getInteger(1); - npc = CitizensAPI.getNPCRegistry().getById(id); - if (npc == null) - throw new CommandException(Messages.NO_NPC_WITH_ID_FOUND, id); + } + NPCCommandSelector.startWithCallback(callback, npcRegistry, sender, args, args.getString(1)); + } else { + callback.run(npc); } - npc.getTrait(Spawned.class).setSpawned(false); - npc.despawn(DespawnReason.REMOVAL); - Messaging.sendTr(sender, Messages.NPC_DESPAWNED, npc.getName()); } @Command( @@ -1013,8 +1019,18 @@ public class NPCCommands { max = 2, permission = "citizens.npc.select") @Requirements - public void select(CommandContext args, CommandSender sender, NPC npc) throws CommandException { - NPC toSelect = null; + public void select(CommandContext args, final CommandSender sender, final NPC npc) throws CommandException { + NPCCommandSelector.Callback callback = new NPCCommandSelector.Callback() { + @Override + public void run(NPC toSelect) throws CommandException { + if (toSelect == null || !toSelect.getTrait(Spawned.class).shouldSpawn()) + throw new CommandException(Messages.NPC_NOT_FOUND); + if (npc != null && toSelect.getId() == npc.getId()) + throw new CommandException(Messages.NPC_ALREADY_SELECTED); + selector.select(sender, toSelect); + Messaging.sendWithNPC(sender, Setting.SELECTION_MESSAGE.asString(), toSelect); + } + }; if (args.argsLength() <= 1) { if (!(sender instanceof Player)) throw new ServerCommandException(); @@ -1033,44 +1049,12 @@ public class NPCCommands { NPC test = npcRegistry.getNPC(possibleNPC); if (test == null) continue; - toSelect = test; + callback.run(test); break; } } else { - try { - int id = args.getInteger(1); - toSelect = npcRegistry.getById(id); - } catch (NumberFormatException ex) { - String name = args.getString(1); - List possible = Lists.newArrayList(); - double range = -1; - if (args.hasValueFlag("r")) { - range = Math.abs(args.getFlagDouble("r")); - } - for (NPC test : npcRegistry) { - if (test.getName().equalsIgnoreCase(name)) { - if (range > 0 - && test.isSpawned() - && !Util.locationWithinRange(args.getSenderLocation(), test.getEntity().getLocation(), - range)) - continue; - possible.add(test); - } - } - if (possible.size() == 1) { - toSelect = possible.get(0); - } else if (possible.size() > 1) { - SelectionPrompt.start(selector, (Conversable) sender, possible); - return; - } - } + NPCCommandSelector.startWithCallback(callback, npcRegistry, sender, args, args.getString(1)); } - if (toSelect == null || !toSelect.getTrait(Spawned.class).shouldSpawn()) - throw new CommandException(Messages.NPC_NOT_FOUND); - if (npc != null && toSelect.getId() == npc.getId()) - throw new CommandException(Messages.NPC_ALREADY_SELECTED); - selector.select(sender, toSelect); - Messaging.sendWithNPC(sender, Setting.SELECTION_MESSAGE.asString(), toSelect); } @Command(aliases = { "npc" }, usage = "skeletontype [type]", desc = "Sets the NPC's skeleton type", modifiers = { @@ -1106,40 +1090,44 @@ public class NPCCommands { @Command( aliases = { "npc" }, - usage = "spawn (id)", + usage = "spawn (id|name)", desc = "Spawn an existing NPC", modifiers = { "spawn" }, min = 1, max = 2, permission = "citizens.npc.spawn") @Requirements(ownership = true) - public void spawn(CommandContext args, CommandSender sender, NPC npc) throws CommandException { - NPC respawn = null; - try { - respawn = args.argsLength() > 1 ? npcRegistry.getById(args.getInteger(1)) : npc; - } catch (NumberFormatException ex) { - Messaging.sendTr(sender, Messages.SPAWN_NUMERIC_ID_ONLY); - return; - } - if (respawn == null) { - if (args.argsLength() > 1) { - throw new CommandException(Messages.NO_NPC_WITH_ID_FOUND, args.getInteger(1)); - } else { - throw new CommandException(CommandMessages.MUST_HAVE_SELECTED); - } - } - if (respawn.isSpawned()) - throw new CommandException(Messages.NPC_ALREADY_SPAWNED, respawn.getName()); - Location location = respawn.getTrait(CurrentLocation.class).getLocation(); - if (location == null || args.hasValueFlag("location")) { - if (args.getSenderLocation() == null) - throw new CommandException(Messages.NO_STORED_SPAWN_LOCATION); + public void spawn(final CommandContext args, final CommandSender sender, NPC npc) throws CommandException { + NPCCommandSelector.Callback callback = new NPCCommandSelector.Callback() { + @Override + public void run(NPC respawn) throws CommandException { + if (respawn == null) { + if (args.argsLength() > 1) { + throw new CommandException(Messages.NO_NPC_WITH_ID_FOUND, args.getString(1)); + } else { + throw new CommandException(CommandMessages.MUST_HAVE_SELECTED); + } + } + if (respawn.isSpawned()) { + throw new CommandException(Messages.NPC_ALREADY_SPAWNED, respawn.getName()); + } + Location location = respawn.getTrait(CurrentLocation.class).getLocation(); + if (location == null || args.hasValueFlag("location")) { + if (args.getSenderLocation() == null) + throw new CommandException(Messages.NO_STORED_SPAWN_LOCATION); - location = args.getSenderLocation(); - } - if (respawn.spawn(location)) { - selector.select(sender, respawn); - Messaging.sendTr(sender, Messages.NPC_SPAWNED, respawn.getName()); + location = args.getSenderLocation(); + } + if (respawn.spawn(location)) { + selector.select(sender, respawn); + Messaging.sendTr(sender, Messages.NPC_SPAWNED, respawn.getName()); + } + } + }; + if (args.argsLength() > 1) { + NPCCommandSelector.startWithCallback(callback, npcRegistry, sender, args, args.getString(1)); + } else { + callback.run(npc); } } @@ -1278,8 +1266,9 @@ public class NPCCommands { try { int id = args.getInteger(1); NPC fromNPC = CitizensAPI.getNPCRegistry().getById(id); - if (fromNPC != null) + if (fromNPC != null) { from = fromNPC.getEntity(); + } } catch (NumberFormatException e) { from = Bukkit.getPlayerExact(args.getString(1)); firstWasPlayer = true; diff --git a/src/main/java/net/citizensnpcs/commands/SelectionPrompt.java b/src/main/java/net/citizensnpcs/commands/SelectionPrompt.java deleted file mode 100644 index 6d8c3ae1f..000000000 --- a/src/main/java/net/citizensnpcs/commands/SelectionPrompt.java +++ /dev/null @@ -1,63 +0,0 @@ -package net.citizensnpcs.commands; - -import java.util.List; - -import net.citizensnpcs.Settings.Setting; -import net.citizensnpcs.api.CitizensAPI; -import net.citizensnpcs.api.npc.NPC; -import net.citizensnpcs.api.util.Messaging; -import net.citizensnpcs.npc.NPCSelector; -import net.citizensnpcs.util.Messages; - -import org.bukkit.command.CommandSender; -import org.bukkit.conversations.Conversable; -import org.bukkit.conversations.Conversation; -import org.bukkit.conversations.ConversationContext; -import org.bukkit.conversations.ConversationFactory; -import org.bukkit.conversations.NumericPrompt; -import org.bukkit.conversations.Prompt; - -public class SelectionPrompt extends NumericPrompt { - private final List choices; - private final NPCSelector selector; - - public SelectionPrompt(NPCSelector selector, List possible) { - choices = possible; - this.selector = selector; - } - - @Override - protected Prompt acceptValidatedInput(ConversationContext context, Number input) { - boolean found = false; - for (NPC npc : choices) { - if (input.intValue() == npc.getId()) { - found = true; - break; - } - } - CommandSender sender = (CommandSender) context.getForWhom(); - if (!found) { - Messaging.sendErrorTr(sender, Messages.SELECTION_PROMPT_INVALID_CHOICE, input); - return this; - } - NPC toSelect = CitizensAPI.getNPCRegistry().getById(input.intValue()); - selector.select(sender, toSelect); - Messaging.sendWithNPC(sender, Setting.SELECTION_MESSAGE.asString(), toSelect); - return null; - } - - @Override - public String getPromptText(ConversationContext context) { - String text = Messaging.tr(Messages.SELECTION_PROMPT); - for (NPC npc : choices) - text += "\n - " + npc.getId(); - return text; - } - - public static void start(NPCSelector selector, Conversable player, List possible) { - final Conversation conversation = new ConversationFactory(CitizensAPI.getPlugin()).withLocalEcho(false) - .withEscapeSequence("exit").withModality(false) - .withFirstPrompt(new SelectionPrompt(selector, possible)).buildConversation(player); - conversation.begin(); - } -}