diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/Raid.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/Raid.java index caf2207f14..a7b151f409 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/Raid.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/Raid.java @@ -24,7 +24,9 @@ */ package net.runelite.client.plugins.raids; +import com.google.common.base.Joiner; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import lombok.Getter; import net.runelite.client.plugins.raids.solver.Layout; @@ -109,6 +111,11 @@ public class Raid return combatRooms.toArray(new RaidRoom[combatRooms.size()]); } + public String getRotationString() + { + return Joiner.on(",").join(Arrays.stream(getCombatRooms()).map(r -> r.getBoss().getName()).toArray()); + } + public String toCode() { StringBuilder builder = new StringBuilder(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java index da23b389b8..4beeb15957 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsConfig.java @@ -103,6 +103,28 @@ public interface RaidsConfig extends Config @ConfigItem( position = 6, + keyName = "enableRotationWhitelist", + name = "Enable rotation whitelist", + description = "Enable the rotation whitelist" + ) + default boolean enableRotationWhitelist() + { + return false; + } + + @ConfigItem( + position = 7, + keyName = "whitelistedRotations", + name = "Whitelisted rotations", + description = "Warn when boss rotation doesn't match a whitelisted one. Add rotations like [tekton, muttadile, guardians]" + ) + default String whitelistedRotations() + { + return ""; + } + + @ConfigItem( + position = 8, keyName = "enableLayoutWhitelist", name = "Enable layout whitelist", description = "Enable the layout whitelist" @@ -113,7 +135,7 @@ public interface RaidsConfig extends Config } @ConfigItem( - position = 7, + position = 9, keyName = "whitelistedLayouts", name = "Whitelisted layouts", description = "Warn when layout doesn't match a whitelisted one. Add layouts like CFSCPPCSCF separated with comma" diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java index ae75c95c4f..802b4dd19e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsOverlay.java @@ -86,6 +86,14 @@ public class RaidsOverlay extends Overlay "Layout", Color.WHITE, layout, color )); + int bossMatches = 0; + int bossCount = 0; + + if (config.enableRotationWhitelist()) + { + bossMatches = plugin.getRotationMatches(); + } + for (Room layoutRoom : plugin.getRaid().getLayout().getRooms()) { int position = layoutRoom.getPosition(); @@ -101,11 +109,13 @@ public class RaidsOverlay extends Overlay switch (room.getType()) { case COMBAT: + bossCount++; if (plugin.getRoomWhitelist().contains(room.getBoss().getName().toLowerCase())) { color = Color.GREEN; } - else if (plugin.getRoomBlacklist().contains(room.getBoss().getName().toLowerCase())) + else if (plugin.getRoomBlacklist().contains(room.getBoss().getName().toLowerCase()) + || config.enableRotationWhitelist() && bossCount > bossMatches) { color = Color.RED; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index 7cf1c30339..e0b1a5d29e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -35,11 +35,21 @@ import java.text.DecimalFormat; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.imageio.ImageIO; import javax.inject.Inject; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.*; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.InstanceTemplates; +import net.runelite.api.ObjectID; +import net.runelite.api.Point; +import net.runelite.api.Setting; +import net.runelite.api.Tile; +import net.runelite.api.Varbits; import static net.runelite.api.Perspective.SCENE_SIZE; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.ConfigChanged; @@ -72,6 +82,7 @@ public class RaidsPlugin extends Plugin private static final int TOTAL_POINTS = 0, PERSONAL_POINTS = 1, TEXT_CHILD = 4; private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###.##"); private static final String SPLIT_REGEX = "\\s*,\\s*"; + private static final Pattern ROTATION_REGEX = Pattern.compile("\\[(.*?)\\]"); private BufferedImage raidsIcon; private RaidsTimer timer; @@ -104,6 +115,9 @@ public class RaidsPlugin extends Plugin @Getter private ArrayList roomBlacklist = new ArrayList<>(); + @Getter + private ArrayList rotationWhitelist = new ArrayList<>(); + @Getter private ArrayList layoutWhitelist = new ArrayList<>(); @@ -174,6 +188,11 @@ public class RaidsPlugin extends Plugin updateList(roomBlacklist, config.blacklistedRooms()); } + if (event.getKey().equals("whitelistedRotations")) + { + updateList(rotationWhitelist, config.whitelistedRotations()); + } + if (event.getKey().equals("whitelistedLayouts")) { updateList(layoutWhitelist, config.whitelistedLayouts()); @@ -305,13 +324,31 @@ public class RaidsPlugin extends Plugin { updateList(roomWhitelist, config.blacklistedRooms()); updateList(roomBlacklist, config.blacklistedRooms()); + updateList(rotationWhitelist, config.whitelistedRotations()); updateList(layoutWhitelist, config.whitelistedLayouts()); } private void updateList(ArrayList list, String input) { list.clear(); - list.addAll(Arrays.asList(input.toLowerCase().split(SPLIT_REGEX))); + + if (list == rotationWhitelist) + { + Matcher m = ROTATION_REGEX.matcher(input); + while (m.find()) + { + String rotation = m.group(1); + + if (!list.contains(rotation)) + { + list.add(rotation); + } + } + } + else + { + list.addAll(Arrays.asList(input.toLowerCase().split(SPLIT_REGEX))); + } } private void cacheColors() @@ -323,6 +360,43 @@ public class RaidsPlugin extends Plugin .refreshAll(); } + public int getRotationMatches() + { + String rotation = raid.getRotationString().toLowerCase(); + String[] bosses = rotation.split(SPLIT_REGEX); + + if (rotationWhitelist.contains(rotation)) + { + return bosses.length; + } + + for (String whitelisted : rotationWhitelist) + { + int matches = 0; + String[] whitelistedBosses = whitelisted.split(SPLIT_REGEX); + + for (int i = 0; i < whitelistedBosses.length; i++) + { + if (i < bosses.length && whitelistedBosses[i].equals(bosses[i])) + { + matches++; + } + else + { + matches = 0; + break; + } + } + + if (matches >= 2) + { + return matches; + } + } + + return 0; + } + private Point findLobbyBase() { Tile[][] tiles = client.getRegion().getTiles()[LOBBY_PLANE];