diff --git a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java index 83b44e7b2..f178a14f8 100644 --- a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java @@ -9,7 +9,6 @@ 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; @@ -30,6 +29,7 @@ import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.EntityControllers; import net.citizensnpcs.npc.NPCSelector; import net.citizensnpcs.npc.Template; +import net.citizensnpcs.npc.ai.speech.TalkableEntity; import net.citizensnpcs.trait.Age; import net.citizensnpcs.trait.Anchors; import net.citizensnpcs.trait.Behaviour; @@ -967,28 +967,29 @@ public class NPCCommands { usage = "speak message to speak --target npcid|player_name --type vocal_type", desc = "Uses the NPCs SpeechController to talk", modifiers = { "speak" }, - min = 1, - max = 3, + min = 2, 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) { + String message = StringHelper.parseColors(args.getJoinedStrings(1)); + + if (message.length() <= 0) { Messaging.send(sender, "Default Vocal Chord for " + npc.getName() + ": " + npc.getTrait(Speech.class).getDefaultVocalChord()); return; } - SpeechContext context = new SpeechContext(args.getJoinedStrings(1)); + + SpeechContext context = new SpeechContext(message); 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)); + context.addRecipient(target.getBukkitEntity()); } else { Player player = Bukkit.getPlayer(args.getFlag("target")); if (player != null) - context.addRecipient(new TalkableEntity(player)); + context.addRecipient(player); } } @@ -997,9 +998,7 @@ public class NPCCommands { type = args.getFlag("type"); } - if (context.hasRecipients()) - Util.faceEntity(npc.getBukkitEntity(), context.iterator().next().getEntity()); - npc.getDefaultSpeechController().speak(new SpeechContext(args.getJoinedStrings(1)), type); + npc.getDefaultSpeechController().speak(context, type); } @Command( diff --git a/src/main/java/net/citizensnpcs/npc/ai/speech/Chat.java b/src/main/java/net/citizensnpcs/npc/ai/speech/Chat.java index 1883539f4..34ea75409 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/speech/Chat.java +++ b/src/main/java/net/citizensnpcs/npc/ai/speech/Chat.java @@ -10,7 +10,6 @@ import org.bukkit.entity.LivingEntity; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.ai.speech.Talkable; -import net.citizensnpcs.api.ai.speech.TalkableEntity; import net.citizensnpcs.api.ai.speech.SpeechContext; import net.citizensnpcs.api.ai.speech.VocalChord; import net.citizensnpcs.api.npc.NPC; @@ -108,6 +107,7 @@ public class Chat implements VocalChord { if (context.hasRecipients()) { for (Talkable target : context) if (target.getEntity() == bystander) continue; + else new TalkableEntity((LivingEntity) bystander).talkNear(context, text, this); } else // Found a nearby LivingEntity, make it Talkable and talkNear it new TalkableEntity((LivingEntity) bystander).talkNear(context, text, this); 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 b46a37d23..1c9d4176a 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/speech/CitizensSpeechFactory.java +++ b/src/main/java/net/citizensnpcs/npc/ai/speech/CitizensSpeechFactory.java @@ -4,9 +4,12 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import org.bukkit.entity.LivingEntity; + import com.google.common.base.Preconditions; import net.citizensnpcs.api.ai.speech.SpeechFactory; +import net.citizensnpcs.api.ai.speech.Talkable; import net.citizensnpcs.api.ai.speech.VocalChord; public class CitizensSpeechFactory implements SpeechFactory { @@ -65,4 +68,12 @@ public class CitizensSpeechFactory implements SpeechFactory { registered.put(name.toLowerCase(), clazz); } + @Override + public Talkable newTalkableEntity(LivingEntity entity) { + if (entity == null) return null; + return new TalkableEntity(entity); + } + + + } diff --git a/src/main/java/net/citizensnpcs/npc/ai/speech/TalkableEntity.java b/src/main/java/net/citizensnpcs/npc/ai/speech/TalkableEntity.java new file mode 100644 index 000000000..f2ae0a82e --- /dev/null +++ b/src/main/java/net/citizensnpcs/npc/ai/speech/TalkableEntity.java @@ -0,0 +1,91 @@ +package net.citizensnpcs.npc.ai.speech; + +import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.ai.speech.SpeechContext; +import net.citizensnpcs.api.ai.speech.Talkable; +import net.citizensnpcs.api.ai.speech.VocalChord; +import net.citizensnpcs.api.ai.speech.event.SpeechBystanderEvent; +import net.citizensnpcs.api.ai.speech.event.SpeechTargetedEvent; +import net.citizensnpcs.api.npc.NPC; +import net.citizensnpcs.util.Messaging; + +import org.bukkit.Bukkit; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +public class TalkableEntity implements Talkable { + + LivingEntity entity; + + public TalkableEntity(LivingEntity entity) { + this.entity = entity; + } + + public TalkableEntity(NPC npc) { + entity = npc.getBukkitEntity(); + } + + public TalkableEntity(Player player) { + entity = (LivingEntity) player; + } + + /** + * Used to compare a LivingEntity to this TalkableEntity + * + * @return + * 0 if the Entities are the same, 1 if they are not, -1 if + * the object compared is not a valid LivingEntity + */ + @Override + public int compareTo(Object o) { + // If not living entity, return -1 + if (!(o instanceof LivingEntity)) return -1; + // If NPC and matches, return 0 + else if (CitizensAPI.getNPCRegistry().isNPC((LivingEntity) o) + && CitizensAPI.getNPCRegistry().isNPC((LivingEntity) entity) + && CitizensAPI.getNPCRegistry().getNPC((LivingEntity) o).getId() == + CitizensAPI.getNPCRegistry().getNPC((LivingEntity) entity).getId()) + return 0; + else if ((LivingEntity) o == entity) return 0; + // Not a match, return 1 + else return 1; + } + + @Override + public LivingEntity getEntity() { + return entity; + } + + @Override + public String getName() { + if (CitizensAPI.getNPCRegistry().isNPC(entity)) + return CitizensAPI.getNPCRegistry().getNPC(entity).getName(); + else if (entity instanceof Player) + return ((Player) entity).getName(); + else + return entity.getType().name().replace("_", " "); + } + + private void talk(String message) { + if (entity instanceof Player + && !CitizensAPI.getNPCRegistry().isNPC(entity)) + Messaging.send((Player) entity, message); + } + + @Override + public void talkNear(SpeechContext context, String text, VocalChord vocalChord) { + SpeechBystanderEvent event = new SpeechBystanderEvent(this, context, text, vocalChord); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) return; + else talk(event.getMessage()); + } + + @Override + public void talkTo(SpeechContext context, String text, VocalChord vocalChord) { + SpeechTargetedEvent event = new SpeechTargetedEvent(this, context, text, vocalChord); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) return; + else talk(event.getMessage()); + } + +} diff --git a/src/main/java/net/citizensnpcs/trait/text/Text.java b/src/main/java/net/citizensnpcs/trait/text/Text.java index 5283d3b0e..a863d2a6b 100644 --- a/src/main/java/net/citizensnpcs/trait/text/Text.java +++ b/src/main/java/net/citizensnpcs/trait/text/Text.java @@ -12,12 +12,12 @@ import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.ai.speech.SpeechContext; import net.citizensnpcs.api.ai.speech.Talkable; -import net.citizensnpcs.api.ai.speech.TalkableEntity; import net.citizensnpcs.api.event.NPCRightClickEvent; import net.citizensnpcs.api.exception.NPCLoadException; import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.editor.Editor; +import net.citizensnpcs.npc.ai.speech.TalkableEntity; import net.citizensnpcs.trait.Toggleable; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.Messaging; @@ -194,7 +194,6 @@ public class Text extends Trait implements Runnable, Toggleable, Listener, Conve } 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; }