package org.mcmonkey.sentinel.commands; import net.citizensnpcs.api.command.Command; import net.citizensnpcs.api.command.CommandContext; import net.citizensnpcs.api.command.Requirements; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.command.CommandSender; import org.mcmonkey.sentinel.SentinelPlugin; import org.mcmonkey.sentinel.SentinelTrait; import org.mcmonkey.sentinel.targeting.SentinelTargetLabel; import org.mcmonkey.sentinel.targeting.SentinelTargetList; import java.util.Collection; /** * Commands related to targeting. */ public class SentinelTargetCommands { public static void outputEntireTargetsList(CommandSender sender, SentinelTargetList list, String prefixType) { boolean any = false; any = any | outputTargetsList(sender, prefixType + " by Type", list.targets); any = any | outputTargetsList(sender, prefixType + " by Player Name", list.byPlayerName); any = any | outputTargetsList(sender, prefixType + " by NPC Name", list.byNpcName); any = any | outputTargetsList(sender, prefixType + " by Entity Name", list.byEntityName); any = any | outputTargetsList(sender, prefixType + " by Held Item", list.byHeldItem); any = any | outputTargetsList(sender, prefixType + " by Offhand Item", list.byOffhandItem); any = any | outputTargetsList(sender, prefixType + " by Equipped Item", list.byEquippedItem); any = any | outputTargetsList(sender, prefixType + " by Inventory-carried Item", list.byInventoryItem); any = any | outputTargetsList(sender, prefixType + " by Permissions Group", list.byGroup); any = any | outputTargetsList(sender, prefixType + " by Event", list.byEvent); any = any | outputTargetsList(sender, prefixType + " by Status", list.byStatus); any = any | outputTargetsList(sender, prefixType + " by Other", list.byOther); if (!list.byAllInOne.isEmpty()) { for (int i = 0; i < list.byAllInOne.size(); i++) { sender.sendMessage(SentinelCommand.prefixGood + prefixType + " by All-In-One (" + ChatColor.AQUA + i + SentinelCommand.colorBasic + "): " + ChatColor.AQUA + list.byAllInOne.get(i).toAllInOneString()); } any = true; } if (!list.byMultiple.isEmpty()) { for (int i = 0; i < list.byMultiple.size(); i++) { sender.sendMessage(SentinelCommand.prefixGood + prefixType + " by Multiple (" + ChatColor.AQUA + i + SentinelCommand.colorBasic + "): " + ChatColor.AQUA + list.byMultiple.get(i).toMultiTargetString()); } any = true; } if (!any) { sender.sendMessage(SentinelCommand.prefixGood + prefixType + ": Nothing."); } } public static boolean outputTargetsList(CommandSender sender, String label, Collection<String> targets) { if (!targets.isEmpty()) { sender.sendMessage(SentinelCommand.prefixGood + label + ": " + ChatColor.AQUA + getNameTargetString(targets)); return true; } return false; } public static boolean testLabel(CommandSender sender, SentinelTargetLabel label) { if (!label.isValidTarget()) { sender.sendMessage(SentinelCommand.prefixBad + "Invalid target! See the readme for a list of valid targets."); return false; } if (!label.isValidRegex()) { sender.sendMessage(SentinelCommand.prefixBad + "Bad regular expression!"); return false; } if (!label.isValidPrefix()) { sender.sendMessage(SentinelCommand.prefixBad + "The target prefix '" + label.prefix + "' is unknown!"); return false; } if (!label.isValidMulti()) { sender.sendMessage(SentinelCommand.prefixBad + "The multi-target '" + label.value + "' is invalid (targets within don't exist?)!"); return false; } return true; } /** * Gets a string holding all name targets. */ public static String getNameTargetString(Collection<String> targetList) { StringBuilder targets = new StringBuilder(); for (String str : targetList) { targets.append(str).append(", "); } return targets.length() > 0 ? targets.substring(0, targets.length() - 2) : targets.toString(); } @Command(aliases = {"sentinel"}, usage = "addtarget TYPE", desc = "Adds a target.", modifiers = {"addtarget"}, permission = "sentinel.addtarget", min = 2, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void addTarget(CommandContext args, CommandSender sender, SentinelTrait sentinel) { SentinelTargetLabel targetLabel = new SentinelTargetLabel(args.getString(1)); if (!testLabel(sender, targetLabel)) { return; } if (targetLabel.addToList(sentinel.allTargets)) { sender.sendMessage(SentinelCommand.prefixGood + "Tracking new target!"); } else { sender.sendMessage(SentinelCommand.prefixBad + "Already tracking that target!"); } } @Command(aliases = {"sentinel"}, usage = "removetarget TYPE", desc = "Removes a target.", modifiers = {"removetarget"}, permission = "sentinel.removetarget", min = 2, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void removeTarget(CommandContext args, CommandSender sender, SentinelTrait sentinel) { SentinelTargetLabel targetLabel = new SentinelTargetLabel(args.getString(1)); if (!testLabel(sender, targetLabel)) { return; } if (targetLabel.removeFromList(sentinel.allTargets)) { sender.sendMessage(SentinelCommand.prefixGood + "No longer tracking that target!"); } else { sender.sendMessage(SentinelCommand.prefixBad + "Was already not tracking that target!"); } } @Command(aliases = {"sentinel"}, usage = "addignore TYPE", desc = "Ignores a target.", modifiers = {"addignore"}, permission = "sentinel.addignore", min = 2, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void addIgnore(CommandContext args, CommandSender sender, SentinelTrait sentinel) { SentinelTargetLabel targetLabel = new SentinelTargetLabel(args.getString(1)); if (!testLabel(sender, targetLabel)) { return; } if (targetLabel.addToList(sentinel.allIgnores)) { sender.sendMessage(SentinelCommand.prefixGood + "Ignoring new target!"); } else { sender.sendMessage(SentinelCommand.prefixBad + "Already ignoring that target!"); } } @Command(aliases = {"sentinel"}, usage = "removeignore TYPE", desc = "Allows targeting a target.", modifiers = {"removeignore"}, permission = "sentinel.removeignore", min = 2, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void removeIgnore(CommandContext args, CommandSender sender, SentinelTrait sentinel) { SentinelTargetLabel targetLabel = new SentinelTargetLabel(args.getString(1)); if (!testLabel(sender, targetLabel)) { return; } if (targetLabel.removeFromList(sentinel.allIgnores)) { sender.sendMessage(SentinelCommand.prefixGood + "No longer ignoring that target!"); } else { sender.sendMessage(SentinelCommand.prefixBad + "Was already not ignoring that target!"); } } @Command(aliases = {"sentinel"}, usage = "addavoid TYPE", desc = "Avoids a target.", modifiers = {"addavoid"}, permission = "sentinel.addavoid", min = 2, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void addAvoid(CommandContext args, CommandSender sender, SentinelTrait sentinel) { SentinelTargetLabel targetLabel = new SentinelTargetLabel(args.getString(1)); if (!testLabel(sender, targetLabel)) { return; } if (targetLabel.addToList(sentinel.allAvoids)) { sender.sendMessage(SentinelCommand.prefixGood + "Avoiding a new target!"); } else { sender.sendMessage(SentinelCommand.prefixBad + "Already avoiding that target!"); } } @Command(aliases = {"sentinel"}, usage = "removeavoid TYPE", desc = "Stops avoding a target.", modifiers = {"removeavoid"}, permission = "sentinel.removeavoid", min = 2, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void removeAvoid(CommandContext args, CommandSender sender, SentinelTrait sentinel) { SentinelTargetLabel targetLabel = new SentinelTargetLabel(args.getString(1)); if (!testLabel(sender, targetLabel)) { return; } if (targetLabel.removeFromList(sentinel.allAvoids)) { sender.sendMessage(SentinelCommand.prefixGood + "No longer avoiding that target!"); } else { sender.sendMessage(SentinelCommand.prefixBad + "Was already not tracking that target!"); } } @Command(aliases = {"sentinel"}, usage = "avoidrange RANGE", desc = "Sets the distance to try to keep from threats.", modifiers = {"avoidrange"}, permission = "sentinel.avoidrange", min = 1, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void avoidRange(CommandContext args, CommandSender sender, SentinelTrait sentinel) { if (args.argsLength() <= 1) { sender.sendMessage(SentinelCommand.prefixGood + "Current avoid range: " + ChatColor.AQUA + sentinel.avoidRange); return; } try { double d = Double.parseDouble(args.getString(1)); if (d >= 4 && d < 100) { sentinel.avoidRange = d; sender.sendMessage(SentinelCommand.prefixGood + "Avoidance range set!"); } else { throw new NumberFormatException("Number out of range (must be >= 4 and < 100)."); } } catch (NumberFormatException ex) { sender.sendMessage(SentinelCommand.prefixBad + "Invalid range number: " + ex.getMessage()); } } @Command(aliases = {"sentinel"}, usage = "targettime TIME", desc = "Sets the NPC's enemy target time limit in seconds.", modifiers = {"targettime"}, permission = "sentinel.targettime", min = 1, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void targetTime(CommandContext args, CommandSender sender, SentinelTrait sentinel) { if (args.argsLength() <= 1) { sender.sendMessage(SentinelCommand.prefixGood + "Current target time: " + ChatColor.AQUA + (sentinel.enemyTargetTime / 20.0)); return; } try { double d = Double.parseDouble(args.getString(1)); if (d >= 0) { sentinel.enemyTargetTime = (long) (d * 20); sender.sendMessage(SentinelCommand.prefixGood + "Target time set!"); } else { throw new NumberFormatException("Number out of range (must be >= 0)."); } } catch (NumberFormatException ex) { sender.sendMessage(SentinelCommand.prefixBad + "Invalid time number: " + ex.getMessage()); } } @Command(aliases = {"sentinel"}, usage = "runaway ['true'/'false']", desc = "Toggles whether the NPC will run away when attacked.", modifiers = {"runaway"}, permission = "sentinel.runaway", min = 1, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void runaway(CommandContext args, CommandSender sender, SentinelTrait sentinel) { boolean mode = !sentinel.runaway; if (args.argsLength() > 1 && "true".equalsIgnoreCase(args.getString(1))) { mode = true; } if (args.argsLength() > 1 && "false".equalsIgnoreCase(args.getString(1))) { mode = false; } sentinel.runaway = mode; if (sentinel.runaway) { sender.sendMessage(SentinelCommand.prefixGood + "NPC now runs away!"); } else { sender.sendMessage(SentinelCommand.prefixGood + "NPC no longer runs away!"); } } @Command(aliases = {"sentinel"}, usage = "fightback ['true'/'false']", desc = "Toggles whether the NPC will fight back.", modifiers = {"fightback"}, permission = "sentinel.fightback", min = 1, max = 2) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void fightback(CommandContext args, CommandSender sender, SentinelTrait sentinel) { boolean mode = !sentinel.fightback; if (args.argsLength() > 1 && "true".equalsIgnoreCase(args.getString(1))) { mode = true; } if (args.argsLength() > 1 && "false".equalsIgnoreCase(args.getString(1))) { mode = false; } sentinel.fightback = mode; if (sentinel.fightback) { sender.sendMessage(SentinelCommand.prefixGood + "NPC now fights back!"); } else { sender.sendMessage(SentinelCommand.prefixGood + "NPC no longer fights back!"); } } @Command(aliases = {"sentinel"}, usage = "forgive", desc = "Forgives all current targets.", modifiers = {"forgive"}, permission = "sentinel.forgive", min = 1, max = 1) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void forgive(CommandContext args, CommandSender sender, SentinelTrait sentinel) { sentinel.targetingHelper.currentTargets.clear(); sentinel.targetingHelper.currentAvoids.clear(); sentinel.chasing = null; sender.sendMessage(SentinelCommand.prefixGood + "Targets forgiven."); } @Command(aliases = {"sentinel"}, usage = "targets", desc = "Shows the targets of the current NPC.", modifiers = {"targets"}, permission = "sentinel.info", min = 1, max = 1) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void targets(CommandContext args, CommandSender sender, SentinelTrait sentinel) { sender.sendMessage(SentinelCommand.prefixGood + ChatColor.RESET + sentinel.getNPC().getFullName() + SentinelCommand.colorBasic + ": owned by " + ChatColor.RESET + SentinelPlugin.instance.getOwner(sentinel.getNPC())); outputEntireTargetsList(sender, sentinel.allTargets, "Targeted"); } @Command(aliases = {"sentinel"}, usage = "ignores", desc = "Shows the ignore targets of the current NPC.", modifiers = {"ignores"}, permission = "sentinel.info", min = 1, max = 1) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void ignores(CommandContext args, CommandSender sender, SentinelTrait sentinel) { sender.sendMessage(SentinelCommand.prefixGood + ChatColor.RESET + sentinel.getNPC().getFullName() + SentinelCommand.colorBasic + ": owned by " + ChatColor.RESET + SentinelPlugin.instance.getOwner(sentinel.getNPC())); outputEntireTargetsList(sender, sentinel.allIgnores, "Ignored"); } @Command(aliases = {"sentinel"}, usage = "avoids", desc = "Shows the avoid targets of the current NPC.", modifiers = {"avoids"}, permission = "sentinel.info", min = 1, max = 1) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void avoids(CommandContext args, CommandSender sender, SentinelTrait sentinel) { sender.sendMessage(SentinelCommand.prefixGood + ChatColor.RESET + sentinel.getNPC().getFullName() + SentinelCommand.colorBasic + ": owned by " + ChatColor.RESET + SentinelPlugin.instance.getOwner(sentinel.getNPC())); outputEntireTargetsList(sender, sentinel.allAvoids, "Avoided"); } @Command(aliases = {"sentinel"}, usage = "avoidreturnpoint", desc = "Changes the location the NPC runs to when avoid mode is activated, or removes it if the NPC is already there.", modifiers = {"avoidreturnpoint"}, permission = "sentinel.avoidreturnpoint", min = 1, max = 1) @Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class}) public void avoidReturnpoint(CommandContext args, CommandSender sender, SentinelTrait sentinel) { if (!sentinel.getNPC().isSpawned()) { sender.sendMessage(SentinelCommand.prefixBad + "NPC must be spawned for this command!"); return; } Location pos = sentinel.getLivingEntity().getLocation().getBlock().getLocation(); if (sentinel.avoidReturnPoint != null && pos.getBlockX() == sentinel.avoidReturnPoint.getBlockX() && pos.getBlockY() == sentinel.avoidReturnPoint.getBlockY() && pos.getBlockZ() == sentinel.avoidReturnPoint.getBlockZ() && pos.getWorld().getName().equals(sentinel.avoidReturnPoint.getWorld().getName())) { sentinel.avoidReturnPoint = null; sender.sendMessage(SentinelCommand.prefixGood + "Spawn point removed!"); } else { sentinel.avoidReturnPoint = pos.add(0.5, 0.0, 0.5); sender.sendMessage(SentinelCommand.prefixGood + "Spawn point updated!"); } } }