Skip to content
Permalink
Browse files

add initial multi-target support

  • Loading branch information...
mcmonkey4eva committed Mar 23, 2019
1 parent 6099c77 commit 19d70c13fc68287b51598fc3440541bb060cf289
@@ -160,6 +160,17 @@ These are all valid targets and ignores:
- Also, permission:PERM.KEY
- Also, squad:SENTINEL\_SQUAD\_NAME
- Also anything listed in the integrations section above!
- You can also add multi-targets - that is, `multi:TARGET_ONE,TARGET_TWO,...` to have multiple targets required together.
- For example: `multi:PLAYER,PLAYER,CHICKEN` will make the NPC angry at 2 players and a chicken if they are all together.
- As another example: `multi:npc:steve,player,healthabove:50` will make the player angry at the NPC named steve, any one player, and any entity with health above 50%, if all 3 are together.
- Note that currently `multi` targets do not work with `ignores`.
- You can also add all-in-one list targets - that is, `allinone:REQUIRED_ONE|REQUIRED_TWO|...` to have multiple target inputs that all must match for a single entity.
- For example, `allinone:player|healthabove:50` will target specifically a player with health above 50%.
- As another example: `allinone:chicken|entityname:cluckers|healthbelow:75` will target specifically injured chickens who are named "cluckers".
- Note that incompatible requirements don't work together (for example, `allinone:dolphin|parrot` doesn't work, because no single entity is both a dolphin *and* a parrot).
- Note that you can have `allinone` targets inside a `multi` target, but you cannot have `multi` targets inside an `allinone` target.
- Also, do not put `allinone` inside another `allinone`, and do not put a `multi` inside another `multi`.
- Note that to remove `allinone` and `multi` targets, you need to use the ID number (use `/sentinel targets` and related commands to find the ID).

### Some random supported things

