diff --git a/src/main/java/net/citizensnpcs/Settings.java b/src/main/java/net/citizensnpcs/Settings.java index 648ae1a89..a9b5e8165 100644 --- a/src/main/java/net/citizensnpcs/Settings.java +++ b/src/main/java/net/citizensnpcs/Settings.java @@ -39,6 +39,8 @@ public class Settings { QUICK_SELECT("npc.selection.quick-select", false), SELECTION_ITEM("npc.selection.item", 280), SELECTION_MESSAGE("npc.selection.message", "You selected !"), + TALK_CLOSE_MAXIMUM_COOLDOWN("npc.talk.max-cooldown", 60), + TALK_CLOSE_MINIMUM_COOLDOWN("npc.talk.min-cooldown", 30), USE_DATABASE("use-database", false); private String path; diff --git a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java index 315077278..89bd2fb78 100644 --- a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java +++ b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java @@ -19,6 +19,7 @@ import net.citizensnpcs.command.exception.CommandException; import net.citizensnpcs.command.exception.NoPermissionsException; import net.citizensnpcs.npc.CitizensNPCManager; import net.citizensnpcs.trait.LookClose; +import net.citizensnpcs.trait.text.Text; import net.citizensnpcs.util.Messaging; import net.citizensnpcs.util.Paginator; import net.citizensnpcs.util.StringHelper; @@ -197,8 +198,14 @@ public class NPCCommands { throw new CommandException("The page '" + page + "' does not exist."); } - @Command(aliases = { "npc" }, usage = "lookclose", desc = "Toggle an NPC's look-close state", modifiers = { - "lookclose", "look", "rotate" }, min = 1, max = 1, permission = "npc.lookclose") + @Command( + aliases = { "npc" }, + usage = "lookclose", + desc = "Toggle whether an NPC will look when a player is near", + modifiers = { "lookclose", "look", "rotate" }, + min = 1, + max = 1, + permission = "npc.lookclose") public void lookClose(CommandContext args, Player player, NPC npc) { LookClose trait = npc.getTrait(LookClose.class); trait.toggle(); @@ -326,6 +333,22 @@ public class NPCCommands { + " Use '/npc tphere' to teleport the NPC to your location."); } + @Command( + aliases = { "npc" }, + usage = "talkclose", + desc = "Toggle whether an NPC talks when a player is near", + modifiers = { "talkclose", "talk" }, + min = 1, + max = 1, + permission = "npc.talkclose") + public void talkClose(CommandContext args, Player player, NPC npc) { + Text trait = npc.getTrait(Text.class); + trait.toggle(); + String msg = StringHelper.wrap(npc.getName()) + " will " + + (trait.shouldTalkClose() ? "now talk" : "no longer talk"); + Messaging.send(player, msg += " when a player is nearby."); + } + @Command( aliases = { "npc" }, usage = "tp", diff --git a/src/main/java/net/citizensnpcs/trait/Toggleable.java b/src/main/java/net/citizensnpcs/trait/Toggleable.java index a2daec244..a2f2e2673 100644 --- a/src/main/java/net/citizensnpcs/trait/Toggleable.java +++ b/src/main/java/net/citizensnpcs/trait/Toggleable.java @@ -1,9 +1,6 @@ package net.citizensnpcs.trait; -/** - * Represents a two-state entity which can be toggled on and off. - * - */ public interface Toggleable { + public void toggle(); -} +} \ No newline at end of file diff --git a/src/main/java/net/citizensnpcs/trait/text/Text.java b/src/main/java/net/citizensnpcs/trait/text/Text.java index cbd486bb7..5f596ad7f 100644 --- a/src/main/java/net/citizensnpcs/trait/text/Text.java +++ b/src/main/java/net/citizensnpcs/trait/text/Text.java @@ -1,7 +1,10 @@ package net.citizensnpcs.trait.text; import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Random; import org.bukkit.Bukkit; @@ -9,6 +12,7 @@ import org.bukkit.conversations.ConversationFactory; import org.bukkit.entity.Player; import net.citizensnpcs.Citizens; +import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.exception.NPCLoadException; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.trait.SaveId; @@ -28,6 +32,7 @@ public class Text extends Trait implements Runnable, Toggleable { private final Citizens plugin; private final NPC npc; private final List text = new ArrayList(); + private final Map cooldowns = new HashMap(); private boolean talkClose; public Text(NPC npc) { @@ -60,8 +65,23 @@ public class Text extends Trait implements Runnable, Toggleable { public void run() { EntityHuman search = null; EntityLiving handle = ((CitizensNPC) npc).getHandle(); - if ((search = handle.world.findNearbyPlayer(handle, 5)) != null && talkClose) - sendRandomText((Player) search.getBukkitEntity()); + if ((search = handle.world.findNearbyPlayer(handle, 5)) != null && talkClose) { + Player player = (Player) search.getBukkitEntity(); + // If the cooldown is not expired, do not send text + if (cooldowns.get(player.getName()) != null) { + if (!Calendar.getInstance().after(cooldowns.get(player.getName()))) + return; + cooldowns.remove(player.getName()); + } + sendRandomText(player); + // Add a cooldown if the text was successfully sent + Calendar wait = Calendar.getInstance(); + wait.add( + Calendar.SECOND, + (new Random().nextInt(Setting.TALK_CLOSE_MAXIMUM_COOLDOWN.asInt()) + Setting.TALK_CLOSE_MINIMUM_COOLDOWN + .asInt())); + cooldowns.put(player.getName(), wait); + } } @Override @@ -74,6 +94,10 @@ public class Text extends Trait implements Runnable, Toggleable { return builder.toString(); } + public boolean shouldTalkClose() { + return talkClose; + } + public Editor getEditor(final Player player) { final StartPrompt startPrompt = new StartPrompt(this); return new Editor() {