diff --git a/src/main/java/net/citizensnpcs/Settings.java b/src/main/java/net/citizensnpcs/Settings.java index 06ba0030a..554b3eb14 100644 --- a/src/main/java/net/citizensnpcs/Settings.java +++ b/src/main/java/net/citizensnpcs/Settings.java @@ -45,12 +45,12 @@ public class Settings { public enum Setting { CHAT_FORMAT("npc.chat.format.no-targets", "[]: "), CHAT_FORMAT_TO_TARGET("npc.chat.format.to-target", "[] -> You: "), - CHAT_FORMAT_TO_BYSTANDERS("npc.chat.prefix.to-bystanders", "[] -> []: "), - CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS("npc.chat.format.with-target-to-bystanders", "[] -> []: "), + CHAT_FORMAT_TO_BYSTANDERS("npc.chat.format.with-target-to-bystanders", "[] -> []: "), + CHAT_FORMAT_WITH_TARGETS_TO_BYSTANDERS("npc.chat.format.with-targets-to-bystanders", "[] -> []: "), CHAT_RANGE("npc.chat.options.range", 5), CHAT_BYSTANDERS_HEAR_TARGETED_CHAT("npc.chat.options.bystanders-hear-targeted-chat", true), - CHAT_MAX_NUMBER_OF_TARGETS("npc.chat.options.max-number-of-targets-to-show", 3), - CHAT_MULTIPLE_TARGETS_FORMAT("npc.chat.options.multiple-targets-format", ",||& |& others"), + CHAT_MAX_NUMBER_OF_TARGETS("npc.chat.options.max-number-of-targets-to-show", 2), + CHAT_MULTIPLE_TARGETS_FORMAT("npc.chat.options.multiple-targets-format", "|, | & | & others"), DATABASE_DRIVER("storage.database.driver", ""), DATABASE_PASSWORD("storage.database.password", ""), DATABASE_URL("storage.database.url", ""), diff --git a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java index b000892d5..e60de5abb 100644 --- a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java @@ -8,6 +8,8 @@ import java.util.List; import net.citizensnpcs.Citizens; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.ai.speech.SpeechContext; +import net.citizensnpcs.api.ai.speech.TalkableEntity; import net.citizensnpcs.api.event.PlayerCreateNPCEvent; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPCRegistry; @@ -15,6 +17,7 @@ import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.trait.trait.MobType; import net.citizensnpcs.api.trait.trait.Owner; import net.citizensnpcs.api.trait.trait.Spawned; +import net.citizensnpcs.api.trait.trait.Speech; import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.api.util.MemoryDataKey; import net.citizensnpcs.command.Command; @@ -959,6 +962,47 @@ public class NPCCommands { } } + @Command( + aliases = { "npc" }, + usage = "speak message to speak --type vocalChordType ", + desc = "Uses the NPCs SpeechController to talk", + modifiers = { "speak" }, + min = 1, + max = 3, + permission = "npc.speak") + public void speak(CommandContext args, CommandSender sender, NPC npc) throws CommandException { + + String type = npc.getTrait(Speech.class).getDefaultVocalChord(); + + if (args.length() < 1) { + Messaging.send(sender, "Default Vocal Chord for " + npc.getName() + ": " + npc.getTrait(Speech.class).getDefaultVocalChord()); + return; + } + Messaging.send(sender, "TEST: " + args.getJoinedStrings(1)); + SpeechContext context = new SpeechContext(args.getJoinedStrings(1)); + + if (args.hasValueFlag("target")) { + if (args.getFlag("target").matches("\\d+")) { + NPC target = CitizensAPI.getNPCRegistry().getById(Integer.valueOf(args.getFlag("target"))); + if ( target != null) + context.addRecipient(new TalkableEntity(target)); + } else { + Player player = Bukkit.getPlayer(args.getFlag("target")); + if (player != null) + context.addRecipient(new TalkableEntity(player)); + } + } + + if (args.hasValueFlag("type")) { + if (CitizensAPI.getSpeechFactory().isRegistered(args.getFlag("type"))) + type = args.getFlag("type"); + } + + if (context.hasRecipients()) + Util.faceEntity(npc.getBukkitEntity(), context.iterator().next().getEntity()); + npc.getDefaultSpeechController().speak(new SpeechContext(args.getJoinedStrings(1)), type); + } + @Command( aliases = { "npc" }, usage = "speed [speed]", diff --git a/src/main/java/net/citizensnpcs/npc/ai/speech/CitizensSpeechFactory.java b/src/main/java/net/citizensnpcs/npc/ai/speech/CitizensSpeechFactory.java index 983017cc1..b46a37d23 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/speech/CitizensSpeechFactory.java +++ b/src/main/java/net/citizensnpcs/npc/ai/speech/CitizensSpeechFactory.java @@ -4,6 +4,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import com.google.common.base.Preconditions; + import net.citizensnpcs.api.ai.speech.SpeechFactory; import net.citizensnpcs.api.ai.speech.VocalChord; @@ -12,20 +14,23 @@ public class CitizensSpeechFactory implements SpeechFactory { Map> registered = new HashMap>(); @Override - public void register(Class clazz, String name) { - registered.put(name, clazz); - } - - @Override - public String getVocalChordName(Class clazz) { - for (Entry> vocalChord : registered.entrySet()) - if (vocalChord.getValue() == clazz) return vocalChord.getKey(); + public VocalChord getVocalChord(Class clazz) { + // Return a new instance of the VocalChord specified + try { + return clazz.newInstance(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } return null; } @Override public VocalChord getVocalChord(String name) { - if (registered.containsKey(name.toLowerCase())) + // Check if VocalChord name is a registered type + if (isRegistered(name)) + // Return a new instance of the VocalChord specified try { return registered.get(name.toLowerCase()).newInstance(); } catch (InstantiationException e) { @@ -37,15 +42,27 @@ public class CitizensSpeechFactory implements SpeechFactory { } @Override - public VocalChord getVocalChord(Class clazz) { - try { - return clazz.newInstance(); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } + public String getVocalChordName(Class clazz) { + // Get the name of a VocalChord class that has been registered + for (Entry> vocalChord : registered.entrySet()) + if (vocalChord.getValue() == clazz) return vocalChord.getKey(); + return null; } + @Override + public boolean isRegistered(String name) { + if (registered.containsKey(name.toLowerCase())) return true; + else return false; + } + + @Override + public void register(Class clazz, String name) { + Preconditions.checkNotNull(name, "info cannot be null"); + Preconditions.checkNotNull(clazz, "vocalchord cannot be null"); + if (registered.containsKey(name.toLowerCase())) + throw new IllegalArgumentException("vocalchord name already registered"); + registered.put(name.toLowerCase(), clazz); + } + } diff --git a/src/main/java/net/citizensnpcs/trait/text/Text.java b/src/main/java/net/citizensnpcs/trait/text/Text.java index 8013d2275..5283d3b0e 100644 --- a/src/main/java/net/citizensnpcs/trait/text/Text.java +++ b/src/main/java/net/citizensnpcs/trait/text/Text.java @@ -193,7 +193,8 @@ public class Text extends Trait implements Runnable, Toggleable, Listener, Conve index = currentIndex++; } - npc.getDefaultSpeechController().speak(new SpeechContext(text.get(index), new TalkableEntity(player))); + npc.getDefaultSpeechController().speak(new SpeechContext(text.get(index), player)); + Messaging.log("Talking..."); // Messaging.sendWithNPC(player, Setting.CHAT_PREFIX.asString() + text.get(index), npc); return true; }