diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 8a5d739a4f..39cf465eeb 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -27,7 +27,7 @@ object ProjectVersions { const val launcherVersion = "2.0.4" const val rlVersion = "1.6.2-SNAPSHOT" - const val openosrsVersion = "2.1.20-SNAPSHOT" + const val openosrsVersion = "2.1.21-SNAPSHOT" const val rsversion = 187 const val cacheversion = 165 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 60003ba543..bfee49658d 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 @@ -61,19 +61,8 @@ class Raid if (room == null) { - RaidRoom.Type type = RaidRoom.Type.fromCode(layout.getRoomAt(i).getSymbol()); - room = new RaidRoom(null, type); - - if (type == RaidRoom.Type.COMBAT) - { - room.setBoss(RaidRoom.Boss.UNKNOWN); - } - - if (type == RaidRoom.Type.PUZZLE) - { - room.setPuzzle(RaidRoom.Puzzle.UNKNOWN); - } - + RoomType type = RoomType.fromCode(layout.getRoomAt(i).getSymbol()); + room = type.getUnsolvedRoom(); setRoom(room, i); } } @@ -103,7 +92,7 @@ class Raid continue; } - if (rooms[room.getPosition()].getType() == RaidRoom.Type.COMBAT) + if (rooms[room.getPosition()].getType() == RoomType.COMBAT) { combatRooms.add(rooms[room.getPosition()]); } @@ -114,7 +103,7 @@ class Raid String getRotationString() { - return Joiner.on(",").join(Arrays.stream(getCombatRooms()).map(r -> r.getBoss().getName()).toArray()); + return Joiner.on(",").join(Arrays.stream(getCombatRooms()).map(RaidRoom::getName).toArray()); } private RaidRoom[] getAllRooms() @@ -167,7 +156,7 @@ class Raid final int position = r.getPosition(); final RaidRoom room = getRoom(position); - if (room == null || !(room.getType() == RaidRoom.Type.COMBAT || room.getType() == RaidRoom.Type.PUZZLE)) + if (room == null) { continue; } @@ -175,26 +164,8 @@ class Raid switch (room.getType()) { case PUZZLE: - final RaidRoom.Puzzle puzzle = room.getPuzzle(); - sb.append(puzzle.getName()); - - if (puzzle == RaidRoom.Puzzle.UNKNOWN) - { - sb.append(" (puzzle)"); - } - - sb.append(", "); - break; case COMBAT: - final RaidRoom.Boss boss = room.getBoss(); - sb.append(boss.getName()); - - if (boss == RaidRoom.Boss.UNKNOWN) - { - sb.append(" (combat)"); - } - - sb.append(", "); + sb.append(room.getName()).append(", "); break; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidRoom.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidRoom.java index bf6407999d..a5bf0e314e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidRoom.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidRoom.java @@ -24,139 +24,37 @@ */ package net.runelite.client.plugins.raids; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.Setter; -import net.runelite.api.Tile; +import lombok.RequiredArgsConstructor; -public class RaidRoom +@RequiredArgsConstructor +@Getter +public enum RaidRoom { + START("Start", RoomType.START), + END("End", RoomType.END), + SCAVENGERS("Scavengers", RoomType.SCAVENGERS), + FARMING("Farming", RoomType.FARMING), + EMPTY("Empty", RoomType.EMPTY), + + TEKTON("Tekton", RoomType.COMBAT), + MUTTADILES("Muttadiles", RoomType.COMBAT), + GUARDIANS("Guardians", RoomType.COMBAT), + VESPULA("Vespula", RoomType.COMBAT), + SHAMANS("Shamans", RoomType.COMBAT), + VASA("Vasa", RoomType.COMBAT), + VANGUARDS("Vanguards", RoomType.COMBAT), + MYSTICS("Mystics", RoomType.COMBAT), + UNKNOWN_COMBAT("Unknown (combat)", RoomType.COMBAT), + + CRABS("Crabs", RoomType.PUZZLE), + ICE_DEMON("Ice Demon", RoomType.PUZZLE), + TIGHTROPE("Tightrope", RoomType.PUZZLE), + THIEVING("Thieving", RoomType.PUZZLE), + UNKNOWN_PUZZLE("Unknown (puzzle)", RoomType.PUZZLE); + static final int ROOM_MAX_SIZE = 32; - @Getter(AccessLevel.PACKAGE) - private final Tile base; - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private Type type; - @Getter(AccessLevel.PUBLIC) - @Setter(AccessLevel.PUBLIC) - private Boss boss; - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private Puzzle puzzle; - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private RaidRoom previousRoom; - @Getter(AccessLevel.PACKAGE) - @Setter(AccessLevel.PACKAGE) - private RaidRoom nextRoom; - RaidRoom(final Tile base, final Type type) - { - this.base = base; - this.type = type; - } - - @Override - public String toString() - { - switch (type) - { - case COMBAT: - return " " + type.getName() + " - " + boss.getName(); - - case PUZZLE: - return " " + type.getName() + " - " + puzzle.getName(); - - default: - return " " + type.getName(); - } - } - - @AllArgsConstructor - public enum Type - { - START("Start", "#"), - END("End", "¤"), - SCAVENGERS("Scavengers", "S"), - FARMING("Farming", "F"), - COMBAT("Combat", "C"), - PUZZLE("Puzzle", "P"), - EMPTY("Empty", " "); - - @Getter - private final String name; - - @Getter - private final String code; - - public static Type fromCode(char code) - { - for (Type type : Type.values()) - { - if (type.getCode().equalsIgnoreCase(String.valueOf(code))) - { - return type; - } - } - - return Type.EMPTY; - } - } - - @AllArgsConstructor - public enum Boss - { - TEKTON("Tekton"), - MUTTADILES("Muttadiles"), - GUARDIANS("Guardians"), - VESPULA("Vespula"), - SHAMANS("Shamans"), - VASA("Vasa"), - VANGUARDS("Vanguards"), - MYSTICS("Mystics"), - UNKNOWN("Unknown"); - - @Getter - private final String name; - - public static Boss fromString(String name) - { - for (Boss boss : Boss.values()) - { - if (boss.getName().equalsIgnoreCase(name)) - { - return boss; - } - } - - return null; - } - } - - @AllArgsConstructor - public enum Puzzle - { - CRABS("Crabs"), - ICE_DEMON("Ice Demon"), - TIGHTROPE("Tightrope"), - THIEVING("Thieving"), - UNKNOWN("Unknown"); - - @Getter - private final String name; - - public static Puzzle fromString(String name) - { - for (Puzzle puzzle : Puzzle.values()) - { - if (puzzle.getName().equalsIgnoreCase(name)) - { - return puzzle; - } - } - - return null; - } - } + private final String name; + private final RoomType type; } \ No newline at end of file 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 edd309e661..cdfc5e943f 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 @@ -33,7 +33,6 @@ import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; @@ -180,20 +179,18 @@ public class RaidsOverlay extends Overlay { case COMBAT: combatCount++; - roomName = room.getBoss().getName(); - switch (Objects.requireNonNull(RaidRoom.Boss.fromString(roomName))) + switch (room) { case VANGUARDS: vanguards = true; break; - case UNKNOWN: + case UNKNOWN_COMBAT: unknownCombat = true; break; } break; case PUZZLE: - roomName = room.getPuzzle().getName(); - switch (Objects.requireNonNull(RaidRoom.Puzzle.fromString(roomName))) + switch (room) { case CRABS: crabs = true; @@ -316,17 +313,17 @@ public class RaidsOverlay extends Overlay { case COMBAT: bossCount++; - if (plugin.getRoomWhitelist().contains(room.getBoss().getName().toLowerCase())) + if (plugin.getRoomWhitelist().contains(room.getName().toLowerCase())) { color = Color.GREEN; } - else if (plugin.getRoomBlacklist().contains(room.getBoss().getName().toLowerCase()) + else if (plugin.getRoomBlacklist().contains(room.getName().toLowerCase()) || plugin.isEnableRotationWhitelist() && bossCount > bossMatches) { color = Color.RED; } - String bossName = room.getBoss().getName(); + String bossName = room.getName(); String bossNameLC = bossName.toLowerCase(); if (plugin.isShowRecommendedItems() && plugin.getRecommendedItemsList().get(bossNameLC) != null) { @@ -338,7 +335,7 @@ public class RaidsOverlay extends Overlay break; case PUZZLE: - String puzzleName = room.getPuzzle().getName(); + String puzzleName = room.getName(); String puzzleNameLC = puzzleName.toLowerCase(); if (plugin.getRecommendedItemsList().get(puzzleNameLC) != null) { 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 864e1712bf..4f8f0b10db 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 @@ -25,20 +25,24 @@ */ package net.runelite.client.plugins.raids; +import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.inject.Binder; import com.google.inject.Provides; import java.awt.Color; import java.awt.image.BufferedImage; +import java.io.IOException; import java.text.DecimalFormat; import java.time.Instant; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ScheduledExecutorService; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.inject.Inject; @@ -46,18 +50,19 @@ import javax.inject.Singleton; import lombok.AccessLevel; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import static net.runelite.api.Perspective.SCENE_SIZE; +import static net.runelite.api.SpriteID.TAB_QUESTS_BROWN_RAIDING_PARTY; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.InstanceTemplates; import net.runelite.api.ItemID; import net.runelite.api.MenuOpcode; +import net.runelite.api.MessageNode; import net.runelite.api.NullObjectID; -import static net.runelite.api.Perspective.SCENE_SIZE; import net.runelite.api.Player; import net.runelite.api.Point; import net.runelite.api.SpriteID; -import static net.runelite.api.SpriteID.TAB_QUESTS_BROWN_RAIDING_PARTY; import net.runelite.api.Tile; import net.runelite.api.VarPlayer; import net.runelite.api.Varbits; @@ -70,12 +75,14 @@ import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatColorType; +import net.runelite.client.chat.ChatCommandManager; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.ChatInput; import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.game.ItemManager; @@ -98,8 +105,11 @@ import net.runelite.client.util.ImageUtil; import net.runelite.client.ws.PartyMember; import net.runelite.client.ws.PartyService; import net.runelite.client.ws.WSClient; +import net.runelite.http.api.chat.ChatClient; +import net.runelite.http.api.chat.LayoutRoom; import net.runelite.http.api.ws.messages.party.PartyChatMessage; import org.apache.commons.lang3.StringUtils; +import static net.runelite.api.util.Text.sanitize; import static org.apache.commons.lang3.StringUtils.containsIgnoreCase; @PluginDescriptor( @@ -121,6 +131,7 @@ public class RaidsPlugin extends Plugin private static final String RAID_COMPLETE_MESSAGE = "Congratulations - your raid is complete!"; private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###.##"); private static final Pattern ROTATION_REGEX = Pattern.compile("\\[(.*?)]"); + private static final String LAYOUT_COMMAND = "!layout"; private static final Pattern RAID_COMPLETE_REGEX = Pattern.compile("Congratulations - your raid is complete! Duration: ([0-9:]+)"); private static final ImmutableSet GOOD_CRABS_FIRST = ImmutableSet.of( "FSCCP.PCSCF - #WNWSWN#ESEENW", //both good crabs @@ -226,6 +237,15 @@ public class RaidsPlugin extends Plugin @Inject private WSClient ws; + @Inject + private ChatCommandManager chatCommandManager; + + @Inject + private ChatClient chatClient; + + @Inject + private ScheduledExecutorService scheduledExecutorService; + @Getter private final List roomWhitelist = new ArrayList<>(); @@ -316,6 +336,7 @@ public class RaidsPlugin extends Plugin } updateLists(); clientThread.invokeLater(() -> checkRaidPresence(true)); + chatCommandManager.registerCommandAsync(LAYOUT_COMMAND, this::lookupRaid, this::submitRaid); widgetOverlay = overlayManager.getWidgetOverlay(WidgetInfo.RAIDS_POINTS_INFOBOX); RaidsPanel panel = injector.getInstance(RaidsPanel.class); panel.init(); @@ -329,9 +350,93 @@ public class RaidsPlugin extends Plugin clientToolbar.addNavigation(navButton); } + private void lookupRaid(ChatMessage chatMessage, String s) + { + ChatMessageType type = chatMessage.getType(); + + final String player; + if (type.equals(ChatMessageType.PRIVATECHATOUT)) + { + player = client.getLocalPlayer().getName(); + } + else + { + player = sanitize(chatMessage.getName()); + } + + LayoutRoom[] layout; + try + { + layout = chatClient.getLayout(player); + } + catch (IOException ex) + { + log.debug("unable to lookup layout", ex); + return; + } + + if (layout == null || layout.length == 0) + { + return; + } + + String layoutMessage = Joiner.on(", ").join(Arrays.stream(layout) + .map(l -> RaidRoom.valueOf(l.name())) + .filter(room -> room.getType() == RoomType.COMBAT || room.getType() == RoomType.PUZZLE) + .map(RaidRoom::getName) + .toArray()); + + String response = new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append("Layout: ") + .append(ChatColorType.NORMAL) + .append(layoutMessage) + .build(); + + log.debug("Setting response {}", response); + final MessageNode messageNode = chatMessage.getMessageNode(); + messageNode.setRuneLiteFormatMessage(response); + chatMessageManager.update(messageNode); + client.refreshChat(); + } + + private boolean submitRaid(ChatInput chatInput, String s) + { + if (raid == null) + { + return false; + } + + final String playerName = client.getLocalPlayer().getName(); + RaidRoom[] rooms = raid.getRooms(); + + LayoutRoom[] layoutRooms = Arrays.stream(rooms) + .map(room -> LayoutRoom.valueOf(room.name())) + .toArray(LayoutRoom[]::new); + + scheduledExecutorService.execute(() -> + { + try + { + chatClient.submitLayout(playerName, layoutRooms); + } + catch (Exception ex) + { + log.warn("unable to submit layout", ex); + } + finally + { + chatInput.resume(); + } + }); + + return true; + } + @Override protected void shutDown() { + chatCommandManager.unregisterCommand(LAYOUT_COMMAND); overlayManager.remove(overlay); overlayManager.remove(pointsOverlay); clientToolbar.removeNavigation(navButton); @@ -1016,98 +1121,71 @@ public class RaidsPlugin extends Plugin private RaidRoom determineRoom(Tile base) { - RaidRoom room = new RaidRoom(base, RaidRoom.Type.EMPTY); int chunkData = client.getInstanceTemplateChunks()[base.getPlane()][(base.getSceneLocation().getX()) / 8][base.getSceneLocation().getY() / 8]; InstanceTemplates template = InstanceTemplates.findMatch(chunkData); if (template == null) { - return room; + return RaidRoom.EMPTY; } switch (template) { case RAIDS_LOBBY: case RAIDS_START: - room.setType(RaidRoom.Type.START); - break; + return RaidRoom.START; case RAIDS_END: - room.setType(RaidRoom.Type.END); - break; + return RaidRoom.END; case RAIDS_SCAVENGERS: case RAIDS_SCAVENGERS2: - room.setType(RaidRoom.Type.SCAVENGERS); - break; + return RaidRoom.SCAVENGERS; case RAIDS_SHAMANS: - room.setType(RaidRoom.Type.COMBAT); - room.setBoss(RaidRoom.Boss.SHAMANS); - break; + return RaidRoom.SHAMANS; case RAIDS_VASA: - room.setType(RaidRoom.Type.COMBAT); - room.setBoss(RaidRoom.Boss.VASA); - break; + return RaidRoom.VASA; case RAIDS_VANGUARDS: - room.setType(RaidRoom.Type.COMBAT); - room.setBoss(RaidRoom.Boss.VANGUARDS); - break; + return RaidRoom.VANGUARDS; case RAIDS_ICE_DEMON: - room.setType(RaidRoom.Type.PUZZLE); - room.setPuzzle(RaidRoom.Puzzle.ICE_DEMON); - break; + return RaidRoom.ICE_DEMON; case RAIDS_THIEVING: - room.setType(RaidRoom.Type.PUZZLE); - room.setPuzzle(RaidRoom.Puzzle.THIEVING); - break; + return RaidRoom.THIEVING; case RAIDS_FARMING: case RAIDS_FARMING2: - room.setType(RaidRoom.Type.FARMING); - break; + return RaidRoom.FARMING; case RAIDS_MUTTADILES: - room.setType(RaidRoom.Type.COMBAT); - room.setBoss(RaidRoom.Boss.MUTTADILES); - break; + return RaidRoom.MUTTADILES; case RAIDS_MYSTICS: - room.setType(RaidRoom.Type.COMBAT); - room.setBoss(RaidRoom.Boss.MYSTICS); - break; + return RaidRoom.MYSTICS; case RAIDS_TEKTON: - room.setType(RaidRoom.Type.COMBAT); - room.setBoss(RaidRoom.Boss.TEKTON); - break; + return RaidRoom.TEKTON; case RAIDS_TIGHTROPE: - room.setType(RaidRoom.Type.PUZZLE); - room.setPuzzle(RaidRoom.Puzzle.TIGHTROPE); - break; + return RaidRoom.TIGHTROPE; case RAIDS_GUARDIANS: - room.setType(RaidRoom.Type.COMBAT); - room.setBoss(RaidRoom.Boss.GUARDIANS); - break; + return RaidRoom.GUARDIANS; case RAIDS_CRABS: - room.setType(RaidRoom.Type.PUZZLE); - room.setPuzzle(RaidRoom.Puzzle.CRABS); - break; + return RaidRoom.CRABS; case RAIDS_VESPULA: - room.setType(RaidRoom.Type.COMBAT); - room.setBoss(RaidRoom.Boss.VESPULA); - break; + return RaidRoom.VESPULA; + + default: + return RaidRoom.EMPTY; } - return room; } private void reset() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RoomType.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RoomType.java new file mode 100644 index 0000000000..a76b3cef82 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RoomType.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2018, Kamiel + * Copyright (c) 2019, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.raids; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum RoomType +{ + START("Start", '#'), + END("End", '¤'), + SCAVENGERS("Scavengers", 'S'), + FARMING("Farming", 'F'), + EMPTY("Empty", ' '), + COMBAT("Combat", 'C'), + PUZZLE("Puzzle", 'P'); + + private final String name; + private final char code; + + RaidRoom getUnsolvedRoom() + { + switch (this) + { + case START: + return RaidRoom.START; + case END: + return RaidRoom.END; + case SCAVENGERS: + return RaidRoom.SCAVENGERS; + case FARMING: + return RaidRoom.FARMING; + case COMBAT: + return RaidRoom.UNKNOWN_COMBAT; + case PUZZLE: + return RaidRoom.UNKNOWN_PUZZLE; + case EMPTY: + default: + return RaidRoom.EMPTY; + } + } + + static RoomType fromCode(char code) + { + for (RoomType type : values()) + { + if (type.getCode() == code) + { + return type; + } + } + + return EMPTY; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/solver/RotationSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/solver/RotationSolver.java index f6310a94bb..06db930cfe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/solver/RotationSolver.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/solver/RotationSolver.java @@ -24,37 +24,45 @@ */ package net.runelite.client.plugins.raids.solver; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; import net.runelite.client.plugins.raids.RaidRoom; -import net.runelite.client.plugins.raids.RaidRoom.Boss; +import net.runelite.client.plugins.raids.RoomType; +import java.util.Arrays; +import java.util.List; +import static net.runelite.client.plugins.raids.RaidRoom.GUARDIANS; +import static net.runelite.client.plugins.raids.RaidRoom.MUTTADILES; +import static net.runelite.client.plugins.raids.RaidRoom.MYSTICS; +import static net.runelite.client.plugins.raids.RaidRoom.SHAMANS; +import static net.runelite.client.plugins.raids.RaidRoom.TEKTON; +import static net.runelite.client.plugins.raids.RaidRoom.UNKNOWN_COMBAT; +import static net.runelite.client.plugins.raids.RaidRoom.VANGUARDS; +import static net.runelite.client.plugins.raids.RaidRoom.VASA; +import static net.runelite.client.plugins.raids.RaidRoom.VESPULA; public class RotationSolver { - private static final Rotation[] ROTATIONS = + private static final List[] ROTATIONS = { - new Rotation<>(Arrays.asList(Boss.TEKTON, Boss.VASA, Boss.GUARDIANS, Boss.MYSTICS, Boss.SHAMANS, Boss.MUTTADILES, Boss.VANGUARDS, Boss.VESPULA)), - new Rotation<>(Arrays.asList(Boss.TEKTON, Boss.MUTTADILES, Boss.GUARDIANS, Boss.VESPULA, Boss.SHAMANS, Boss.VASA, Boss.VANGUARDS, Boss.MYSTICS)), - new Rotation<>(Arrays.asList(Boss.VESPULA, Boss.VANGUARDS, Boss.MUTTADILES, Boss.SHAMANS, Boss.MYSTICS, Boss.GUARDIANS, Boss.VASA, Boss.TEKTON)), - new Rotation<>(Arrays.asList(Boss.MYSTICS, Boss.VANGUARDS, Boss.VASA, Boss.SHAMANS, Boss.VESPULA, Boss.GUARDIANS, Boss.MUTTADILES, Boss.TEKTON)) + Arrays.asList(TEKTON, VASA, GUARDIANS, MYSTICS, SHAMANS, MUTTADILES, VANGUARDS, VESPULA), + Arrays.asList(TEKTON, MUTTADILES, GUARDIANS, VESPULA, SHAMANS, VASA, VANGUARDS, MYSTICS), + Arrays.asList(VESPULA, VANGUARDS, MUTTADILES, SHAMANS, MYSTICS, GUARDIANS, VASA, TEKTON), + Arrays.asList(MYSTICS, VANGUARDS, VASA, SHAMANS, VESPULA, GUARDIANS, MUTTADILES, TEKTON) }; - public static void solve(RaidRoom[] rooms) + public static boolean solve(RaidRoom[] rooms) { if (rooms == null) { - return; + return false; } - Rotation match = null; + List match = null; Integer start = null; Integer index = null; int known = 0; for (int i = 0; i < rooms.length; i++) { - if (rooms[i] == null || rooms[i].getBoss() == null || rooms[i].getBoss() == Boss.UNKNOWN) + if (rooms[i] == null || rooms[i].getType() != RoomType.COMBAT || rooms[i] == UNKNOWN_COMBAT) { continue; } @@ -69,29 +77,29 @@ public class RotationSolver if (known < 2) { - return; + return false; } if (known == rooms.length) { - return; + return true; } - for (Rotation rotation : ROTATIONS) + for (List rotation : ROTATIONS) { COMPARE: for (int i = 0; i < rotation.size(); i++) { - if (rooms[start].getBoss() == rotation.get(i)) + if (rooms[start] == rotation.get(i)) { for (int j = start + 1; j < rooms.length; j++) { - if (rooms[j].getBoss() == null || rooms[j].getBoss() == Boss.UNKNOWN) + if (rooms[j].getType() != RoomType.COMBAT || rooms[j] == UNKNOWN_COMBAT) { continue; } - if (rooms[j].getBoss() != rotation.get(i + j - start)) + if (rooms[j] != rotation.get((i + j - start) % rotation.size())) { break COMPARE; } @@ -99,7 +107,7 @@ public class RotationSolver if (match != null && match.equals(rotation)) { - return; + return false; } index = i - start; @@ -110,7 +118,7 @@ public class RotationSolver if (match == null) { - return; + return false; } for (int i = 0; i < rooms.length; i++) @@ -120,30 +128,11 @@ public class RotationSolver continue; } - if (rooms[i].getBoss() == null || rooms[i].getBoss() == Boss.UNKNOWN) + if (rooms[i].getType() != RoomType.COMBAT || rooms[i] == UNKNOWN_COMBAT) { - rooms[i].setBoss((Boss) match.get(index + i)); + rooms[i] = match.get((index + i) % match.size()); } } - - } - - private static class Rotation extends ArrayList - { - Rotation(final Collection bosses) - { - super(bosses); - } - - @Override - public E get(int index) - { - if (index < 0) - { - index = index + size(); - } - - return super.get(index % size()); - } + return true; } } \ No newline at end of file