@@ -1043,6 +1043,7 @@ else if (needsToUnpause && npc.hasTrait(Waypoints.class)) {
chasing = null;
}
}
targetingHelper.processAllMultiTargets();
LivingEntity target = targetingHelper.findBestTarget();
if (target != null) {
Location near = nearestPathPoint();
@@ -99,6 +99,19 @@ public static Pattern regexFor(String input) {
return result;
}

/**
* Returns the string of a regex that matches the name (if any).
*/
public static String getRegexTarget(String name, List<String> regexes) {
for (String str : regexes) {
Pattern pattern = SentinelUtilities.regexFor(".*" + str + ".*");
if (pattern.matcher(name).matches()) {
return str;
}
}
return null;
}

/**
* Returns whether a list of regex values match the a string.
*/
@@ -25,12 +25,12 @@
/**
* Output string representing a message color.
*/
public static final String ColorBasic = ChatColor.YELLOW.toString();
public static final String colorBasic = ChatColor.YELLOW.toString();

/**
* Output string representing a success prefix.
*/
public static final String prefixGood = ChatColor.DARK_GREEN + "[Sentinel] " + ColorBasic;
public static final String prefixGood = ChatColor.DARK_GREEN + "[Sentinel] " + colorBasic;

/**
* Output string representing a failure prefix.
@@ -16,9 +16,9 @@
modifiers = {"info"}, permission = "sentinel.info", min = 1, max = 1)
@Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class})
public void info(CommandContext args, CommandSender sender, SentinelTrait sentinel) {
sender.sendMessage(SentinelCommand.prefixGood + ChatColor.RESET + sentinel.getNPC().getFullName() + SentinelCommand.ColorBasic
sender.sendMessage(SentinelCommand.prefixGood + ChatColor.RESET + sentinel.getNPC().getFullName() + SentinelCommand.colorBasic
+ ": owned by " + ChatColor.RESET + SentinelPlugin.instance.getOwner(sentinel.getNPC()) +
(sentinel.getGuarding() == null ? "" : SentinelCommand.ColorBasic
(sentinel.getGuarding() == null ? "" : SentinelCommand.colorBasic
+ ", guarding: " + ChatColor.RESET + Bukkit.getOfflinePlayer(sentinel.getGuarding()).getName()));
sender.sendMessage(SentinelCommand.prefixGood + "Damage: " + ChatColor.AQUA + sentinel.damage);
sender.sendMessage(SentinelCommand.prefixGood + "Armor: " + ChatColor.AQUA + sentinel.armor);
@@ -50,7 +50,7 @@ public void info(CommandContext args, CommandSender sender, SentinelTrait sentin
modifiers = {"stats"}, permission = "sentinel.info", min = 1, max = 1)
@Requirements(livingEntity = true, ownership = true, traits = {SentinelTrait.class})
public void stats(CommandContext args, CommandSender sender, SentinelTrait sentinel) {
sender.sendMessage(SentinelCommand.prefixGood + ChatColor.RESET + sentinel.getNPC().getFullName() + SentinelCommand.ColorBasic
sender.sendMessage(SentinelCommand.prefixGood + ChatColor.RESET + sentinel.getNPC().getFullName() + SentinelCommand.colorBasic
+ ": owned by " + ChatColor.RESET + SentinelPlugin.instance.getOwner(sentinel.getNPC()));
sender.sendMessage(SentinelCommand.prefixGood + "Arrows fired: " + ChatColor.AQUA + sentinel.stats_arrowsFired);
sender.sendMessage(SentinelCommand.prefixGood + "Potions thrown: " + ChatColor.AQUA + sentinel.stats_potionsThrown);
@@ -45,13 +45,29 @@ public static void outputEntireTargetsList(CommandSender sender, SentinelTargetL
any = any | outputTargetsList(sender, prefixType + " by Held Item", list.byHeldItem);
any = any | outputTargetsList(sender, prefixType + " by Event", list.byEvent);
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.size() > 0) {
if (!targets.isEmpty()) {
sender.sendMessage(SentinelCommand.prefixGood + label + ": " + ChatColor.AQUA + getNameTargetString(targets));
return true;
}
@@ -72,6 +88,10 @@ public static boolean testLabel(CommandSender sender, SentinelTargetLabel label)
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;
}

@@ -286,7 +306,7 @@ public void forgive(CommandContext args, CommandSender sender, SentinelTrait sen
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
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");
}
@@ -296,7 +316,7 @@ public void targets(CommandContext args, CommandSender sender, SentinelTrait sen
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
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");
}
@@ -306,7 +326,7 @@ public void ignores(CommandContext args, CommandSender sender, SentinelTrait sen
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
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");
}
@@ -37,7 +37,7 @@
* All default prefixes (anything else handled by an integration object).
*/
public static HashSet<String> corePrefixes = new HashSet<>(
Arrays.asList("player", "npc", "entityname", "helditem", "group", "event")
Arrays.asList("player", "npc", "entityname", "helditem", "group", "event", "multi", "allinone")
);

/**
@@ -73,6 +73,7 @@ public boolean isValidTarget() {

/**
* Returns whether the prefix is valid - if 'false', the prefix doesn't exist.
* True for all non-prefixed targets.
*/
public boolean isValidPrefix() {
if (prefix == null) {
@@ -112,6 +113,12 @@ else if (prefix.equals("group")) {
else if (prefix.equals("event")) {
return listSet.byEvent;
}
else if (prefix.equals("multi")) {
return null;
}
else if (prefix.equals("allinone")) {
return null;
}
else {
return listSet.byOther;
}
@@ -129,10 +136,45 @@ public String addable() {
return value;
}

/**
* Returns whether the label is a valid multi-target.
* True for all non-multi targets.
*/
public boolean isValidMulti() {
if (prefix.equals("multi")) {
return getMulti(",").totalTargetsCount() > 0;
}
else if (prefix.equals("allinone")) {
return getMulti("|").totalTargetsCount() > 0;
}
return true;
}

/**
* Gets the TargetList created by this multi-target label.
*/
public SentinelTargetList getMulti(String splitter) {
SentinelTargetList newList = new SentinelTargetList();
for (String str : value.split(splitter)) {
SentinelTargetLabel label = new SentinelTargetLabel(str);
label.addToList(newList);
}
newList.recalculateCacheNoClear();
return newList;
}

/**
* Adds this target label to a list set.
*/
public boolean addToList(SentinelTargetList listSet) {
if (prefix.equals("multi")) {
listSet.byMultiple.add(getMulti(","));
return true;
}
if (prefix.equals("allinone")) {
listSet.byAllInOne.add(getMulti("|"));
return true;
}
Collection<String> list = getTargetsList(listSet);
String addable = addable();
if (list.contains(addable)) {
@@ -149,6 +191,32 @@ public boolean addToList(SentinelTargetList listSet) {
* Removes this target label from a list set.
*/
public boolean removeFromList(SentinelTargetList listSet) {
if (prefix.equals("multi")) {
try {
int integerValue = Integer.parseInt(value);
if (integerValue >= 0 && integerValue < listSet.byMultiple.size()) {
listSet.byMultiple.remove(integerValue);
return true;
}
return false;
}
catch (NumberFormatException ex) {
return false;
}
}
if (prefix.equals("allinone")) {
try {
int integerValue = Integer.parseInt(value);
if (integerValue >= 0 && integerValue < listSet.byAllInOne.size()) {
listSet.byAllInOne.remove(integerValue);
return true;
}
return false;
}
catch (NumberFormatException ex) {
return false;
}
}
Collection<String> list = getTargetsList(listSet);
String addable = addable();
if (!list.contains(addable)) {

0 comments on commit 19d70c1

Please sign in to comment.
You can’t perform that action at this time.