From c9cd33a8dd4eff05159fac664420006a74baec99 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 24 Jan 2021 00:07:02 -0500 Subject: [PATCH 01/53] spec counter: add bone dagger, crossbow, and anchor Co-authored-by: sdc6 --- .../plugins/specialcounter/SpecialCounterPlugin.java | 2 +- .../client/plugins/specialcounter/SpecialWeapon.java | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java index 799dd098ef..65f41baf67 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java @@ -60,7 +60,7 @@ import net.runelite.client.ws.WSClient; @PluginDescriptor( name = "Special Attack Counter", - description = "Track DWH, Arclight, Darklight, and BGS special attacks used on NPCs", + description = "Track special attacks used on NPCs", tags = {"combat", "npcs", "overlay"}, enabledByDefault = false ) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialWeapon.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialWeapon.java index e3cd82cfc6..a566f7680b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialWeapon.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialWeapon.java @@ -37,7 +37,13 @@ enum SpecialWeapon ARCLIGHT("Arclight", ItemID.ARCLIGHT, false, SpecialCounterConfig::arclightThreshold), DARKLIGHT("Darklight", ItemID.DARKLIGHT, false, SpecialCounterConfig::darklightThreshold), BANDOS_GODSWORD("Bandos Godsword", ItemID.BANDOS_GODSWORD, true, SpecialCounterConfig::bandosGodswordThreshold), - BANDOS_GODSWORD_OR("Bandos Godsword", ItemID.BANDOS_GODSWORD_OR, true, SpecialCounterConfig::bandosGodswordThreshold); + BANDOS_GODSWORD_OR("Bandos Godsword", ItemID.BANDOS_GODSWORD_OR, true, SpecialCounterConfig::bandosGodswordThreshold), + BARRELCHEST_ANCHOR("Barrelchest Anchor", ItemID.BARRELCHEST_ANCHOR, true, (c) -> 0), + BONE_DAGGER("Bone Dagger", ItemID.BONE_DAGGER, true, (c) -> 0), + BONE_DAGGER_P("Bone Dagger (p)", ItemID.BONE_DAGGER_P, true, (c) -> 0), + BONE_DAGGER_P8876("Bone Dagger (p+)", ItemID.BONE_DAGGER_P_8876, true, (c) -> 0), + BONE_DAGGER_P8878("Bone Dagger (p++)", ItemID.BONE_DAGGER_P_8878, true, (c) -> 0), + DORGESHUUN_CROSSBOW("Dorgeshuun Crossbow", ItemID.DORGESHUUN_CROSSBOW, true, (c) -> 0); private final String name; private final int itemID; From ce6cff4a1f64423d1f39544c258aa2c87073555d Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Mon, 7 Dec 2020 12:04:39 +0000 Subject: [PATCH 02/53] timetracking: Add option to show the soonest completion time of a tab --- .../plugins/timetracking/TimeTrackingConfig.java | 12 ++++++++++++ .../plugins/timetracking/TimeTrackingPlugin.java | 5 +++++ .../timetracking/farming/FarmingTracker.java | 16 ++++++++++++---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java index 494320517a..53d31a8314 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingConfig.java @@ -38,6 +38,7 @@ public interface TimeTrackingConfig extends Config String BOTANIST = "botanist"; String TIMERS = "timers"; String STOPWATCHES = "stopwatches"; + String PREFER_SOONEST = "preferSoonest"; @ConfigItem( keyName = "timeFormatMode", @@ -118,6 +119,17 @@ public interface TimeTrackingConfig extends Config return 10; } + @ConfigItem( + keyName = PREFER_SOONEST, + name = "Prefer soonest completion", + description = "When displaying completion times on the overview, prefer showing the soonest any patch will complete.", + position = 7 + ) + default boolean preferSoonest() + { + return false; + } + @ConfigItem( keyName = "activeTab", name = "Active Tab", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java index 55ff192afd..2b08418d10 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/TimeTrackingPlugin.java @@ -49,6 +49,7 @@ import net.runelite.client.game.ItemManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.CONFIG_GROUP; +import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.PREFER_SOONEST; import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.STOPWATCHES; import static net.runelite.client.plugins.timetracking.TimeTrackingConfig.TIMERS; import net.runelite.client.plugins.timetracking.clocks.ClockManager; @@ -172,6 +173,10 @@ public class TimeTrackingPlugin extends Plugin { clockManager.loadStopwatches(); } + else if (e.getKey().equals(PREFER_SOONEST)) + { + farmingTracker.loadCompletionTimes(); + } } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java index 298e91a5ce..dca3a4f51c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/farming/FarmingTracker.java @@ -277,7 +277,7 @@ public class FarmingTracker { for (Map.Entry> tab : farmingWorld.getTabs().entrySet()) { - long maxCompletionTime = 0; + long extremumCompletionTime = config.preferSoonest() ? Long.MAX_VALUE : 0; boolean allUnknown = true; boolean allEmpty = true; @@ -296,7 +296,15 @@ public class FarmingTracker allEmpty = false; // update max duration if this patch takes longer to grow - maxCompletionTime = Math.max(maxCompletionTime, prediction.getDoneEstimate()); + if (config.preferSoonest()) + { + extremumCompletionTime = Math.min(extremumCompletionTime, prediction.getDoneEstimate()); + } + else + { + extremumCompletionTime = Math.max(extremumCompletionTime, prediction.getDoneEstimate()); + } + } } @@ -313,7 +321,7 @@ public class FarmingTracker state = SummaryState.EMPTY; completionTime = -1L; } - else if (maxCompletionTime <= Instant.now().getEpochSecond()) + else if (extremumCompletionTime <= Instant.now().getEpochSecond()) { state = SummaryState.COMPLETED; completionTime = 0; @@ -321,7 +329,7 @@ public class FarmingTracker else { state = SummaryState.IN_PROGRESS; - completionTime = maxCompletionTime; + completionTime = extremumCompletionTime; } summaries.put(tab.getKey(), state); completionTimes.put(tab.getKey(), completionTime); From 68aacfa0bb0b452c54b0441c16691705d111a9bc Mon Sep 17 00:00:00 2001 From: Christian Gati Date: Sun, 24 Jan 2021 07:43:23 -0800 Subject: [PATCH 03/53] tears of guthix: add config for tears color Add the ability to toggle green tears off and allow for both tear colors to be changed --- .../tearsofguthix/TearsOfGuthixConfig.java | 72 +++++++++++++++++++ .../tearsofguthix/TearsOfGuthixOverlay.java | 31 ++++++-- .../tearsofguthix/TearsOfGuthixPlugin.java | 8 +++ 3 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixConfig.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixConfig.java new file mode 100644 index 0000000000..936a14db20 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixConfig.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020, cgati + * 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.tearsofguthix; + +import java.awt.Color; +import net.runelite.client.config.Alpha; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import net.runelite.client.util.ColorUtil; + +@ConfigGroup("tearsofguthix") +public interface TearsOfGuthixConfig extends Config +{ + @ConfigItem( + keyName = "showGreenTearsTimer", + name = "Enable Green Tears Timer", + description = "Configures whether to display a timer for green tears or not", + position = 1 + ) + default boolean showGreenTearsTimer() + { + return true; + } + + @Alpha + @ConfigItem( + keyName = "blueTearsColor", + name = "Blue Tears Color", + description = "Color of Blue Tears timer", + position = 2 + ) + default Color getBlueTearsColor() + { + return ColorUtil.colorWithAlpha(Color.CYAN, 100); + } + + @Alpha + @ConfigItem( + keyName = "greenTearsColor", + name = "Green Tears Color", + description = "Color of Green Tears timer", + position = 3 + ) + default Color getGreenTearsColor() + { + return ColorUtil.colorWithAlpha(Color.GREEN, 100); + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java index 08a4168ecc..dd4e0853ea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixOverlay.java @@ -36,17 +36,18 @@ import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.components.ProgressPieComponent; +import net.runelite.client.util.ColorUtil; class TearsOfGuthixOverlay extends Overlay { - private static final Color CYAN_ALPHA = new Color(Color.CYAN.getRed(), Color.CYAN.getGreen(), Color.CYAN.getBlue(), 100); - private static final Color GREEN_ALPHA = new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 100); private static final Duration MAX_TIME = Duration.ofSeconds(9); + private final TearsOfGuthixConfig config; private final TearsOfGuthixPlugin plugin; @Inject - private TearsOfGuthixOverlay(TearsOfGuthixPlugin plugin) + private TearsOfGuthixOverlay(TearsOfGuthixConfig config, TearsOfGuthixPlugin plugin) { + this.config = config; this.plugin = plugin; setPosition(OverlayPosition.DYNAMIC); setLayer(OverlayLayer.ABOVE_SCENE); @@ -55,8 +56,24 @@ class TearsOfGuthixOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { + if (plugin.getStreams().isEmpty()) + { + return null; + } + + Color blueTearsFill = config.getBlueTearsColor(); + Color greenTearsFill = config.getGreenTearsColor(); + Color blueTearsBorder = ColorUtil.colorWithAlpha(blueTearsFill, 255); + Color greenTearsBorder = ColorUtil.colorWithAlpha(greenTearsFill, 255); + plugin.getStreams().forEach((object, timer) -> { + if ((object.getId() == ObjectID.GREEN_TEARS || object.getId() == ObjectID.GREEN_TEARS_6666) + && !config.showGreenTearsTimer()) + { + return; + } + final Point position = object.getCanvasLocation(100); if (position == null) @@ -70,14 +87,14 @@ class TearsOfGuthixOverlay extends Overlay if (object.getId() == ObjectID.BLUE_TEARS || object.getId() == ObjectID.BLUE_TEARS_6665) { - progressPie.setFill(CYAN_ALPHA); - progressPie.setBorderColor(Color.CYAN); + progressPie.setFill(blueTearsFill); + progressPie.setBorderColor(blueTearsBorder); } else if (object.getId() == ObjectID.GREEN_TEARS || object.getId() == ObjectID.GREEN_TEARS_6666) { - progressPie.setFill(GREEN_ALPHA); - progressPie.setBorderColor(Color.GREEN); + progressPie.setFill(greenTearsFill); + progressPie.setBorderColor(greenTearsBorder); } progressPie.setPosition(position); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java index d7b0217235..b2a33ee80a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tearsofguthix/TearsOfGuthixPlugin.java @@ -28,6 +28,7 @@ import java.time.Instant; import java.util.HashMap; import java.util.Map; import javax.inject.Inject; +import com.google.inject.Provides; import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.DecorativeObject; @@ -35,6 +36,7 @@ import net.runelite.api.ObjectID; import net.runelite.api.events.DecorativeObjectDespawned; import net.runelite.api.events.DecorativeObjectSpawned; import net.runelite.api.events.GameStateChanged; +import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; @@ -61,6 +63,12 @@ public class TearsOfGuthixPlugin extends Plugin @Getter private final Map streams = new HashMap<>(); + @Provides + TearsOfGuthixConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(TearsOfGuthixConfig.class); + } + @Override protected void startUp() { From 8541ce6667ddfee2e37115e89854d95edea23428 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 24 Jan 2021 13:19:50 -0500 Subject: [PATCH 04/53] teamcapes: rewrite to use events --- .../plugins/teamcapes/TeamCapesOverlay.java | 2 +- .../plugins/teamcapes/TeamCapesPlugin.java | 101 +++++++++++------- 2 files changed, 64 insertions(+), 39 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesOverlay.java index 8ec93c1b18..1d54c85935 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesOverlay.java @@ -39,7 +39,7 @@ import net.runelite.client.ui.overlay.OverlayPriority; import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.ImageComponent; -public class TeamCapesOverlay extends OverlayPanel +class TeamCapesOverlay extends OverlayPanel { private final TeamCapesPlugin plugin; private final TeamCapesConfig config; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesPlugin.java index 103129d64f..c36b7ddd76 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/teamcapes/TeamCapesPlugin.java @@ -25,21 +25,24 @@ package net.runelite.client.plugins.teamcapes; import com.google.inject.Provides; -import java.time.temporal.ChronoUnit; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.stream.Collectors; import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import net.runelite.api.GameState; import net.runelite.api.Player; +import net.runelite.api.events.PlayerChanged; +import net.runelite.api.events.PlayerDespawned; +import net.runelite.client.callback.ClientThread; import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; -import net.runelite.client.task.Schedule; import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( @@ -48,19 +51,26 @@ import net.runelite.client.ui.overlay.OverlayManager; tags = {"overlay", "players"}, enabledByDefault = false ) +@Slf4j public class TeamCapesPlugin extends Plugin { @Inject private Client client; + @Inject + private ClientThread clientThread; + @Inject private OverlayManager overlayManager; @Inject private TeamCapesOverlay overlay; - // Hashmap of team capes: Key is the teamCape #, Value is the count of teamcapes in the area. - private Map teams = new HashMap<>(); + // Team number -> Number of players + @Getter(AccessLevel.PACKAGE) + private Map teams = new LinkedHashMap<>(); + // Player -> Team number + private final Map playerTeam = new HashMap<>(); @Provides TeamCapesConfig provideConfig(ConfigManager configManager) @@ -72,6 +82,8 @@ public class TeamCapesPlugin extends Plugin protected void startUp() throws Exception { overlayManager.add(overlay); + + clientThread.invokeLater(() -> client.getPlayers().forEach(this::update)); } @Override @@ -79,48 +91,61 @@ public class TeamCapesPlugin extends Plugin { overlayManager.remove(overlay); teams.clear(); + playerTeam.clear(); } - @Schedule( - period = 1800, - unit = ChronoUnit.MILLIS - ) - public void update() + @Subscribe + public void onPlayerChanged(PlayerChanged playerChanged) { - if (client.getGameState() != GameState.LOGGED_IN) + Player player = playerChanged.getPlayer(); + update(player); + } + + private void update(Player player) + { + int oldTeam = playerTeam.getOrDefault(player, 0); + if (oldTeam == player.getTeam()) { return; } - List players = client.getPlayers(); - teams.clear(); - for (Player player : players) + + log.debug("{} has changed teams: {} -> {}", player.getName(), oldTeam, player.getTeam()); + + if (oldTeam > 0) { - int team = player.getTeam(); - if (team > 0) - { - if (teams.containsKey(team)) - { - teams.put(team, teams.get(team) + 1); - } - else - { - teams.put(team, 1); - } - } + teams.computeIfPresent(oldTeam, (key, value) -> value > 1 ? value - 1 : null); + playerTeam.remove(player); } + if (player.getTeam() > 0) + { + teams.merge(player.getTeam(), 1, Integer::sum); + playerTeam.put(player, player.getTeam()); + } + + sort(); + } + + @Subscribe + public void onPlayerDespawned(PlayerDespawned playerDespawned) + { + Player player = playerDespawned.getPlayer(); + Integer team = playerTeam.remove(player); + if (team != null) + { + teams.computeIfPresent(team, (key, value) -> value > 1 ? value - 1 : null); + sort(); + } + } + + private void sort() + { // Sort teams by value in descending order and then by key in ascending order, limited to 5 entries teams = teams.entrySet().stream() - .sorted( - Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()) - .thenComparingInt(Map.Entry::getKey) - ) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); + .sorted( + Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder()) + .thenComparingInt(Map.Entry::getKey) + ) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); } - - public Map getTeams() - { - return teams; - } - } From 46434c304c8576c572f9be689babea884f2daeac Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 24 Jan 2021 11:49:55 -0500 Subject: [PATCH 05/53] image util: simplify fillImage alpha check --- .../src/main/java/net/runelite/client/util/ImageUtil.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java index 3efeabcfa4..3fb1da78d8 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageUtil.java @@ -395,8 +395,9 @@ public class ImageUtil { for (int y = 0; y < filledImage.getHeight(); y++) { - final Color pixelColor = new Color(image.getRGB(x, y), true); - if (pixelColor.getAlpha() == 0) + int pixel = image.getRGB(x, y); + int a = pixel >>> 24; + if (a == 0) { continue; } From f6953f3bef586d713a16d590f67b4597a2b7a943 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 24 Jan 2021 15:26:31 -0500 Subject: [PATCH 06/53] inventory tags: add fill tag option This changes the display mode selector to be several separate options so that users can select multiple, such as outline and fill. Co-authored-by: Jordan Co-authored-by: 1jz --- .../inventorytags/InventoryTagsConfig.java | 89 ++++++++++++++----- .../inventorytags/InventoryTagsOverlay.java | 41 ++++++++- .../inventorytags/InventoryTagsPlugin.java | 10 +++ 3 files changed, 113 insertions(+), 27 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsConfig.java index 745d64594b..b9981d49f9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsConfig.java @@ -28,20 +28,74 @@ import java.awt.Color; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.ConfigSection; +import net.runelite.client.config.Range; -@ConfigGroup("inventorytags") +@ConfigGroup(InventoryTagsConfig.GROUP) public interface InventoryTagsConfig extends Config { - enum DisplayMode - { - OUTLINE, - UNDERLINE - } - String GROUP = "inventorytags"; + @ConfigSection( + name = "Tag display mode", + description = "How tags are displayed in the inventory", + position = 0 + ) + String tagStyleSection = "tagStyleSection"; + @ConfigItem( position = 0, + keyName = "showTagOutline", + name = "Outline", + description = "Configures whether or not item tags show be outlined", + section = tagStyleSection + ) + default boolean showTagOutline() + { + return true; + } + + @ConfigItem( + position = 1, + keyName = "tagUnderline", + name = "Underline", + description = "Configures whether or not item tags should be underlined", + section = tagStyleSection + ) + default boolean showTagUnderline() + { + return false; + } + + @ConfigItem( + position = 2, + keyName = "tagFill", + name = "Fill", + description = "Configures whether or not item tags should be filled", + section = tagStyleSection + ) + default boolean showTagFill() + { + return false; + } + + @Range( + max = 255 + ) + @ConfigItem( + position = 3, + keyName = "fillOpacity", + name = "Fill opacity", + description = "Configures the opacity of the tag \"Fill\"", + section = tagStyleSection + ) + default int fillOpacity() + { + return 50; + } + + @ConfigItem( + position = 1, keyName = "groupColor1", name = "Group 1 Color", description = "Color of the Tag" @@ -52,7 +106,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 1, + position = 2, keyName = "groupColor2", name = "Group 2 Color", description = "Color of the Tag" @@ -63,7 +117,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 2, + position = 3, keyName = "groupColor3", name = "Group 3 Color", description = "Color of the Tag" @@ -74,7 +128,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 3, + position = 4, keyName = "groupColor4", name = "Group 4 Color", description = "Color of the Tag" @@ -85,7 +139,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 4, + position = 5, keyName = "groupColor5", name = "Group 5 Color", description = "Color of the Tag" @@ -96,7 +150,7 @@ public interface InventoryTagsConfig extends Config } @ConfigItem( - position = 5, + position = 6, keyName = "groupColor6", name = "Group 6 Color", description = "Color of the Tag" @@ -105,15 +159,4 @@ public interface InventoryTagsConfig extends Config { return new Color(0, 255, 255); } - - @ConfigItem( - position = 6, - keyName = "displayMode", - name = "Display mode", - description = "How tags are displayed in the inventory" - ) - default DisplayMode getDisplayMode() - { - return DisplayMode.OUTLINE; - } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java index 03857e185c..4b9e471fab 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsOverlay.java @@ -24,21 +24,26 @@ */ package net.runelite.client.plugins.inventorytags; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import java.awt.Color; import java.awt.Graphics2D; +import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; import javax.inject.Inject; import net.runelite.api.widgets.WidgetItem; import net.runelite.client.game.ItemManager; -import net.runelite.client.plugins.inventorytags.InventoryTagsConfig.DisplayMode; import net.runelite.client.ui.overlay.WidgetItemOverlay; +import net.runelite.client.util.ColorUtil; +import net.runelite.client.util.ImageUtil; public class InventoryTagsOverlay extends WidgetItemOverlay { private final ItemManager itemManager; private final InventoryTagsPlugin plugin; private final InventoryTagsConfig config; + private final Cache fillCache; @Inject private InventoryTagsOverlay(ItemManager itemManager, InventoryTagsPlugin plugin, InventoryTagsConfig config) @@ -48,6 +53,10 @@ public class InventoryTagsOverlay extends WidgetItemOverlay this.config = config; showOnEquipment(); showOnInventory(); + fillCache = CacheBuilder.newBuilder() + .concurrencyLevel(1) + .maximumSize(32) + .build(); } @Override @@ -57,16 +66,22 @@ public class InventoryTagsOverlay extends WidgetItemOverlay if (group != null) { final Color color = plugin.getGroupNameColor(group); - final DisplayMode displayMode = config.getDisplayMode(); if (color != null) { Rectangle bounds = widgetItem.getCanvasBounds(); - if (displayMode == DisplayMode.OUTLINE) + if (config.showTagOutline()) { final BufferedImage outline = itemManager.getItemOutline(itemId, widgetItem.getQuantity(), color); graphics.drawImage(outline, (int) bounds.getX(), (int) bounds.getY(), null); } - else + + if (config.showTagFill()) + { + final Image image = getFillImage(color, widgetItem.getId(), widgetItem.getQuantity()); + graphics.drawImage(image, (int) bounds.getX(), (int) bounds.getY(), null); + } + + if (config.showTagUnderline()) { int heightOffSet = (int) bounds.getY() + (int) bounds.getHeight() + 2; graphics.setColor(color); @@ -75,4 +90,22 @@ public class InventoryTagsOverlay extends WidgetItemOverlay } } } + + private Image getFillImage(Color color, int itemId, int qty) + { + long key = (((long) itemId) << 32) | qty; + Image image = fillCache.getIfPresent(key); + if (image == null) + { + final Color fillColor = ColorUtil.colorWithAlpha(color, config.fillOpacity()); + image = ImageUtil.fillImage(itemManager.getImage(itemId, qty, false), fillColor); + fillCache.put(key, image); + } + return image; + } + + void invalidateCache() + { + fillCache.invalidateAll(); + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java index 77a0548287..cdbf26a845 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventorytags/InventoryTagsPlugin.java @@ -39,6 +39,7 @@ import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.events.ConfigChanged; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; import net.runelite.client.plugins.Plugin; @@ -147,6 +148,15 @@ public class InventoryTagsPlugin extends Plugin editorMode = false; } + @Subscribe + public void onConfigChanged(ConfigChanged configChanged) + { + if (configChanged.getGroup().equals(InventoryTagsConfig.GROUP)) + { + overlay.invalidateCache(); + } + } + @Subscribe public void onWidgetMenuOptionClicked(final WidgetMenuOptionClicked event) { From d0bf05ddd9c9ca7590c1921a1f927ae641288a92 Mon Sep 17 00:00:00 2001 From: Psikoi Date: Sun, 17 May 2020 00:31:30 +0100 Subject: [PATCH 07/53] hiscore panel: update boss icons This uses a new boss icon set from Psikoi he made for wiseoldman --- .../plugins/hiscore/bosses/abyssal_sire.png | Bin 958 -> 876 bytes .../hiscore/bosses/alchemical_hydra.png | Bin 969 -> 435 bytes .../plugins/hiscore/bosses/barrows_chests.png | Bin 648 -> 272 bytes .../plugins/hiscore/bosses/bryophyta.png | Bin 697 -> 594 bytes .../client/plugins/hiscore/bosses/callisto.png | Bin 1024 -> 364 bytes .../client/plugins/hiscore/bosses/cerberus.png | Bin 745 -> 291 bytes .../hiscore/bosses/chambers_of_xeric.png | Bin 952 -> 518 bytes .../chambers_of_xeric_challenge_mode.png | Bin 985 -> 510 bytes .../plugins/hiscore/bosses/chaos_elemental.png | Bin 910 -> 471 bytes .../plugins/hiscore/bosses/chaos_fanatic.png | Bin 593 -> 515 bytes .../hiscore/bosses/commander_zilyana.png | Bin 998 -> 616 bytes .../plugins/hiscore/bosses/corporeal_beast.png | Bin 977 -> 861 bytes .../hiscore/bosses/crazy_archaeologist.png | Bin 881 -> 863 bytes .../plugins/hiscore/bosses/dagannoth_prime.png | Bin 697 -> 384 bytes .../plugins/hiscore/bosses/dagannoth_rex.png | Bin 688 -> 382 bytes .../hiscore/bosses/dagannoth_supreme.png | Bin 697 -> 352 bytes .../hiscore/bosses/deranged_archaeologist.png | Bin 1162 -> 368 bytes .../hiscore/bosses/general_graardor.png | Bin 890 -> 531 bytes .../plugins/hiscore/bosses/giant_mole.png | Bin 904 -> 422 bytes .../hiscore/bosses/grotesque_guardians.png | Bin 884 -> 332 bytes .../client/plugins/hiscore/bosses/hespori.png | Bin 766 -> 478 bytes .../plugins/hiscore/bosses/kalphite_queen.png | Bin 807 -> 422 bytes .../hiscore/bosses/king_black_dragon.png | Bin 848 -> 331 bytes .../client/plugins/hiscore/bosses/kraken.png | Bin 720 -> 351 bytes .../client/plugins/hiscore/bosses/kreearra.png | Bin 800 -> 407 bytes .../plugins/hiscore/bosses/kril_tsutsaroth.png | Bin 1075 -> 549 bytes .../client/plugins/hiscore/bosses/mimic.png | Bin 1139 -> 403 bytes .../plugins/hiscore/bosses/nightmare.png | Bin 811 -> 609 bytes .../client/plugins/hiscore/bosses/obor.png | Bin 648 -> 627 bytes .../plugins/hiscore/bosses/sarachnis.png | Bin 884 -> 488 bytes .../client/plugins/hiscore/bosses/scorpia.png | Bin 706 -> 333 bytes .../client/plugins/hiscore/bosses/skotizo.png | Bin 994 -> 473 bytes .../hiscore/bosses/the_corrupted_gauntlet.png | Bin 823 -> 546 bytes .../plugins/hiscore/bosses/the_gauntlet.png | Bin 909 -> 618 bytes .../hiscore/bosses/theatre_of_blood.png | Bin 788 -> 613 bytes .../bosses/thermonuclear_smoke_devil.png | Bin 700 -> 543 bytes .../plugins/hiscore/bosses/tzkal_zuk.png | Bin 868 -> 583 bytes .../plugins/hiscore/bosses/tztok_jad.png | Bin 764 -> 315 bytes .../plugins/hiscore/bosses/venenatis.png | Bin 882 -> 378 bytes .../client/plugins/hiscore/bosses/vetion.png | Bin 728 -> 391 bytes .../client/plugins/hiscore/bosses/vorkath.png | Bin 1041 -> 597 bytes .../plugins/hiscore/bosses/wintertodt.png | Bin 957 -> 873 bytes .../client/plugins/hiscore/bosses/zalcano.png | Bin 929 -> 485 bytes .../client/plugins/hiscore/bosses/zulrah.png | Bin 489 -> 374 bytes 44 files changed, 0 insertions(+), 0 deletions(-) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/abyssal_sire.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/abyssal_sire.png index 3e410775614442cc3208632038b0d062aa425fb9..0209db1f974818c6d8638e7ba7f39c3f860ca2b8 100644 GIT binary patch literal 876 zcmeAS@N?(olHy`uVBq!ia0vp^qChOd!3-orr?xRNFfjfI@Ck7Ra>)QpOpI|CzyZoxWQ8k(9+jEu6fT%ioow#LR5y1LrxvVq)8E-Vbn3=9%t0vxO?3bLYs zUS`I|#*VhOB0|E>wz@(BJib11YN{$`hK6<)7T&hDlLZ;vyuDqWoGmRaqd6H&w6)C) z3>P&6%*l8)7DOBXW(FB6c!RPHZe8O(NPc=PtwyaQEak7aXC5R0Jp?UmYI|8l>XX{eYBQk#3 z($Ut{?C$F6;^F4y{QezLYXN`oE%*2 z=$$=VL_T23{=JJguim|UyZ-+ALq|MIColIAWw0#2^+nQ{^D|vjdB)S# K&t;ucLK6Vl^XKCL literal 958 zcmV;v13~(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZH)Q=NJxN05hsL1 zkDO@E6$dVGMS>G2pj^94Gb0>$SbZCAPM)NmEt* zOLN%A%r`UNeDfDovQq!8v#&1@UjMvKk5#4+inJ zt5((GeQ^Nf+x0tla7d4L8G0;;W(ydOV6@2;cm41O5CQv)67m{7i|B?d7{4&SP&?06taK6FXZp1<)ffI`%jK&Ne{M^SCv* zpOti$#r^~QnI7d%#id%Su~jZptJeV~lgTy|{)UK5?F2Xp@Jh0i)XEYBN-Qni!mHPD zU6;xH&#Xq`teF45%H|elzjxa&yLP4TQaH!>Hwb**Z=?j1DO!uTUe}OZy%i_ z<&~3X>g%WB=8;q^8(3E1lV4yJ8WvPp9ah(%=H%>=mF=9IYUJe;(b(*kmTnszW8mfy zP*NJ*)E-)0YZD%kS}vQ@z96Z4LR5WgKys-=K%9+NgqFQSR?F;!j{b<+W}mnMr=TPa zBO47Hn}V|5wA`kUh%8Uv7*i)dB`cfChM7@ug>GI^t{!0y&VjZLzQvUjGV@wY7Orvz zI+VF2$S;_IVcKJnic(YU~go~+5qpNFoj+Wm4|EbfM zl#QQg7F(J7iY$$1j$~n&80*cVCA-L*<(7wez;+j*8GgKyDiY2sldWXAgqcl)g?1d3 z+}hZgyel+dPo!MBmciVa`vL`@*?bW5DV@gDV<6(V=9;5O?l$Y|{ef%MGwM0|mVZ|5 zTYq(Vl73V4q_oO7li%EjY%6U}U*Emc{gS#a_wKzLmgR^2S-5Nq_t_tM9@ literal 969 zcmV;)12+7LP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZju#n{7aZPEAB7Opz#Om)EIQ{p&rNX7F_7sBumHGY&h_HWNluY`et(jY zp|YD8tGjw_*m+7F1z9*LKse_RLO6hP%?4*0lLUU5+&Qu=BTF;lM3bZ`t#+GMyImCj zv2$+WIE4-X-kqH#3`3NZ*gW3_SWA|sBuPTI-{;}_`hG|eTfm%i?#|PjECe>sG1lVy z9-ikRl|l-EQVOLMo>By!V!PX=AM4^}75GjF0Z`xnQ+S8+Bc&wIbCNVA@&g3m@*L+J zzVA~hmuZ}CP}iD`^~Y4tR!MrA%||VCoB*_i5POh=00aV%LSP-}G$o2cl;?pE2q6f= zkW#5cHP0EX)#&S(zVG3m30QrwMwVm+WW_l*b)W}BAg14oQC2V> z)sRYIjKNwKB@h;yhir6S#qt_Do}k|kkxEdi z#0*zsg1|q1nhqedMPD*wFRv~?q}Sf2GCs-M?~M`$hLzB}5gnaN(L>NkXUB~yg6TZFqpV4@h<#Aw< rz|=_=({lp`kmQaG}Wq?nJ>;M1%flLVKZ%&-un_*(2 zJbz-2oSdkwt)`WQy1u@Gs;Y#91fQd$wzjski;KRer=hR6v0Hg}Ay6B0NswPK1H-h( zQlHiXxy_y~jv*44Q!hN^JFLLLl5jjXY^~__@AWqr)2FX}+<$U9H;3lZ=qV15eB)H^ z6e=EU-ssAtkk8tu;<$G0+r2VvDm__Oue@=Xkic_z%`e3>FQ=93K3($MWRHMB``I4G zCE_pbRbRxX7bP0l+XkKGNoSE literal 648 zcmV;30(bq1P)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;4oO5oRCwC7mBCIEQ51&1)0wfQmd?;xTtO)%v?#D>j3$|9dl{svPGE zaLlV~0TFRUL|c^Gvw(=)77+zrv}s#u-Y`3b1DgPrWs%8DFf%hnqoIVu0~Cvo{MMa6 zW;+S_@Z`Ae9MjWTJg>_B{x@ph>+HOIjptPWP*v&LA`x)_0s$eHn?*!$9GiGNhG`kp z>vg~NPOl+<21q7H5rp80AeLnk9ULS*o?^kB^ZPdcHf(kpa-pz@VFVBnhGI75@*bY& z;Z?l;TvH=pU^`I^(_m|BoAme?W630$$w?f?_U-h#4%rWQDm%$R?F%3GKC!muQmHmr zzIu&v`2+8F%RGMa%pbX>s-!+6!NJbnI#TK#~XS9jY_t7^*v9smmH(qc}puU^z4=cM|3Eo$R8 zMknxj`SuCM0RiH3i|I{~*80Pgu9H-A=7C+ubm zoSp=L(oxWS{)`TUtgbC-C!l~jc33Yh%&Og^CI1vyUOKOlNXUnK{{vUmUoY8zu}xQ4 i`uWSe-)}g;j{yKT2KIqKyi4c+0000olw7G@?kHkO=J+n5kzFCV?U4DX0|2TM~m z8EL`79G{eUmmoj0q70wZSStxJ0X9|^QDK27f9t|zpNtsym_WPCcsBuR84+<&eqT4^5MK*EUQPooDMKCkq$sCQKMP550ajLK78Yh}Qzan*E{}qK zdtmShlmz(&Gdx&euu&i&;qt74319ma9O5>2*8t@qkczK@Y*x*#Tspu0|msgH}T=%A~RkL=n3AY?yvvTR$#jBT}=X(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;KS@MERCwC7l+8{PQ5462XTDlGl+LtPK!^}SVq#4E2qbi^E+VSO=8qM3T!}=a2u$_vDWzoK3Pi*ckriNSV$5Ud=`H+Bs$13nkmwDt zU|S}SA5Jo6R~a48=(EppkXVUCL;);4xy_7MXJ;>@<(^~p!*{+GerY#fDHROV4+5A6sBBkBBvXW& zC5mfBg33PQ6Im?N09X)_#nS?c0M$Q-DAz@XhA=IY$*fN{muBwfjP_eT5kN$~bQ-)1 za6X^LPGm^BK1m~qg^+GH__0y$owk3Lb;QlD0XVirW@MOqvsWMlt7VchlZ0V|^`BLK zm%GFB{Gaw#sXG9768cST$)jn$qPAx zpoVE2vb7Z)DNkIJec%P~8sPn>H5x5IgnFw@rJ-;V-TQg{lJu>hQ}S}B;m^w30jk}? zaZDOfn?hlOgM+$u4+eScUIC2eGdPZkVHhMF2=)%N%Z+~e#{xuT8h8mXo_E;_Kmp3KOm%nelFE81y|;K|ju^mnXF_zcm7afX-l+jSAWwfg fjqd{EV*d^Rt)WNwY~q`I00000NkvXXu0mjfK}0Ng diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/callisto.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/callisto.png index 6f307a26d5d6b5b0c829093ebc76dfeab22c4b8a..691ec6acf6ecfa107b6793aa9911fafc17d1c107 100644 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9Q!3-pIZrslUQpo{6A+A9B|Ns9$5(u2_?G1Hx zwKX-pTwSfq%*>69)KyhY^!260#eF^8>?|#n6%~`BBV)qC9BpjeoSfujWJCl7<0B#> zgM%ZrHN8AslP%4io$P}Gd{UBP@^jKl3bPm(7~fs(>jj$5ToU9L%)l`1vDByaK<-vg z7sn8Z%f1s{Pdlu@(K2~~%fu7gB)8wq{`}8Ba?8!)Y4#7E8z@~aIp*Zj{k-y@wP5QB z*?j_Q6;n0OtTCC8y=|*nx2k*TT;;0WF_-tHx2?=t+;=ZOTSL+C!mOp*TLdV$JYD@<);T3K F0Ra36hnfHY literal 1024 zcmV+b1poVqP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZmN}9%}vBz_s%|+tMO)a-V>Xt?tX|47Dv;JA@ z-$HB6i#(DSe4d*?2ytBqp(i{GQ|q23kr1K+bf)EKt;KT_2qBh$KPDw#T3w~xZj)vi zQV7=8*NNkJ6kgU^-^gQ51y3Aw^MOSr%xGWtvY--jf7rN}QzZ?e8-PHjqlu?RJq; zqP52JJOJ`M$8j9uIL7llwAQ3)$}k9~Z}RuIZqa?PLs1mW%(x5(0pW0n)|&UvtzavK zYulKniQnrnSF7R8&Z3k;N=Z=^(>riYlecPBu5CYH>CHDdeR`2rtIhJ#8S3?uY~0(# zP?BL3kt7NAdYwVPkCO74Ui3M@R+RpM48^zK{lx3@lKb}>JluPTW7|j} zDDs@x|6GgH uE*v?QQ~@pmTVwGp;1ghZ3jVYh{|x}o7^k!+^{BxB0000f+ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/cerberus.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/cerberus.png index 4f7ef937cdcfc5be249f1608d2b852d935084fcd..8d0802478387885cd93eaf406d7a88cec114df56 100644 GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+o!3-o#udq!9Qh@bq4Nr=;r zk5f!Ys7#VCSco%CjMIgWL7ssjUyRRylR<-lL6VP8M_xuvQnI`x$cvBj!AhBZ6C@*q zINN0SdgX=8IT>PwIOoNl&jT9AR1)MD%rGtg|8Gwquin$eF+}3B?}XbzhZQ(nQUhnT zOfuWL{mXy*Ew2_RKR(S^7R%e{@U$f`LBWq##dA8VEa&S@D|wDxz2VZ(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;Z%IT!RCwC7l}k?)K@^3*+dVbYGtCV1fB>R^vXDd#n2;DWCahc;VsIt#2k6eY zFmWZWToL^b`afjrN;GjvBu+FKMIOTd17VH}Xl>;+qfp6B-&EJVr|O<_t4tCnIXq5y z>D9}20UAi5GoW5j5~uFY;x9gq;>7-LG&Ac1K01Sfa&&Y! zs!Ln+Tt3B@@;BC(Hz==G2{S3GYqcostfaX{OSA;AC0I_Zk!>$>{(3*3XBSvms!?67 za=#;FJn(SNMKLo?$uut23$ar4fcikWQkw>f1@&h`xr876pKPc^aisv<>I-=MsKAHW zO{S(6r~npQR|DpMZ`StYIRxMV@H}lWmQ1rKs3bNhuZhk8RySd_4hi5#HqA<9Jqj&I zS~^mul3oC;3({FJTyoS6zG9S8(CVOnSFtOVbuyV$6q;{{gE$YDd=!{z093>jV(JHV zfdNpIbFMi)NVWW*US{_(Dpla`c>D^O~0=*p2 bY(ED8eE`&hj||qd00000NkvXXu0mjfu*5>B diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chambers_of_xeric.png index a7240d11f04bd8a755107d8b9ef134d6fcf7c5d0..58c4625bf104340bfb60683cd0653c99a1f53b43 100644 GIT binary patch literal 518 zcmV+h0{Q)kP)dn*B#LLXg($Xp^DOpof@A2{I>+6=HqtVva&eYYmzrWMi+2iKs$Ii~y+uP;o>Br5^ z!pX{{udjWDhpxD}thTqez`?n~!l<*fyTZiK)z*E6hir6p)!ErpPMzhs+w$SPJ z`l_r9hNH1Ff(ljp6Mm}ciXk&XFq(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZibI`PWnDKrdb_r}_qH3y7p|G* zYG)?D?_Sn-A+S=P` z*u2@IX`B@l>n;IC0a@d6N%!Hy($m!`x@pSKiG*DG`WyLpXh@t@RRUNNu=67#_8Evs zD?qVS06zV@WW4&lol7+6x~QD5X3Z1re{(d zd841#`}-}kVWm{-azD)vr-(tc1@;IDVa^rNjj5}#LX#b+p}l+Us_k| z@cxMpWG<5t-7q9yD9Fv}Y5VBPGO_}wSmc#1nsR-+B~(6WL7?Yf{C`q*Z@#17{7)P1 a&jA1)<>Je)g5qER0000z1OU(bm__)YZ1Xzth;+b%719VbOQvjCKT+{!L0002JNklVHy~SNiad-Lu&tXfGmdPcXeQTLx%n%1Sv&6ySbp8>zKyupz zZjTr6`C)-TPzuT62<#nEDJJ3x*h`YBbVdm45=SP#V`W4?fn=yJ7QZ?-!yO6ctm=pIk!3w2Pc<9Z`MMeRNX zGr@x@(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZQIhUv7}cE(O^TG3iMK-CTnG9+k4V<@I# zBqkOX#+|TosWEQ-vvLbDQ5P<#J4p;8NF))OV$ucB(#C&nS}091I-Ni7x@cdW5^BqW zl{fh|_q^}>?s@mzbHo_KgItOSy#6N!B9al2vm#V7-RkuKn5^(A-f(gfLiC| z2Z0HI`g9}VRAUettokM%;Jz~mPTbU*HXnTXk=eEH$smJ~<@m@wvK!n`1|rfA;JOZP zyz?erG)i_)j@m>Fpi4xCfG({yT5Ghe1L}$DY}6X!dEgX4XKp*O_$Df)G7q&hv#lpf z#B%`-gj|Qi$B*#-=O6Ok7a!Bqk_seFu4y15p8($hbab_|@6{LaeVP>4k*gqMip77FB^&y#y$FJFE78M$hQ~4xm~8Nwg&ItI~c4s zco)Do6^g|&^RqXZo0_IlC?HB9mcr5+r7bK`lq^jl>_Ie2Y2gl&XU@^EIl^xXCEV0X zC7l4!)fM#Yz<$!r4SfIY4HhRx@pkUQ@;r3NMl6N#mu83Sd0f3X%@mzePuHHy17qBjZ=O<%CE!r!feKV(#}T#?GB*_?sUn{#E4R zrdmRst(+d6CQ|;J@a)X$vR|$u6TI3IibF@9;r!4g>gzTUt%>l{^%=vT!Q{26pbbgTbB^7kr>tN{@1v&gP_GHaqSgCDKo&T= z25-n1!+Ndx_!{K?yLkOojc)|Vuf#Sm4~D9QPi}M$1o&qFG^5J^m1fqC00000NkvXX Hu0mjf(kR3Y diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_elemental.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_elemental.png index cc36114993d01af961150d0a5c0c28679e4a3755..fb104c32d4b2e0234003a8fbbdc8ddb262d265f1 100644 GIT binary patch literal 471 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+g!3-q-bzC(AQqKc?LR|m<{|{sWfrV<|=InHJ zX{&3!ok12ALY&e!r%X6hlJBaQ8fad6y}x^7W}1(2o{pTu+Vms`otQIKr7KbsuCz9I z=x5}m)}_al$A{;H`=@3mRK|v6#)M=gM-_$pr{t&B2YJWE1ZM_##<|-0#{_4@g=UBQ zC40MsC5Go_Csidy7v`rmq{fyQ>)S*HrUm=NCxqpM2c%@gmnVehMhB%QMHNK`rTV!? zMFpq1+WQB4C&Y#4g!m--xS>vJ zI)^yh`kENnDDW>i2J|FTNswPK!?gVWzdeDxxt=bLAsp9z{jZ8O1qh_DGjFusAj%q@ z^XA5>CmPg?QMrVx{;8U2$&)`et$bqh|Lb0JGRYq|FKU(DJDGQC?*mYBus zgfDZraQ#=>?%VQxr%uk|$avmewfF8^VUGUiumAq6%}BekPyhXLUa8PGDq5h(@pScb JS?83{1OS#huo(aV literal 910 zcmV;919AL`P)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ<6iGxuRCwC7l-o~SRTPK6HOve{hq*9iW&{k-qEIUeLQxY*7?XO5#M_H~Y-7^s zvwuO;|G>+O@kJkf!}!odLIJBu)0n2#(0Hc>Y@rNu=FB-~&Si$PeUM`e)Xq4uJ6R7q z`K|Tswbouslu|s%6XF4%rU4?N{$Wc^`!!P{5lI8u{WMA`X(5Dh=>B18tCWf;SBLdQ>42R%r9SOI(M9pzh1ysHGm^Zshj^P0};6fa3tH!`B!K8 z{Hjj6D*?dF@Gw(@BZNZjf&5%6B^m?x=#En|&*HqF_WvS=G?EdE;Lm6H>M!)*Ysi^!)9o4nVg#o(Suqibc&SJ>8fM!xxU%{?x$YzrgR_DBbi+9aUj6K3fu|>DaBLf|W>YaL4D=0Q zS~^D~4i~@MWMO5Fp42fcSEFp-2KY=Vb*3r6d+(gbt$DbvP1QC@B{Nu-j#40g4c)LY zsv7Y_oqV$y}k?Z{Qf@Nv&nahcknz1(=srt1~tzm6bjSXnZj?2Qu96fA08r= z?xyhEi=+~Nf78YNv#>vdYrvQY%)W4nNH|L3Py*Aj=*{tnz>VB*c@ZOUR|$6({c;Gn{! z!p6X+&#dRq;P1le?8@%q%I?a~$j{8c%)-pX#KPq7fpe^&JGkd*4O9b;jyu_^z-llDzY*&jSUTDW@ggU(e`$8FE=zSI1v!N z?(=D&{8CRB#}J9jy%&y(H3bN;J@Bq@b#Rg0y_@^!5wYF(|0kAk9(MZwwEUTm;3sXK z(;pvfl5P#K5b8a;(pPb!&r-$7tO>fW&OPNm8niQLEvMMmE7E7fc3*zmxV3r3SN2~5 zD#xyc%k`>n>bSP(@=V8xg70fKmMEBpWwS2M-+VVy%kJtO`4W4*seS5~8^6>r9#`qx ve~(EbbccP5LfF%vRhuO^YvR=>)qi6AWXQk2qEB)*C@MW&{an^LB{Ts5)KZ1- literal 593 zcmV-X0(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ-*GWV{RCwC7m9cIUQ4mGXynWca!U;A_WMLskA}#`2D~SvdG@&3;48o}>@)h9^ z!XNk(@(HOZLPMQ~G$}x7Ks1CVLZ$$*z7%9FN38MMCL@iuc$#yixihmSiK`69701K^ zW>z<|T{G*NnJ)5pWPzky3G4&yFLjK5%pw|?@^DR{U4Nr3P;HiJ@rWX$#fZv!L~^H0I-+BmX{iObib9km9q#4Q0!yv1Ustu!KUuc0w0{~^jc;_Mbi2I_+>uM fc>6dj9N_l=38UqZt1Yzf00000NkvXXu0mjf6w&|8 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/commander_zilyana.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/commander_zilyana.png index e207d7e79166acad1472ebd1ca753d4155cb9555..bec91f5bc183edc8886564f7fc6642cedb2320e5 100644 GIT binary patch literal 616 zcmV-u0+;=XP)ox;X5r!G<>MDXh_DC>ac~HWh=R32M8w2dB_yS!Wmpip*kt8I`oRaAitW=4=h)YO4MLsLXcTSu3Lk%2`|-@wq&(8$=t)Xdz}0wiK-WvyYuX=H0> zug34-2oiB}c5!uebNBG@^z!!c1^R`>&(S|1Feo@AG%UnBJR*{X!PhE^g(W&BHZI;P zAu%c0nuUQSg@qYpe=19wS31agpzX|%&|n6085jZ3n;R(+>-l#80000(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZQ%lF{$}z)5bP!v+BskY*Asbxeu-T5T^_&!<${S z13_Voxr;H_WXx?aM=$0&$G|HuhP#l77j9n2=qe0pFB+k%RB>yRlByveCT-5i$;o+l zlZ+U*HgovGb93JF{C_+j@AC*LC6DqbJmS+dKnQV82qCMsPYB^}%27(WssZN!*=SAq zHX(irkgBT4kGDT3Uwgby2Hb0!hG?s#jskx$)+--tss61 z7zX(0g=gsv`q^}FKlwWea*=gR9zXr?fNBAU6(KnC;x-04LLenexeRmHZxRT!{O>N> z3=sBucqYQlUw4u(-+9*b!@v*bG<30j5Y!e178gcY{BOb66%QX{{AO$ zdxKPL8!17-BxUq+{!)S6{WC1WqoYS_(?K-0X%rw9dy+$k-ezGj zg=x*AnL3)Q1+cL#n_RkpqG~uCE)=7LstBZT&=DJC{_@0%HAn#bJ`+dPG};0_W^++= z!-j=jO%;J^|SI(k?1i1;Z$j zx|?Jo-A*77#^rM2UZb(GXNsw--4vajwD(ygrcFrYP=rEvcQ0+BFv;Wsz^}DduSMVk z*sCjT_ha>HJyF{O~z**OJU9%2*Xp9WAVNuOpimsEUfmZE#}j2!>%$E?d~P zTzM85Ob(DRsRjb@aZ416=usg>vQJ7EKctePH1w+r z#LvTyiIFir+-uFENwfQFG82PEg#|Pu5fvSJ*qO=omh)s&bdRvH_e$lv1ZrW zscYtUx;a^TyI4ufbKIf^!IYhPIQk64y?{dPIk2^O^$al(&p#m+r_hTB{2H= zOM?7@87@3f=wG(r>x4ZH2Lu8NY97{rQp|r(7sn8Z%gG4`SS5ZoHgLLj#5)9dM6^hH zwz#^4_{2C(67_6}_lj~0^NVX_J(T|Vd3Z?Bv+%&s;Oh_CJ3eM-Wxjs#>ZP=Vl;muU zPsU8GH++AdJ#$u9XYHEYoVP#T{%mxT;p_7|r?)Qeo!q>*dv^QgI4Gut+5c}iu;9Uj z3mZOkoY2slka#BWqT$BEjUPEXJx^)|SnmwJe972o^QNE0ML!e$&Y#xT(9zP<)YWe1 z4h;zly?*7|RdbU=Ejwn&z`{tB0$0?W(T&edf2i&m0!fM>B0wUu}6=`^-4) z+$>x6B<1&aDnEz7#(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ4}gsG^+m?b{@ zpz&?VqCOZCHC|%WWEqK1ChDRw8rhait8*s62puVtZm_mu2X;`}($aBhe?CZ;Mr&6w zJIQ(YCEs(-?|jcqlv3PG(YVP{Pyi8ei-`K0`U{Gnl*+4sA5j0I{u|lLjcOnw3gEfE zM>y2~7!#8|PX9E_w!#rDdpc3MI!PlfF^>b36XdTV@WZ#>T=2~<_yeNa1BJn zEFzy|cm`epc%o+?_S$M3j-8wt8fRr?m8TCLV7qx+#x7E528+O<%)?e?;lN%e&5aIT zdwYQC$q8cfVFq2pj8BZyz5js>v~=TBk%A~X_TCX3b}M~79YkXhUVnE0P1E@9xt5y4hv$qwYs_NC7iAiliJW&afhPea%KySQ(66QyPw$!LPP9cJQs z9eeI=Cm0N1x}}8RT$m@j_i_B2?*Z=2m%;l0pB_KK;O8Im)WJs?8VxXdKFHByU$SSf zlm2IWu-8@N^ZE$=k)Wlyfurvn#_hS7yHT>+R7Bcx`J!Z+r{8w#_dqMVvaAsREXv)sbmv=>WV17l<77@3+O z8jJmtsvHOA#XJY5AkFrds|K$Bd4^xge*8HAXt1VM=dIdh00000NkvXXu0mjf3J<|K diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/crazy_archaeologist.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/crazy_archaeologist.png index 53d758bf8efc796a336498d1328965e271a3fca9..9a5f9ce8ace5c6d2026571ea7a4b4b6a58a87471 100644 GIT binary patch literal 863 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47=H)>!8^|Ns97lJo)0OpG!T zyp9%f;ochFj!LqUyn=ijZZ-<3;d(i-h8a=%i6Oea&Zc_l5DKZEX+*u(p*6<;@-9r{*L^f_M%=6@?MULAs!koRRj} z(w=s55nfsu;TEYO#uJMDW>tm-+AGUTa4<0f0fV>@ru&^*Q8mY-9`j~jz zh)1}}2RTTq$nu7{$obhxsmSv9*h+~Daj>y69pMPc06IvuB*+h#95`dPzIk4k*48rH z$k=wyvThH57LH&>)9406y>ubB^-a?P#ZvYduK;Rz=jq}YB5^r6fq_XaO)Si;OrX0_ z(4}C-s+HLpS%pP~pBq>!ww9KB{ld%B+vDr=(}C$v+B30fVb{#Im3`x5Qebp+S5FrY zH!tV+*Uz88r6?b7|G(kDf(H{W7$h!`bb2T_G4P_{#=?)Bot`IsdU%vHS7vs;l$;rP z({g9!$wfUpK0jGoU5~0RO?@glHEEH9?xWDFrdvzD^7i_k)mLZep7HYopf=o+qeUUUy_w?*$4n1*Zp7Ly?@_T<+xy3yl|0pRRSI}D@u(jf3 tkn4=+4h}1`ZWg7cFfKU3B|3qD!CArjP0R(I6rj%;JYD@<);T3K0RTiJ;~fA1 literal 881 zcmV-%1CIQOP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;_en%SRCwB~mCbGwR}{y8cgADaO^6*kAx&LADiBCTRIp${rK->cYFBL+RhR7} z^bMeIK;MA8L|3!|foP>jR?`YdASwc zbM6Ns!e9bLzz1YR)__~x=bJ$BUtX^O)KZua%|S2KH9QbXDFOKUvolPU-p2D>LXjac0syo&SgWw6O%OB)qZng7+{_sH+yvGNYmIg~fKuuPa2=pje2Z4FiN9^hdb_x; zMcX{eoy2uBSb;?EwJnVMHb0E2;5xu`d7N{nkKnfwl$*n<0>);rB1j^58K{&?%oHa0 zbNM-#ou2+esuo@Q_$=%7I!Wx}I6`G=ic{~-GCO^gP8{MPoT$9VA4|&^BZQIeNxw)1 z*lcVNcM@jHC8j6GxpwJ8-amd4Z)}pk8iwN&5%sM$Ge;{dt^UU1v(27#ZqUma1~67g zwBe=iQy3fLov9LTHjh}tvHUjZgq`L(D%mB9`^)?*5&13^APhqs*FmgcMYug*C5a=% zXrd(Hr~CJKv{K_?Z53-eJ=ra#R54YHlv22k!cmGwv&GXFTh!|7eE!j8?pCY#L4f0A zY3UrTounr#04IUp4|wh0$-NzX>4P$14Cl|C=7R=W_Ub00000NkvXX Hu0mjf)JTjP diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_prime.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_prime.png index 6b5543b5e10d85211c421f8ffff2723cfc37408b..18e004e18b9f6a4137eeffa9471463f45ad60f9b 100644 GIT binary patch literal 384 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3-oh+|s`Ssonse5ZC|z{{xvokZG)%n3?Dw z>K_&p7M&Cw5)~4Y8dGkiQ){c|p)45~5f~XC8J`}Xk)M%On3brn?BVN?oSp2WDxG7h z?it{jmYY^>qf=n6o@S_OXl__yp|!e7XGMk1f&vA-vI07VsU*lRm|}q&W`{)02Ne%7JGnd1{-(RV?r_YmcPv=1m+g8&NY|AcZzT12J!;06>xq0$$hj;K#<&rC!p6c~tuR{8Lk!AfW Z-*Mk@VZR%vdWanqik_~1F6*2Ung9p_kLUmZ literal 697 zcmV;q0!ICbP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;KS@MERCwC7l}%3*Q51%sGo6-x&`!a$pb|RJA{7^6FzL=TCa!g(8~+Ua0~Y=c zqZ>CQiXREcLitEUBZ0Ppfl{18Xoq&lTo6cN>gc@Z(&#&sf*h(rPFGMiFLTE*%eB+mf}fcQ|H?4vB!AB%-I3%yGuA__=& zJRV|0F)|MyFrNRx)b)7BJx$$ zFadvny~92HK|i7X5XOK((*#I}NK`3R{@)5#0k(f`b9U}fcNMndp!$659~8L}31LKy zhOgE2unPqJ#Ox{~JKsoctZ=)y%b*cvZ7WA=GSyR)X8|VCx7c%qwcsGdOqLf*>v;Ws z`Xl{(UHQ_s(X9yX0;KPxsoGWY+Xa++q5I~>Cd(g|a4-6hS4x>(OQdNUyZK#`W(>!1 z7>*efas}#j2jF$9$>*J=hee;AhnP;IdKuh?d^s$j0o f+2%WWXnzL)mIn$vEZ??a00000NkvXXu0mjf_lz*} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_rex.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_rex.png index fc2bcbc3a0f19f0406e8b195fbad4b84c42da019..1b73c2d416676b4884d009716817ac74dabc8ca1 100644 GIT binary patch literal 382 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3-oh+|s`SsrCS$5ZC|z{{xvoP>>ZF9qN%B z=bxDr5)tH<5bc|t8d_DASXZ0s;b9dQ>6Mlcn42C^Q4n8Ml$f04Z);^3T3Q+x z7w6^bYVKrfEGjBgQ<@ywuC*PkcIS*58G1`)WVjoWi$!o3-?1cKN{S zm+La<5qszo}OsTJ9DaS!sB}TM}MSi YnZ>trtUI+cw-pqIp00i_>zopr09^E#?f?J) literal 688 zcmV;h0#E&kP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;Hc3Q5RCwC7luJ)jQ4q&}=hEBvlh#`7lPZxE)P*E2h|w5VF4Pa;%1TC?V(@stML{(d*s=YyL7P&Tmx$AdlSb!41uUvtq zrlaeUa?!@~@YKMr*oftRPxUgLB*M+Qg(>{lDKn;q)) zCT-0?Q3OJOlt$MtGc3SMfR$Hk6!yxPOe(6$L@XNNLh2l}CsWZluvFIu9Q`#%xycxE#EF_o45gdjVVm zxHvOKt={14)^`l!;PSrzxXFvvHH?ExoRLx{hNehS6t*%uB;!F^trnqE9=@f2pzCdb zrC!Mg0w|UD3HZHaw(}t1XRh2eEl4Tv_8o$h@>m6AA6@@j>{0F2!9t(f76)0h-va>f WJ@sLQ6@)KvUG$fqnB80`_48IoQUolzQ>kR2+dCFkaEFRHIBX{zoS6reR;^Q1u9H)so|>ten5OFNW0PN^YHn-DDJ>-Dpf4mUwBS}= zJ8^O^RlV}Yi;Jw?+fv=^4bQNpc!?jn3<@PrS3j3^P6(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;KS@MERCwC7l}&3CQ51%sJDF*kuO>7JO$}`ZWBjOyZi=`N3xX@5Zrti$Y5zfg zhzms!L@KqoXjDozQ7kn{^HH@4os=Y3iocEsh+;gswQgV?? z;eyw|1VRX12qDj4MF^qy^&3PYAw&o;&O4J*ieA3z0Kp4D0w5ZjWZ}_0>PCZiuh&PH zNC+W;gv+H6jZJd@;axuG%Y>)H1J^+95q#lf|Mb~oG`B`BUuJG9!eQ%hbOK-r;LiLU zwr%r1vyG-G*fj&o>N4(e(>9L~LcEkxJ{g8U2S_Am_))I1IPW6h>C$Z4w2pLkq7go> zegaq=wgz>8T6LdhvyIs@sqC7pzWK@CUWdAIFmjP~fLT3Gd}b2UN^#J>jN|xOf1AeV z_l-zR7;Ij;gs(Rh7u>B~rJNjJd}~ z&Y%tu2>J2&Jk*T_wr%4J_?V7Q5tulYDDk(`|C=BKko#W5wk)J0kDsS|jJ>Ks%;zN- z3Y^#)Lk~NTcbtP(n-5!gUTkLhw)>l4z)NPkMDluKB#D*)uH4X3rR1u|&+`ZK#{ppLYmSYzFF41Oct=X94=s_R2ug)rlCx7- z9gA2rNHJHT)9C`d>J@w-f@Y&dI2xi*sey!F)zc1M?lptXei-KhkbRK(m+x8h%3!(A f-Bt!^v_As?zd;F;#K1vc00000NkvXXu0mjfIIc2@ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/deranged_archaeologist.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/deranged_archaeologist.png index 8dfae8c2fb8f4fb5433263f5046cc1a2d262615c..daf19da7a633a377446de5cc2cf56d78be9fb3d6 100644 GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}MSxF;E0Bf&XH!!*OUpn92TL8D zFjrSE8!KO1+b9pW7%xu;6QdAkr#K&y?A;>T622D@|Hpy1A`TiyHIRca@dK24sbX40v20Zn{`%Fwy+boCS;i|8M7OJGSiQ zrOA`uxlLRzu`&Puf%9u8FfbV|@hN0*bZu8@a{hk0p`Kyt74|h(U4uD5;pXY;=d#Wz Gp$Pzw@QRrL literal 1162 zcmV;51a(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ=5J^NqRCwBqm0NFARTRg6`*zOUI~`hDrllRISVK_Y!RUh$eK5T8?2G*d@)6*Z zfS*8lGZ+bp27;niz(j@877%(FI@7sz=A5(7_F*m#1437_l9RpG`Ty76>jwK1H=@;n z!8w4X5&Jj5DWLQ^&~vW<9@bBQJaGMWeqsnP-_vSOmw}T2#p!WQy}iinOrC2$-s8dJ zCoe=YmQ8b{ILpFJ5kF_SdHZixpKJi2hx|&wZ@uqzV18;c&$~w#@e`V)@z~i4c&AiC zDnX;&r2M?bcrM53#YM8IG~jr&x zDN0jCjIWSR;TeO`3MmDhFhXfXv)$^$omNBG8^8q{#~eRe;g~ zmJ;h6T55dH;2DEb5+M{}6cRg&_8ptsy8uZ!a)D0))}B7&+2bb9w*ow^k@CM(DJ4ny zJ_+B$_dJx+Xr&PXtc`KbacFX~@BYOo!FAwDtKFf}sL`s&7_ITN0nsH9Lf{#L?|EpY z@U%iH1vs3GX|+0pd+wziECHALhnaMOg@s94Re^IcMjM=qdse}b;yCGqM`Rri5D37s zUD1TrVr~2q!TJ8d)I^>$ADkeQ@rVOUy9IF^<6JlTLM};ZI*(G_#40Iq&e3dlh-`?B z%NQeGAUFq{EKZGc_M`XN-3f`Bj>iw1IOj+ueBxd+Yb98iDd2ks-xzEhW8)Zvz&D1m zbP}Tka;S7P@HN2f^aOkD04KUvcGlv6b`YSILQ2WpRGwVg$2W#rE2O#Cp;B*g_+XBw zL7wOSu`Nz#q;BEa+NE;sJn;fLRssWloXDXF(Y%GEt)4(8BG zcEN#WtxCoO^wZgB)VX?VnXR1)VPyN`X7EH8hKb6RD%Wn`X8Hbob{h>Q@=3y|TavMJ z#Ifs*YG?-`N#CPVZ?L|x-H-eTaLPGX9c{Ee(N~eR{I#~ucej4x&dMrL6moB+Ouf|^ z)Vc#&od9cNzW@0ywZ>k5N31#Ls;?Y&Lw#|%SHfRjz4bbkdMb z#Q3(w>dGb$o@~A_ZU)7(k8QRDTzc==JfENan9WMSUOU3|_FQBw-`>2zKU>=XyUw}% z@XvA|1m^*c9X^DoHKpk+*_0uSB7!L7{-Z~IaNe{c|4*uKSe<=6@0?>)_am40L+~na c=N$hI0P8jDz1=R*ZvX%Q07*qoM6N<$g5QK9m;e9( diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/general_graardor.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/general_graardor.png index 1d8e4334fa01f36d553cfc3951aedfa63c9e50b9..f26ca05eca402a5c21078e5e88b81e5640928013 100644 GIT binary patch literal 531 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9Q!3-pIZrslUQlA5SLR^9L|NsAiBoLf9uqG@g zETuTcHOw_G#vv*_$i_-T!$u=0&L<)w$j8eqCc-u}$=5T)Y4y_L*x2ys=+MAGucSC9 zXH!!fb8`bVwV14s^()JglcUp9+-z*jGb<7jDiUJL;*zS9ylkujoj5(LIQ{%Qe52e< z4Gf%|Y>V?_Vv1uzvO?0zVzaB00%APvt*o4EZCza*?Cq@rQUWa9EGrTdT640?;$n+q zV?vyre1WnK4t|~<4uK9jmO4$DX%Rs|VF3YwUS2`zL9yZCiBVA#x{E~x1+AP-!@>d- z6l9}ALp_|Gr6eR88!Jjna;gqa$pZS8xg^Lhn1Ny1W2sN;f!s5mE{-7*mvj4H7Bx8t zv_wjU3HN&(;9k7wnNla`>s%I5|E{QODQlX&27|_t6 z#<9vPQ>!<5Nkg2*bb)iu2F{xw&O067s1mA?aeY^!i1(s^H&4B;nq-@|ExazBs5mQZ z_04y8?%lPw343#Fvct8{-qZKZx;FdShPZf^i&8x7i$A9PvMaXjZ~bcYto!MW@8R<6 zf?LaBUs%`)e=^s^eL*nGu@r~mzXIEQ`znV*OM>-E2AYku+~uxOES27igHNTkN~ RJ@TMf^>p=fS?83{1OR0($rS(q literal 890 zcmV-=1BLvFP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ<07*naRCwC#l}m3MRTRg6cb*=P9eY~Gkf>?gmQo;)5-J1>N+K*IHoO){6$@yK zR6Yd~e1l4S09Nd~Kw^W0KmsHbB&P*Ro3=>`P5es7vFjPncxEmOVpO|z>4HcsIMS7_ z&eb{p^FNP!gp`uK6ooyO{{jBP078fhLI^qLd@O`m5<=wv2|(PhO?M65hYZq@QntoD zYGd?y0NvC$`PR#9ZMAvnDVt+c9-n@`i3me#jXU^VAHWqt+-0K z8JmpKBl7dCRF(-7xN+ron(iI?{b*TkK+D3iPWfdbX1}9^*5I= zrDXp2Jm)@mhw{<_XWx6B$$~SKfqNM2Mt&Z6f1o=&TLj?MQ?IdIclqVVuXy~iC3H%{+a9Z{Yg}8a4y9?d1{Z)u0MpR06^#jXKcN}Ya@$BnaPG{z+*pqw0e7bd zDS<+dt7}c3f9~l4!0~&EEQB}>EM_tmvg993v+r?#(*k ztq!Py`MD!}^3jJRNj&g%W{AOHU^Go-=7|zP6w~YacyU5nRXBPehdF(eZ}`{8@Kf3+<@Wt2e)AZ3~43l2TMN8^tM(^;K^K@MxjAfwtG2vQU@ z1IJU*gak#RDJE_+!gT}g>X+6izvF*vozJ_Tcj803_!%7j6xA Qi2wiq07*qoM6N<$f_JQq>;M1& diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/giant_mole.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/giant_mole.png index f814bbd2d5a19b3489669e04b3c62966bd1360a6..5fb3f328e8c8971b09e187c56231478407d31c9f 100644 GIT binary patch literal 422 zcmeAS@N?(olHy`uVBq!ia0vp^f} z>1!$Ks7k9UN{WgKSsAL^nrfNqDeGw|SH!r^n>X3XLdV0&sx95e)kfdb-q6>{*wx-V z)Ym!0!@|l`&rnbO+S<;$yXObEngdk?c{w@R7)J+r%qR`pvuD%huJniiH*-Us?R}XW zJJaGqz0zU=vlBx_g@iKWLz1KX7uLiSq($zTm^~psXzSKhXIFJx0y>MiB*-tAfnnNX zsZZ;H+-;sNjv*44eJ9)&YBJz)xve+NE8t=fqbLx(pZ@>9xwM4rcTLO9vptnuv{@at zPW|)Eas73}n_r_|8<^CZ88!APEwV64GmvrI)Y>7`Wh3c-@N9$5zbcvzW?wfg z>E%2yd7?pq=F1Dheu=Z5o;w{R@;d2R@eKWjJ5!$)ZJoF9mP5jB<~iD*cg4Lcv}pPs z%vBm{>O1*wo}k6t>pNnMYu(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ<4oO5oRCwCNl|649RTPGwbMMTqcV_m}tfOFzgo#50M1%;DCQ?EH6hJ~jm5PRz z1n~#p7Z94HL!v^6#t4L>`8X-O6KyuLAqYh|(vhz2 z$NS!U&U?=hRpnlq;U3%lB@mI5BC;kTI>lcXk=h*@R5jOuWkB!7r(vin&Xk*<2TogS zs01Zu>t#Stl;JQ2gidFNo&JC{RYW9H%5$o^dJER1ibmjP0Tv&gqh1YA1=SQ3QdOcT zB1)8Yr%&s8mpD$wBO+4?L}VE_4e0HIljomW z;Oz^a=Mp$$;O}H%dE&qV)ryZ}1nZ2zW5ux!Q4)9`zEshbAR0#(WQ4}+XWBUC*ak?iEYlOe9wdw5a0=%!P=k6%exki;j!NGMMtPvD2 zMsOU1v1UZ1!YV+BuV#VCV;huBr#YK3__{s;#ffd$1Sq; z_jY!CMMUbV+MY^KD3owb5z>g=FuXbMx)uc-$1;c#jM;m9Q4Ebo7g-B`rPtpDXo<+v zs=AgNqIchTmDm;uYO~A~-0ag~jlr8KVysXKDwL~rtXrZ`C@{aj$P&+nSaf}V<%p_ zIli{tp&P~=KXwF-2PE+TLB!x8L*PORq4uuL*oSRi-C_m9e$AfcJcF zhEp$`z;O(nZl6D|Y;yGQL6Q{WBw_vXCYP>UW@EF(a2Vb8qs`dFs;bJEp9kpmLn>vD z!1vg=y2bHhi+uRW7l;@F&*!(_FY(9vRxWsMi1KWwyUTVj)tONM diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/grotesque_guardians.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/grotesque_guardians.png index 98606aed1143fa45c92611a41e0fc78bcfbcc3ec..ec6a4238d28f5255c1035517703080b753a9bc33 100644 GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9Y!3-pyxA2?>QXv68A+A9B|Ns9$5(t7Kg0ytB zJp4So0=>*_%&qLL99$g?Obu+EY}GW>WEEshEKTwgRwkq;D5)qpdpNuKxP?ZC>KW-p zCr5|JhWm#2#-_$bB}Q>4OyU3<$6ONR7tFvg?XlFS^+4_tPZ!4!iOaDQZVNRl@VGRx zx&~z#Hm&{p|9{S*D;Ev*4=7H*D^c9ieEIM#;RDWz?w=-c95CQ|&5=Au$gy7T$Kok3 zHB+ucEkBW1bxB84e}RUu(Q{RS^&9!t=H*8;FMN7OMcE+AKV6FDN)XUHx3vIVCg!0HA1g`2YX_ literal 884 zcmV-)1B?8LP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;`bk7VRCwC7l}l?|R}ja4BkSt=TGp%B@-y`VH`GqtVh7xX7q$sb7D*sog+QR~ zqR?gOCuqMxKSB!aqG`dKLKZ1~(&Ds&CJKpNyAYhvT8f1AvLs*m-aFmMMm4gfKz(31 zFz3wwe;)st5mn_hhmTVpFGV0C*F{9@_HJ82s@j$T9|C&B@-5?z0sFKGm;xFKhjes& z^r-)K+XN?p_Yd~#M;~0(@re;#Twc&fG;+9h9Dy8Fk%%b3{L(zGPb8VCLN9)YZOmO$7hrBj1 z%iQb)Uw!d4ix(FULLwq^{X_y0$pZv~7LMbvTi#`_vPXO%PB0YY-u*2`&&(oTfSqaw zQ`3{g2jWbgpFDtA5s}6JU>-b?i2ML7h``+ZTV&H&JkP_jEX*#GXf#TPzk^D-f@zvK zj>FLK5CJoQ<2WQ%6Kt$)94J$o-CzOW?9}U&OJzLu@cDfBI(&!-uIsW}+$9taVRo9- z>>9RhV|JR@woTt)Uweu6=i_w@!+^TN+aJ-AZw|5Y~NoqU8{{B9|d#ZZ7DM6hi3XB4O96in0NFR~j0Rm=# z=YMUooz68obWBzA$ErwG^Q!uwuI0CZ&+0Qzx6(L{L+q6p#nPc_mVi%yB~_J1@Ru#u z9|I~PdimPrmPPK^V%MVKXp?>pAu`mt5azXJeDZS{DlPXE;a0000< KMNUMnLSTXdIhWx8 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/hespori.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/hespori.png index dffc71404c749bd8dfbba01b1b1fbe53533e555f..0c104674dbe6df264b138a22b26354cfb29d2ceb 100644 GIT binary patch literal 478 zcmV<40U`d0P)b7f7QjBAa8 za9dSXY-CnvUQ%^uP-k35cyC~piFS&BZi07aH83zZedDyRef+!b!|;^T|#0`Nk~{yQh;<;iG5v_h-Ha+U8I$7WnNuW zO--PZY@(EIr+R!~rogkrLzd5nNwv7vXjr+m4neZH=Nub_6js(!Vk zdQnPB!m)(s2NozT$?4NthH#6&Fm>2|rm=p*y?4JV`I4LG58zP~ U(`CLnBme*a07*qoM6N<$f|_5#U;qFB literal 766 zcmV(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;gh@m}RCwC7mCZ|3Q5c7xbI!eY#u@WE8v7V5KT>DZnYs7QJuOm+$WbRea8~Di--qAtJ?A|_ zYt2?J$ri5-0fZ3xuU)%QfLPBWA;doewASLk6$l~50jk4cdb+ykXl*4N3jL{SpklzX z4Lg)l9B6B!SeT}yAHSfnVYxbpV53cr~ z;AHO}s)7~)%Oqe~2mxMciNRzVPlP#jyu0!yd!-V&LWyADHvm9NNppM~RRKwA^b`4l zQx;&9JIv>c*wvEkM399E6R%|Am0U!vLo^yDU+|fl^($9Ua6Hmu@A#Q;|JijwbF4w#%?Wbf_<0s)g) zT@8j(C?%0nAOxg7WEp<(t#XUv^zkj)h;2P`bQ*flV zv=W}&j76UT?miqL`Fsi~G-w|Ln3loJbdJ==IUWp+lYEw1eV3b=MQ4Hg0M{;^QfwPjsxBwA=B zRAM4PO(KewWN1f4V?;q^MMR*iU_D77V{<4;Stw9pDm6hIGCdqbQ6xG<7DrVlIz=7? zyE60u000AYQchC<0G8t#@~;2@0JBL%K~xyiP0-g8f-n#T(7?4Liir(lqr?^=p#1;0 znIhso?VQ<6_AVh^`S1zxJkK?*(1SDdTl6~{3<1j+jnTfH1k=zcX7jHRL<`E6D?J=_ zw%%;x9p(GOvHh3ebWYMN7ncN`U2pdX<(vjmYIGJqi=q@laG@$aYOR)1((nZoahg>c z&8jfS7~W-?O9jtnk``f#a~I1@Hci7|+Zt_DgLW5i{LTb4N`d^}$+6q{1M(pbjOx50 QyZ`_I07*qoM6N<$f}T31$^ZZW literal 807 zcmV+?1K9kDP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;tw}^dRCwC7l)F!pQ5eR5r#A{M?e~>(E0i|aBB<3SNP-xZp@SP5FPp)|!MHFx z>0jXDu5oc9fx+lPLNvx`Oca7eQ=tUPz2(+Ixs~I>M@j{uHN43gzLV$V_nz}S?X_YH&)Hx3gDA*2wZKVN{z_CV|Ya=ndax1G1cvnUobL$MU; zt)1+115(Oh!GL==+-w?kxaN#Zq^qcF*&sZrWAN*5recY_p6o!AWo-@8S%j)&@K_?u ze27vuJI+)rfnu|0&GZxun2M&@-Yg>OSJ-SRr$MzdXx>I~STP#)==C~)j$L28`8-h< z@C-mLFXmFnOL-;O6gy|UeqMKf#GXtu9A9N(B*jL0=SV+9?w|=FUILxkch}=vRJ&AC z$u&mb#4+zIFyl=SpUv>OZ~RC<#9@=H87_n%a786By+)14K_XpF%4s0HFv{wTfzil3 zz_OH5$!n6euB4PSoN})iejq??>Ut@znSH; z35pEMEX^fxxz%i0R0t6)2rxehnT(!Nn}z6Dn%g%YaG}kH$pnuchOkp0*G`E+l*X lr7IM$3u(^*^yg~+3;?#GtGg9I^{oH^002ovPDHLkV1i;GZ%hCH diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/king_black_dragon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/king_black_dragon.png index 3bc8a77466a84e7800e7751590ca3ecfd1a8be83..7efce3fe35e23d8305a2a42fe4aba621f5ead25e 100644 GIT binary patch literal 331 zcmV-R0kr;!P)Pupt7f@xUQ|BmX_Su*l=iQrkk3-wY8Os ziYh25n~{*Pq@=N>rMj=Ld2w*JtgED%n8UletDv7QEG&C-as=3s*8l(j19VbOQvd*# z;~Mg>0001*NklTD>5K*AxB@ID{Qbfn;ndC>MD55VUu(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;)=5M`RCwC7m0wE~VHC!HGvn;;;JUk33oh7JBB`ZY7e%spQ#X1MbkjxXRY5@% zMBl*A&`m@T1x3+ED8ep83WY$tQ7LE@G=|!7oImZpJ3C!CJNrjVjXZFe!^_L_ob#M_ z&XIiI=O9hyfbGBu{>2Qy55D-m|5x8HXsa8$5y*Q4Pc|MrdGxRrCjXZl{`mE4K1e=D z{`}{;Jy#*`Epv&^R6SX9qXl))0CXhcK_y%M{OMy_Nu);bfq~?ssIp;%9KjgE$KQU+ncPYbzsk{P^px8Rw|Rt z9>H}>VV1HS0|;fC6dsW_6-8;=vC0tDvTS5Ih7gf3lP%Nnyb3cj2B}0lu4_>!Xyo%l z80JElT%=9qQ0g$U93z!VY$u4v+X1Ll$}BE=2vJ6eGX1@mF^n$^4tn(W4RQDO9s2qd zY7vC4`lMjjcnUY_~1AeHE#Cp!W_yQZNk z3f1-Fg@1%gp7?KX~^{L1L4zx%yR7`N_&#znFx!d=|h@4j!^WHoEqUPkK( a|2+WP-=~(>J~#;g0000 zQG8i3oUJ*0F@cnEBVUu_&W3X`fG*q()n6z_}27@&TSCtDH2Kyzjo{K{ zsFO6)|EY;CSCrU`BwKEnOcjvb9XOkwyM{S oDR%C8xbA=LwoA;Ww-?oaWl#=ay=BfMDGmxFPgg&ebxsLQ0QOgVfB*mh literal 720 zcmV;>0x$iEP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;R!KxbRCwC#mCZ|3VHC!H=iWPW?|i7E>3m4Zq()fejA5V!Y74R2REQ8kwQLcA z&_3o*a8;WKUA4?bWXl%SMpBa~un$ZsXd!B;%!f0l&7EPK%5h^WUw9Vx@ZR&B^PG=Y zRF%Cv277$=3HAy81A&NyL?kXEp$hweh^UM4e>zar9RX+=7F}Da!mj`Pf42mtAw_4Q zqOH5rTa~~lOF31R@?>SE2O3HWtpEfA4!y_i>P2v)Ojf4s;yIuVp`hNn<|v>ZkEQXJ zunwN`YNEr^SfsxE?i?@Qu70RLR|m<{|{tBKxchjQ&m-N zT3S>{NMB3Kq>he;T+bKR4xL$6dT4I`wC=8%{e4f)Zh3ZTPiA7`jNYD_l9I!T(R<<} zHcm(@%*v`P$j{HnxUs$OXj06K>ae=9vI%W%K|Veafr04>@m-A#4HXs6_V%SYIX%ry z0bZVpa&noGHu>@Pq5l4%9{OovRx$pjNg)>5$;qwN)$O%4@sW{Vc0RlVbR2U@kY6wZ z!?edzpVkApOFUg1LnJPTUWgQGG7w<7pfWeX!KHOYgZ82o513y3J)b7hdSU+hWof(G z1f2FKGAy2A@{{xVEuJKSJ5mjjESc8M@do~)++$C%HLn&bM&qc}+i6Z*pugj*} ztv8FVey;W-{)nAl>m8ZCSk50eHJ{$GkH4kawnyVrc2Rfqq7IY0@~No-0-0K?N7Jg9aU&q75Ae4(d1> literal 800 zcmV+*1K<3KP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;rb$FWRCwC7l)Fzd=6v6L=R0SV zi10s`=0C5p36xS@N+~Hu$@}G$NGUZ3#Q)qE5w&FnN~sYbuC=0T-#)Gk4ia+R;+bq& zK@sHg#X;(8>PTlZym>p#qorHWSa^N>7wcEe<+#OrSYy^(N`fzzj{ibk=D<+ZF_z)+ z$&v=H>%rBbA+qU3DzrvS9;ZT6DC7vcLB4(ePHK6XaKNJ~5+R+*pp@zpk*Sh%P;ANl zd-u|wXrrknMTG{((O9ebx!QmpQPY<)YU|3X*;^64g`(X4z3#lRY_wkR!oVP z_#3aTTeBZ4jT;K#I1VC0zTlC~XUHett0sr4WL0000J%Pd3#T+I#H8EPt$Q$#tEMYw|m*`s`IU2XKI84I;GWcfN7&vj7u6XclGQ@Ybv zKQ6$2pOa*BZAOF;XRQujh=;{$H=XT1`ZFd~9Skr$5@?tv%DKiybgrq;R(nxrK86jR zdZh(%TfFqvdFZ5RN$&GETwpFV!A3PrnX^=1ZkemrWLwo5W4TUgzFKKMUp~$%Nxm2% zPB{jKMb26??bRcdMcw(>gM>H>CHXuhIfI2czuFhM0)5V0666=mz%cEx)Ti}8?p040 z#}J9jxf7y;n*u~yEuV9{Iyvu3TI#l_Wa*VRNlR0rZl3-0|NnG8rpw*g=ijvFUz@iz zE&G-br=nw*i_lDiuo9yw%BhvgsUl~3)<(TFJlf;=N%cw6nff%51YYS=euq?EOV5tJ zZM`mdZ4I;k!1uK+_t)8JMXSp41Y~6A&zbl1++l88v!a{tSnm4$UR5sp z%Y6I3;`UEp-^<@Qo{-S`&!9@mR(pPe30wZBPruA++xeR<9)ITExA*3o=jD70k1p!g lidGA2@!7TH|A}qeV(Oi{gtmDXOBjG++SAp~Wt~$(696}f!Mgwe literal 1075 zcmV-31kC%1P)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ5Ilv??Hx5K9e-<0Q7@IL>-^y~BaHauO#w z!IR!$-@Nzz&YPY2KB1K2zch{i*)9TVhaY5(xmT1@H2QwYbuaD#oZ2IQ{6K=&dM))* zGI&rIw*l22(A2x>s7gn)dhYE;f~NmqDeo~HHPCfg4}H=k?Qwv2j#>P=RA#N>Z;RJW zZ${9n3)+JQo>!}fKHl1KZ0oxS&=Lt!sKR2ohOPnrZYz86adDwAd9M zib%q`#t(nnO*hd<5Cbp_$%ThQ%;jC?Rz1>jo#ECltcb-W|2{WzWv0v?B7TkGs>i*& zjakz%#J{z!TSEvDQ%V&ZAKC~|061hw>`jGU)mW~0_`)ZZh!dz*Nm&7cMu?8K7K}uk zn>mN&b)QAM%2BB!<%3I65JHU93C4k209H82bLXByRMzS5iE%ucV7BcTF{i?-EgoNX zpCr>gNMvn|Zl^;3;ciZ++Ijm_nuO!=<}2rkSiw5UEg{6X*t!wX<3j_en!`tJ6|86n zLDR&Pk`348r;^8*$dOH?sm%OBP1Cs(8KA?dGH4leh7IP58+<=KOD5Ti>kIyzxeu_W z0a1V#pB>}F_uitfHHNJu0>O9F84{+!L_A11){D9D8{I7yeO*U+IwUw8)cEG^3<`~8 zOPD7*;M@xnJUKd2?;uppt`GAQM;Jkyt8wY&icUVi=rpI^QPaN&VeWOGFd zPK|=?GPhRc?C20bW;byR$xzDTcr1jcE4o?(^tOgM)EOorb&i}lLDk&Y^L4-{t@S002ovPDHLkV1h#=@k;;z diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/mimic.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/mimic.png index 3d2c0a4606d854ea10cc4e207f6b5e0828cfa6b3..0666325dfac408c4daa22fbdc5becddcc6a953d3 100644 GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3-oh+|s`Ssg?kr5ZC|z{{xv25F8xoWzOMm z%@Jb95$VVg>&B7f!I9>}QC3!;7s#ulzz`jsobAtBUENw++g?;uT@=b&7Qx%zF}b^Y zT2(Z!u{uLzV|R0NZ(S^JQzCC`GVg-fIh)s3b~$IXw)Ur`<%e2&$2o-9Xqfh73QU`} zm_b&SK~0Up#MH`7RTbz0=8_=4UCs)bWFHg4>!R&RM=<`ZbyFryGP`Xj7_sEl#PZTGg-iD0{`VW}@2|gnYp2AfKd*cEY?B4H<;C_MwZ3pG r)_(bKnT*X+>06l3aOHjDzg^AfzDzt@W#_6%pm6nc^>bP0l+XkKo4=T_ literal 1139 zcmV-(1dRKMP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ<`AI}URCwC7m0M^WRUF2DXJ&SGb~DYUZ8lb#Cbh8%u_>liH1w(n7TO0}Y6Typ zBKROu5c=YizNpk2h_9lQ;*0c2)Q7fUE!GOHSbG<2Lqlx3Z8n$Po!z;eGslO`E^$q; zcscNgIm5^Q@}2KHM`*42KbO(^LkKY|gwQRq`yW@(S~mlj1@t2EQ46+X0nBUjF@{Oo&&h9OX=E&cnK_Z;|0f=Kf!*0Cx;zWqL5M|l_qOj zgc01o+~CzcS*FW%a5|r->Uqcn{7{o~9l&2$MRT0enX@nrjf`WYlEjH1jABd^lmf2? zT0<0rk_xFL0M$SfE9huzva!2Wra6G&K7;DqdCFKKC0M3~A406akLt<8C`QVdYNbRF zfL9HPr9sznr;+#Yf}UnyxaFj!EU)$!4=eQH0|-969nyvw$)8@e9CYu`ZF0 zzO}5}a34!5RfZqB!_ba{M3G6`s@>$wE8PC>5<^>Tip5ESu_+$gI6{B_AjMlhbK>|{ zi^>#$eDBkQVZheSz0@{D6biGY0n+&_-+cZn1KmBW-`h?lw2+?9 z`3u*W@sg&an`bcpn%Mu`6RcUc3&SwTxkXMNy@+FHP*M`97(WWw^Wr-0PI?&bBPc1E zxcxhBo6Dg?Z#Jn}bONh#hC*QjsgzBUbP`EP%BUyze2=nUrBGhObhXIME2l|h6@TIc zvAgweom{UTfNiIl8av6I-#jd%7pWCN6d+B(re}6BK0b<+3F(;{hy9wlX2IJSdj*`!i7ZP_`ag~`29RGtwyT9fDm(}1PRzGb;IIQ))*3KUkxB8jKa zbOBHcK+1%R*TX-lr+G`as_5UY`3h>KsPrG?|4WWP1_04*{!dOKgCPI_002ovPDHLk FV1oP05$FH_ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nightmare.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nightmare.png index 22907bb92fa8a2b1cfe2892e74ef1e40dfdaff73..f8edd9b211ec893a8f0fab554cf2f821b7d7e0c9 100644 GIT binary patch literal 609 zcmV-n0-pVeP)FY^EY8+P06IG!Ir=lPy{?juQr5Q0nT6(TMe9V8egG#VWu8X_tnA|@gx zEFvm2CMqy0E;TAOKrAvjE-o@KH9RsoKs7u=IX^}^LP|YFO+ZLdLP}IaE;U0#NJULn zMo?NvNKQ#oTuMq&Ofo!7RbEY3Voo(ZP*7G-T4Yf+KvFkAQa4FbTxV2XYE@NRRyspg zVQg1dT~}joSUg5qSz%gQVO%{)U0r2eYIa^;Wnf@uVq$7$W^QR|aA|3BYe-&fZFO#L zcW_K&aBz8Xae8ucdv#D}c6NVwcz}3#fqHs_dwYd@e1&{`hJAg9e}9RAfs2EKjf8}b zg@uoXhLDF_cZi6SiHenri=k6?a}kD8E>o05{Al$4*9m7$iGqnn$kot>$m zpsb>zucV}}rKPc_r?RT5wyPCetgN@KuDP$Ty0Njlwzj{^7;DuUar-rl4-8OF00007 zbW%=J000gwrNiOq*^O5K00C=BL_t(2Q&rOYTftBm2XIV0 zN+Oa_DMj~-f4`lx)id88&*!}F`<%VgXf-H=4#?3FS~(i6`dDQc(0Pz!X)&M0q5!(z zk3>R2wo($a+v@-*fbR40IL9$`tLKa(kYIPIV|0a z699-m7!*34&e8r}%x;Cp*Yb1>52ev)#C-oyb~|jHt>F?3_ho6gm*yy`qT1fYB^d6i z49m?^E{D|u;Z0>3jmOaH!3g_GQdZ0A9Ble?G7tc?i!jb}ZqlC3EW)~9ltFr5d*|sb z#kff7AeVquzcK@W#ua$^j4x2L=f%9qWJ=)gh@b|{&mS!5a8$&cK|h@_Ai=Gi&f)u) z$K@^;@_L(X$%F(|n57H_#^Wi~ZBk~Wb^s_4eM~03ftJr_G#ce?;Z}mMAqe3>G#ri! pE6Nt7cZ}^-z1ne^nw-Et!!J0iIfM2CWiJ2#002ovPDHLkV1kj)P|*MY diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/obor.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/obor.png index 8c9ea13036c8b75907c2220921238496f39655c6..1ec992e6cd1578bf69fca0121b3917747106a629 100644 GIT binary patch literal 627 zcmeAS@N?(olHy`uVBq!ia0vp^!ayvzgjGYq+qY?D)b$EhUL-n>&v#DA+$c zXUCL`4gD$Wrj|`_Oq!h@mb7xO)DV$OfI;k{hVrfuUf#1gdl>I9w@0?S)pecHKRp`u` zu;uM>Yr2ybwZu#+3+^uP?<)$JT^HV->rL6Lw6|b>d(P~Z%+|ul>WrYC z(x}?3kebY34!I;7V6bwP1o;IsOtV>fr}#kltH$pK7WM;0_j|fHhDcmaPH13q)6;Wf z6JZc}`0Syp=+j4!#RWu!o;d}oDQRe_=_z(Dnc(f^@+-NTnpODF1Y?q5H@zM&`~z<}E++an{Q!X+i7gh$&+$4t*o(NI(J=KdVbm6vd$@?2>=8p B34Q(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;4oO5oRCwC7l}&3CQ51%sn{U&`q^TwZ#iVG(g`m=nJ68qKja^C?+F#(ux`Mwz z{KCCUL8J(Zt_vv$)e4HXme$xBlbB>`%uJF=W{wLTD1y!4qz4XMIOm?{-uoWTRU*P} znvY#JR{*6{LMbKN{DNzOi1c+}4v_8cW}k@Aukcl;U_2I;2RAOsp-j?&ECGpr0JW3I zN+|)DIDUkiSEe!b8efawxc_LLl|scy8xxVw|E%E#@bURAP(FI?2L4c#VyVpR-N!7v zT?Z(LNY0bU_Z~i>T3V-TwrMx(42Nv4PoHtZSub5Q1@LlVg{IM=^u5N~Mv2vp3YIP2 z+f+p609LI25F|rSopBj8e)KAh5&xp9C%gjAv7{+9rCdgWl@Uw7}?E-T=TG zXL0fTY4RU7scQ|&TRO2&kVs^YX8-`_CMRihd>Fkhwl9o7U~w=tj4d*lQSs{aBAQkM zCDb&HQ)44ULP6T5=^0P}sMhM_7neyz6`9cl$FgbSLt&E9pf`Ysh4Kfo`n)Vqd%8LeLe?*)D iMu3^W;xqjY@M{1l@ICGKv%xq300007 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/sarachnis.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/sarachnis.png index e74c398976d28b3ae566d7ead7fc69a8ff5d25c0..c8428aa9847a2e95566bfbc218e2655b4a6df61c 100644 GIT binary patch literal 488 zcmeAS@N?(olHy`uVBq!ia0vp^!ayvA)3QZ!Tw%uNCXIrDYYYHck;4D_5e)a+GM%oSt} z1O>wcIRo@`JhU`yl$3O&B-BJjv+ZqsbhOkM7-Sh36a)n&czJC&8T2?AV$Ds{jP&Z$ zQoHi=jAW&XElrdBeDfp1Te33yiwi3av`je}k_~hg1b8J{nwMFbPw{k4x3#LWv6SNE z4A;`o666g~Q)zavN%|T!59ny-k|4ie28L;mr9Q0(a&LLMIEF}Ej=k`*sL4QtHQ}V= zfv61{UAY=hnmEOF1w?Pxd;dR*moatO_wZ-4Q;N>X_U=k#FlIl!XtF~ zap{yR-wzy5-=+W9=|!ftwDpR|nd0+zZ<}kl;_;i;zkBxWe967^)%^Np#{a9Pzm5HV coXzkXyJLXh-&~LM8K9{0boFyt=akR{0BxAC0ssI2 literal 884 zcmV-)1B?8LP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;`bk7VRCwC7mCJ8iRS?F1<9n}D?AX`FeM+P_Dx#uPC9o?MAn2kiq%PPuE7svZ z>3;z1Snw!9Vu`|v6|9O71Q8)6@gsIp+qv(1&al9a+{CrhMUOO#BhAb=`sVS8s`4UV zffxMF1Rx?CBBCd3Q$(5zgH?5|0bc;Rz#cs-UKaI0L=@oOD_3}}S|PNSK!jg*TC}2w zJU0{9FI9E@WW0M;F5f=?GC`IjB3!Oi`S^O7APm_ZJmIIkeXQyO5#c0AVL|ol0EL2} zD1uU}R8eCfNlBzYX}QWf^%?~cfCuCLG|$@P&jD^OIb_x%C@*;~`O%2BlR*XhxbF(#%j^UgmMDH5ne6*#i-| z4}3TIF9W4UgRI@c2<&=G1Zl?J*58EV;(Qm0!gz{4hyLY)z z_xbVbZ>e0U(H%w{CJ}LxP3NtjqG&?TC#x%5t5tDo4U#xw=irb(h9f-BWy$gI9GB5S zmnFgE0D3`4oOoQJ#?)OF~9! z?D%j#^#=2j&jk3n)5lnggCHUVX$lIN+KJ0&sw!ivEjp6Z6s-c=kN0~#$#OPD`1IBd zDgwX7If*?6c=TM7c0yb>76{A6B7r(3SThu?`3#`7=S{Av{5Jq_AN%jm*Ve`W0000< KMNUMnLSTZ)eUt3~ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/scorpia.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/scorpia.png index eeb63104545ee3a399ea58c66844379542d67442..db4c0ff9888f8ebb15c87652d26b21008fb56082 100644 GIT binary patch literal 333 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tQ2{<7u0Z<#|NlS|2m-yml@t`p z^YheIRc$RSeB9lvOic}RbmU}YtT-6_Jv_X4Ihrae+;}+>qax!YBAo5)a#B(ptgVgp z^t3cJf##SS8F{(5;u=|<$jXtrZ+$D4Adt4Hd1 zEx&f`0dtSlPQy~ixqQnE-!v*dDwxu6N=5w)}^O z_qqiW7Jly0e7%U1%`$6ik^M5s$haBYtL8SXQGWYvcSOnQd+)^KcJ5xg>HG8ksmEO6 XWtXwapP4>K5fmPtu6{1-oD!M(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;NJ&INRCwC7l+8|4VGxF&Y0qEjX(=r#6x$x42qkKoAi5wVHEu95v6tY|wO8UL za0y<5EL`Zy#AxDAf&^muO-{>(R?N8Y9Mc}!N&vs)O-|;UGxN>N`;Mq8|MSH7&*#z! zM5Hbv8sOy_2UWc=fI6Vvi2BH7W*{QL&l1E3Rh27gk%;&JBZ&mJD+{4{>q=S#WB?Tr zEfoqHRH8ubjPC`4*TR0MTvrp06$W4L>pvur7a3qJuq&XsY*vl95#D_t7-vX=*HMOq zaFYqWIW?v3h!fhpb0_G2xnr9;<9S-h=QZUf6i~y6t5+(iWf}vi*$tx)LFxc0*JW;Y zmXUAs_OT!Evkc%+jkZh+1uY?|FFfq zYL#}o%}!&NTk?~Sm`r9IOf$}>FFR3I4%R`)?a_3arr*RX-Tz zb(OE14YFfX%+1UoB7^l3RuH~CmmR|^6me`D5kY}wvx(z4oE{yKpP%RRw+}pBTjt=X z#hbTVY;JE6HX>R9-PE&8Q}0$P>L!zF+hz}QVzHQJGZ}rbw4}41r`K{heewK><|ih! zwz4vC;5`Wz%4JQbQfe4+9Yj$;%hS`kT&@23E|rEZyPg?1jzjDCnA6i=02`_*A%L;a zud%m_Wm$}-(roWGxb|RkB^^A oXct*_+HXf)WrFo#LyhA10RGnGHXJ=`sQ>@~07*qoM6N<$g0;~&=l}o! diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/skotizo.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/skotizo.png index cd96bbcca01af36999b59bc2ef0ff99afd00678b..6821a71a1e44ab4c10e10225ebc5f0bfa1bff5ca 100644 GIT binary patch literal 473 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5ts{?#OT>t<74`f0>sK0+gWTc&? zWm0sMwV9bLi?)cMV0Ln{v9Ym*v9Xl6xCDc;5{rSdqGC~2mW{Cw0|TSCeXItHr96vn zcwk^=VxpzKTUlOiT3npEs;az?zP6^Oqm7L!hrTF-ytk{Xv8KHmm$9L)t~!sguZMe(kB_^PQ+|577MJDwTF$pX zhccH0`2{mDOnWT#X+4m8%hSa%MB;Mph3xPa1p&4PcPm5B2p!G~b6O_29{dS{F%5*n)R?}Td=^n3C-d^ zwiY)E?bxx0sq5&v{D8ZU-tC*Vsv^QS)%Wj>ElumM*>bL%udQ5}D84$b<<-p%!Rvn; za=UfhJF@#_?!S*a=U@6DdB$h6n%$FQJ{M(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ$0%e1zXB=Iv-AFdN^LVH3;Ry#C?;Kob$|_=Q-zj-@HdtO7S8? z@Pgx70Zr3-nx-jD)6{M7|0JMk+I^sSZmq7vuMDNs*a0X&-QCzwqxpIKPUTZ2gf{y2 z#Z^4w!l}PGfAxucmbuwkbY1-Gv=jL(iQ6Za|azVjx&-$fHTlZ6s8 zJ!43Eqd@O@U7?#g{$qpLnJV8uc)-L&j(eMLGh1C|_0@Hpykh&OU6vOYke-E-CTH64 zMuBeu5;MR{BG&IMU>GL9JbHxN^GMQ^X0t}BI{f_WZyX>0fs~S7+G1tBLZssB1(Z_z z07;T^=aYFlhbCrNqF5~O!`2qn=?cxo1{q5bgdxjIi$v}KD|!jrve3}47kFN#=(->o zqzsY>VQBP^4DN1h@NjpRC;R)fj*f^21A4xP6Hd|Pgp6g-XinZ}(G!4Tp-8zjNxO53 z)-Lh><{F)Dmmmm<;+P-|dAzqrtun<7ud%`#q`?%HZJ_J=rS_qX+Vu$h?BkDcvJR$c zaHb?#%ORI@ICy%9>v@D>$V|10Fbv`(!m)D%fsfnk(>gk0@8Do$xi+>;bB=>jia3tx z_d|wqNZ4Jj51D5c0b4xaCi+Qt2`76nm6G8o``E^DvPvG-j_?=-}=ErwE( z&1Mn0pmPw>?sRcom&4y%092-?F25@mll*_hxFo+d=0EQiT%|GCKU{we06B@KvWeyY QFaQ7m07*qoM6N<$f?p@fM*si- diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_corrupted_gauntlet.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_corrupted_gauntlet.png index 9553dde2c1241fdcb4ae2e3e9729aa96e5cc16d1..a1b7fd687f99e8f4cb5723ed15bd5f2dbd854fc2 100644 GIT binary patch literal 546 zcmV+-0^R+IP)xzQxkcjS_m76v#WFsAUDkI=fL*{X3>V* zUm+a0KsMuDQKLC8ef9ZpI=XPu6Z)D0CLhYK8Uzq<6kxpF8W+Dt!!EhcLv zAM?Am^SZQ#E+=*=BI}Qa?30V*UQ)k9IG{K#U7L7g00003bW%=J005Tb8uG6I007=e zL_t&-({0fEQ-VMc2k_&*mk)|Eg)~wzpCE;S*%N!3uTcO0|Hiu;1e$4oxtY)G?(Hri z|Ag`WMiB$j kf939u)|9u%*x?4k_INxJ(IlturvLx|07*qoM6N<$f{Ld3-~a#s literal 823 zcmV-71IYY|P)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;y-7qtRCwCFm0d`aVHC%I@5kPKyjyeA>2eNrW|D|$Mi*&f5kZh3ME6$Ebyv}S z*U@!X5!F=}S{6bOWZIJwe zfW;;bRRE|0ajmmEzdr}aU-B{Cg;M@+C``Zwum%uMqbR>aN|GeDRFSvJfebk8*4)t5 ztd}~?EHD5>0QNa`zAuM4ifQLEH4N~`R-Egx+|aG8Q=^!as=J1t zi_2J?5?tHIRBqpU zfF>mBy>|4JPAC~+Gnqsx6R@l9)Ydo!AVyDJ7Ek==iv@9;xD~rv;^OoAv$PULGpWq2 zMoF!$F|~727c1#>qkmJ=QkfTbw7qt%u5tmt1_0J*YYMrLZ&?5U002ovPDHLkV1h=S BYtjG! diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_gauntlet.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_gauntlet.png index e34fbe3d152e1835582375364946d8ff7a9de02c..d24830e178bc468b3a7a8d05af0e77ca475ab53a 100644 GIT binary patch literal 618 zcmV-w0+s!VP)EPQ4fP)QnTR9c>uYP+#?&B9xtmqmGVh3w9b_1BE;&^hC{ zCTn9FN<}E2fMBVhKXGqnw5xT`%XQDhbIZYOzqM((uU({^eACa7+17{k)pyaxF1VFc zl#xb!dP$y?f9uSo-`8rpxH@NLG?IBVk9H_>UJW83NSl&Prkj-7*NWE7WwNL`XJSx{ zib#KbB1}daIWksisPWf;V<=dGygT$f989!cEt*GK_RSBxu3_000AYQchC< z0G8t#@~;2@0Ov_WK~xyiV_?7n7*PNdGZRP*NFl_SSwMn}%&g4F>e!eW7?_yZk;E98 zIe-e8Ik}j@3YfuWFadQlFmv-TGXX_-`S^jN%*-4DKrulfVP<9#Q894|NhxM&8CjrS zCT2Nlc`gM-C1n*=H5PSF4Q8-gm^HPub#(PK^;tAPrh?rJ6g4n3GBz(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ<6G=otRCwC7l}~I`RTRd5cizAG_v}nFe5^WlcHCpJxt)w<_ z;Z9d3>`XMSh>);Hl!Xg1Xa$ThmROY`0a8LrLz_Y~SS{9>&QNT}_hx$Bbed^r+73;) z$+x&U=brDL@7{bzi3m?}d3eHWnLsJkq?GDaN;N%B0j1OnN-0^w`I3YsiTVI3La&HW z309pG;QWesaZ+9Lj^)J1B{*{Y6VWtJ3CW72ws((inxN*nZPNes*^=`s9$7Q3wRD!% zC<=!G(uqH?g8ub?kzp9vL0_Th`%92DNGFw2oxm)B?bS(7{kc9tFdCtuy}hvgYzYLL z>S??31v|ev&h|GCq4_O&E;P2%AN%Krc8?F6EiSBOZ=DF`nI~5TMGSs)k=yfhF?M!$)85m~gV`jmfaxf-=;>FC7H2~MlV$hA8>9GgKoIpUWF$WKoa zn01PapAnJ1vX3kxlOhrVn3_&8;f-+M$SXX0dV%l8exWuA`SBTsZ^lU&DH?hX67GDN zsp-_RB&&Eoxd2`qmI!*AfuFJOhMaK+ucU0b@riNOolmPyLZkxAUAJ{H5W{a67XIj@1{ z^KG6WJw8E1X?%3@1X)cHs&B+GU9#yc?m`yvc<|cx#(ut${YL6SVqwX#e{ad*#EurC?YJ7khLrG-IVtbsOzp=8+rl-YgYlUoWh^(y0 zs;bALqr+uof0LBCet(}@T5)}SooQ)=)Mu@Y00003bW%=J005Tb8uG6I008kxL_t&- z(^b&vR>Ck41>lmKv=XY|LPc?*A}y|9!37jiSrowq1=PB||634f3T1xfd}n6PtWN+rAN4ou}uQ*RI-@>%@QY_TKCD^?^8gk^w$G zzY1yBWgHVD_%?ss)-O{L%n$b8e;0w-V9)}F6*d^}O9a{;00000NkvXXu0mjfBWP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;nn^@KRCwC7mA_9@Q545Nw|(V33Z+%~VTe^sEU`3ziI!j_nnv9);^u&gi*ayp zGdh_#`Uf!h2f$*)NsJC1!~r#k5eX>TN{WF}+XAnBuYGV`Xe6=J(!fd1bien0?!DiW zbA*(Vy$la0k3#q9N89dP=ySgq&O{szv~*jb`j75)7dLHn@)p8ZWIs*{D~ zUzqv|Mpnn^w9r%sjm<&A;b#D8DWzw}9>@(zW+h33dmjOBEB-(bZ_9DgsSP^Xj?mqG zu^@Ht*yK>?3dyAyid`Z3JC0p(APfV$V&`CEGs7ceIBV)kUQj8u7zhOM`#PAOctboE z0R+~@I;mI`dv!Gf*YEM|>!->AUayaZ*-38Pc}OOc#KeAH#I$32xmVBsx7#X5uBwrj5f#{meyYDhK@d{)LW{XK8WSXSQLB;_cWA;!Cl@ zo`IbJ?gGSEiA*t<#OTFR170aRh3#+yDnw&Wq{sG z*Dy_syk)VtIFFgjlFOOot^DrH1I1ng0)((p=k}nfPJ{rpO2h3wQ0QH$iUF@)4`G@X zYin6@rirenv8+6b;=tG1S+WlS#k=X2Te-`ejOp!+ww0I@oDF|9U_p7VugWPV_aK(c~wwQR*#BcKtL*+n`%~3ML;|0002eNklfrLx*ld92pz$;MtsqxtmwQrYj|wbkyt zDen*%hWY-{{_I)^&jh`mZGIW1-L)({&$Hp9(EMlhaCXY)TB7VK>4$V^s? ht;rvi#a@Ja_8+tP6$M+4>$m^_002ovPDHLkV1nQf)rJ57 literal 700 zcmV;t0z>_YP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;LPOws&;x1*OW> zFm*)fOpc4;5iVW5Np~;+xNtg*(zdf|53K4YyR^kusQ|^ z`XABiEAn}|pV3>_OaW@l1ig7bO`XGnz2-Xk?FHuMS9tMiva~%@O$RdosTwT*75*zFE{ zEyvMq+CQ^Sj*Gh9V0yQl4Qb0G67q;B`jKz zu{%*deRLfBFItJD&^48bi5#hgk0A1i0ASJ7{ZKn3%XaIJh}Fdb_#?`}zj^ z_=NcS23eT7=1n8` zc{n@!dwSTIo0}OKnds|#@Ur*G3T{vl2@>E`R#I}Zwe_~Q5ApU6_49Mq)6J zw6n0NZ@gUr3?0^zAirP+hH0D}Pu_g&01906ba4!kxIFj5^`Juz608ZE3OEE9g&iE0 zuJq_F5nU3_-L|ge{(oJcPy8{)b5_sIFH1Wg+5GTIL6ro6N5?t=@I3$l$zf}As(XBp7vtDXeqxh5MK4#PP zMdmJjF23n{(bKh2tIcQWF1V}s`rCw8{0-mvCFjSd9L}$pB4`lyCd2>45=MQ0QG*tl z%_nOTuiXFpGj`pz2MRgctY0lEyZ1kH^OlqC=jL=?ta(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;>PbXFRCwC7mCJ71MifBLkRy>4NmG)IR<#w>LEs85Qos$+0LiBPfug_QKj^Rc zr@G0aO^c#|od?`JEIX+r8lw0T$=ii3!4PCyUSxo~7+~%__c>RI2%qy9eCD$fKq*ZK^Ee^y5bup7Qhgd(I{?lQ_n#D%Ly? z#oY1zJ9W|1M~~3M0skHzQZqHjtuD_t?z1KpZ%$6|qL6Snz^d10D!(eF_ErYiw#8|h zlGrvIrs7Q3c@t;U8ZM4)Q)-*(v|zp6#&{fazG_D=6nOh0{|-mT$Jnk*+V8XZWrtBTM!7DY=h4q| z-X0yHO%vbusnzS~T5Yj)mqu^^U|S8IJbui*PKQe|LRW<(!(j*~DqFB8swP9LIdKxk=zShzNlQrGlg=5D_LxLZ0V$|E^8L zKrSPxX^r1-QA*)A9F$U&BIHFulBQ6WHv*QXsF@{9r&BT!ENxO2B~D$VO~t$Mgg^;8 z%gOVMIF9cg!Edi#b3Pu^HVvM=e9ed9kpISG$_k1!MbeyNnh+-m$t@8qE|=yF%jGs{ uuC#D2r+FXv=@JMK0zcm1=d}yx{{aA29JUf7M}!jq0000Q&5e8)06>7itd_ZZNnhw#31UyDWS$7Xv!dA%D}0{z+l6`smH)6%fR5o zz$^bh_$JUG=8_=4U=NXwxhq*=8?!T}7et?wNUvN*3*wKEmgfrlhy1ZdfIzW@ux|{4#Qfk>#z^iQQcV z8xKntE3C>&Z)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;f=NU{RCwC7mAh^eQ4of|IeW3=P1q#F0wItUpg_<79Zl$X0~(4bkAOrT1l|BD zN}!^pprM0;Hlzu`ZTIXMitIYJv9T#K(l%#i|2hBsXJ$lIxkxiyu+5Y}MDB}- z4t}#HkZC0nkp>Wt^Qo%*7XuO57<1EDH(0Re`aCZ^*O z6e!`-4wZUxLWWLd;^*M6ftu$TmNTCvJj!P-LVQlKELN)=?(NdU0VQhDWwu)TvuRL> zc7rkzhEo(DSioa}fFmp?I0OY05ESJ&Qchakf3g_TV2O|fMRJG1U;xD-7@)vV9EMga z8Pa2Ff@7Nerh_2Z94v%jnp*t;BeE17}r2eBT3j zEFv!_j*6mOcg+gdJ)xdaWk{J?l)U`8Is)@sH*EKjyEltiv zGzg6#AzY29(-`_Wz#&7NCQs856niy#@Mi#|$Pu;>75lRQ0000I_&|F*FL{l?TkV8g9#92hpN?$)&gkx%Vmx!RC zoglBdAg{iv>d8X~kL=#9t*9u&z_4xgsvT?B%$q!U-J(UCmM>d1Z(h=xAU2?7%q2m7 z!3+%39!q^%59Dt5ba4!kxSV_8HD8kf4{O3UUPzq7DX~#o3S)g#P%-z;6z_tMf}Pf-4@ZrPI$YzwMt?y{Qn&742`R*t+`G*{W* SU%Nd(!RP7f=d#Wzp$Pzvrixww literal 882 zcmV-&1C9KNP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;_(?=TRCwC7l}m3NMHGdQP@)zD)t$QYW8;}}i~KKoIU zFa6#*ckVQE0Ysz$9OvVP60Vm60)#ZRbZRfs$|43QLms7?KN3rtW>Y{HaWJW*>1nR4 zuCk;uLJyAXOE{(IWFCW3leRB3iY2s~q`SQc$#($O+il)iUuRgVP{82>f}^iJ4n%R_ zAS{%5%|*OWuP>&eu_|sCivhJtg}&$0G9x18;Q%c{bUI>WEm@Y)u_=B~WYFy{EYoiR z8s!?k*1UJ~CNKT^+qimYJ~`m6cdrvDMW7VFqey}F3_hnw7LkX*tEEE7>z6k$NkXwy z=KVL{VDsu#5@Y!6<4+hgn*>3C=Xu0&j7d|Bwe$vqT>df-zyVy@+{8JDR*GU6^3#I{ zlQkQcE@6`dtu>zKkyuL-$Lt>-;aqkOz?;XguQhR!Ffs-Ku5E1rV6DZbDdPKx2yqng zsPp%~S68cY)a#wgGZ)~m!$WLhC|9ajtx-y0k_4?3X_k=~gNQJUW46}Yq@?`$c$#Ey z#*4-CG{&Z&GzuXyhGaNIl}ePukaB77vR$!_(6|)rV6m8cVY-K&@P% z^>UTXjb*OAy@GKOU);aX_VzYTYq|)B{XV~Rd;ENK%;Uj;{ez=C)sN1(@21QyH?3Fd zb+=rto-?xLrJDQZt1sP0w{E$w_x4;BTp0RKo88@6W;gW?BnUXMCLewZ(C?oT8$-9( zWB1%5X;80Hl{JUhR(vf|pUmiyqw4X2gL*ZlBIn|~TW{yXy8 zcz*ZnRWvG<$^SxqWL`s=(QtMaX)qT7?48-Xvp`pCECTS)0Eh=Xvc2^bGXMYp07*qo IM6N<$g2D-oqyPW_ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vetion.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vetion.png index 383d30a11991846365ce100bed007026e1d29df3..cfc9d47a03bc22fa10ec065933e3708013f243b3 100644 GIT binary patch literal 391 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tlLLH0T>t<74`f0>Z(L7OQk*J- zYJjJwE`x4^M}0nTo+E?334=+FO?D(lL^?-Wq^FmytzjHTY&t^_7XSLGSzt>rJwQ9vKzt!z)C$Z|i-FKAl b_OE#PZ?WvATVH(h2Zg1ltDnm{r-UW|{SSsz literal 728 zcmV;}0w?{6P)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;UP(kjRCwC7mETK~VHC$d=h^1wez|FE%5?9xD9|!Ahy{x&UC1?&>e- zKgs`~=-Lv6>dKM`y+}}~L~<_2{4s6wbhCHpT65DnaNy;6&i8zI&pF@ch^q2G&G4VC zB?1w7CL&t#@uonk+LQw?0j=?gV{t7ID4>sTJ<@?#f0g7ooN2N&;{YDFi|yz-j=baF z^*}@>fENJ0p*XwCC4%k%Zrt|$WThvQb@9iIsfZ{*CYj+vVSwCLj;{SK-k*QN!qPIO zQu%N{rKLX*ks*M9za7(A6NNG8f#^A2x5Ou1atd!AKB)wu6)=@s@lX$blU{-H<>;5+br`&pLq9VYqkwE3zwEb?7> ztaC}MkVQI~Mx>f!<*z-kliJqiauVsj59L=}9!#>o7@~L0Vx}~ME6@gRhzH}$FU=F~ z2(y@9{G%6jOB6nnA>i*prHyZ2pQ8s#p-{x}%S|r2fhW+;LVkfhPam^Ovt(txn!KTs zffZXoE?4^z)f$Z6iQU$V{sB#QUeRmmeyyYIO(4-w$(5iZO0~aJiMYnPJJsPZ>hpRI zCr&i2WK|6TVPF_Y9=^M@I>hc8Jh}Rm?VVz^-m1FNl9E+*Q&s0{fjgxlIdbIYHt>qK z?$n&*si-~yTZ378A|dAXKQPR&eQcd}A3OjU8@s`ta|dG#qYwM|()$Txq^h42?}OS& zNm)^KI*i^NO{>f0w9iLQybpkhI^$UDiBm6}3R$R5@{vZE-va=iM-p~g0g`3_0000< KMNUMnLSTZL7*c!y diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vorkath.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vorkath.png index 03bcc75ed4c073de3fa989e659208d3211c320fa..696669c35306f5dab14d48a9bbfb3f6ce5d81cef 100644 GIT binary patch literal 597 zcmV-b0;>IqP)zO=~A#k;|`P*hEBu)%P%#i_BSw!E@urnX?3sZfB7JYj3T!@A7S%9ovz zLPbD*bb4Ktq+FDuWumfTo~~|lYp%Ackd})|c!fxGe?@P3Ia_2A9UzO4hE9EoQiYM0 zosu+CTOu_)!^gk6zqY8aqJV{aaA|OAVrrF}kV0y7H&|gLIzJsUH;s$_5IdMv)r5uB1qC!TMYN!H$Y|@x z>*}fM>Khm`L)^#2EMuf&tgdTpVrpj2%n0@evxTLVwU&*ooxOvj6HLt6MaR|6-NTdB z%NwrFmD$V3*T+xSUco;ACKedv>+8!C91(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZR1`&)qIb0filW3TaKkGSmhRw9Kq^B- zSWVoH1NJOiuS|NScdtaE5j%09f@GkAU=r8_d|=P(x-Pq)d9qR@P*vdg$$r^?V4rB3 zQ>yH&YJ}=*1(3e}FC-KS+Vh)ifn}HM_4wGfV;lZ}pQeVu-*pB$cRfYNLyu9TyNQJT zgd-ukw`?SnD{|uWF*K(}xFKvq_SheeN&%NkCl-qlZHSVd$?*8@T`bPcaU4OZtCOZ!j9-UF@Ok~rq-TgkBU~7}2=ESYaD_m*Y!MDe*th>hempV2gWVhG z-n@|uiL0EKFjlcZ-P-l+Y*di4;IFIY{SV*6vMf@m8)P%t6-~5EV03hpt(&*-a8D0C zTestO>tu{PJ9jkm=j0+avqhZ267_nTYnc-9)(+w!57X1v$z`%!NhEBlL$}H+A}ER? z04>ciUO)5^N!5qLr7>TI?UEwuuAy&ALyQdhY>qA~$nqCymVOuk2)3=`>9^m-p=pR!rp6xthZCigXL>ThY%Wd7oI_Jp$_plDp+I72kf}@K zHs|vqa>!&fZvhgeKs9LH(i zs{MgV@?};bB9p+W;!TsW<3|auT~DB~8F4r%%uFGQ;8iW0ULTS64rb$Rc)UJLU^;Es z9H0D~**yaA@u!D*w6?&+#3f#66fkFbtusWeuF#a9VDhIQP^<-fEphff`^4S5>6f1$ zA#Iqv)E*{v`6|l5w~UOP$DwL8Hnh^BySUG}Kzu$$CUyO;1l|G|96ZOFlLJiU=17hw zQC)7nIdY7GQNW3d_?kAxZe&R&uQ7P`oQ*wI)om+ZG(}MYKo-E|tL5dxpK-sDX6XCx zFp33&^+8P2B%Mi<)O4==@-t>WW5c^eWcZFJ5RshS!*j&~>glhUX=qN1WDJ{-YT ztm)=Fic$hS@p>nBEqt^n{r~>DOOtXW`M55vF|&|j-jyt~IbLdYw4|<_gn^EN2sd+r zjnJ$l)$f~2y8{@$>}=l@<}bp@(QM7RK3?o(ivI0Pt7~bN%ltIkBb4?vIR4+3_4DZb z`6-?^4u!TfF$i-pu8$L287+LX%JA7-`KPmG*OYKgh*4QxV6dqr^gx;=1DD$MQ?acJ zCjS5CFUrjnqQa1=!SJZc=vuDZEXC%ui?kE)W1tAzAdQvFhBFdp2}6#!6_bk9@=W3XH|Thka@j2 zX-i_zzU)X17UiGo4L_}Q`hB?a^$J%3KCXq4Ug3J`M$+Ou9Bd2>3fGUU`Eq9AvwLUQ zS(z6!WyM7X&uq#O66DSd_pmcmH`CWj@OKpA<4Fy6w$@iwQ&I7-HlAFOoE#CLq@Yll z5@ezw8xy0;>AjW{DK)2mO1nnY%rK5aPMWqgoKTk zFPsSY@HOJZiWR_A!sY4W7$R{wIYEKhz^KzOxocC0x5uVMof|tlJv~pK*mU@6M`s~} zrlDmetE*~i7@HrTp+G=js4(-%RoNL?nXd~r7QKAc`BGX!O48V{sibq}j9D|IBcdX2 z-?(+t+QMq11CMZVSz&4McY)7eK7IT6^|N?$l%Rlwh>Vbwn4F-bsI0IwyI@+kzlV>P zpQo?)`4eYOojZA!nS1kdaS<`m=~Jdn4G#$`{QP0l$Huph*RNZ-c6EM6PF7xKZgOL_ z+nT+LH*>#O_-@`kJHr%vu7)iezxdCv$TZ?+wi1|aRC?=+WKvR7#v$YMv-6D0@6{-p zJY?k-*F6`nq|zg{&3n4;`E+4HH}jZ~o@U{5j11Q$t)4GdJZ}ifFrKb{F6*2UngH?1 BE#CkD literal 957 zcmV;u148_XP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZoDVR4 z5Vw$M{1bx@CXg63YBa`Zh&(XjlNi&v7ukbb41cB>T8Ci>5gQy6b%Sn^u3guAd|8{j zt~9X3_)Si7Z_Y30`}>}Ae&;A6!heY>{%14;VzEUKk&0Fc$&%m##O{`$G(`zZu#nBB zqN*yot{42_N;gszMM}(Vv-sn{#==iz?ZX;sh$ z&=_n08c}RIu?RHPPUCdg3uj{1;H6kuXK?bJXLx8sb6I~J5Vy-Ar;bM?5D3UCkK1L} zgPQD%Iv3PpWrJJZ-P7SAgQTa7tWq`0(lua(UrEIK|UnjdJ*@RYdOzv32vk%(~X&_dm+mvL6_^zn6*6i=9<0 zOyQ$gIG?U?ba#N+e4cQqiRG(rAg0OLUnUv5-aydrq{hDnk`y@>VQQ=gV)SWHWe{3)zd;&7j|N%rx^b`%dg`pbiIb|Bj5AW34^TZVOedI)U{#OJa?MZ zbQ<8`e0rPbvoI(k$wjXnke-gmq`hUGYzo$i(_UR{wcrY`K(maV`a=F0?ve2;!wY89 zoy?+mnVGY|YBW`j9qN`n9lPYnq5b0ZILe(1R~mL!lFoU_3lw&>Z!q`8 zt9T7(DM6wffz9&BDq?OfN8U6^-O6))Vw!{9?Iel1x%^sk>h|evgZ6HbbPf zm02ajOYa?HC~>h6oO$I-f&ijc+vWL=C&XpAMAOvL^z2y5!dXO8VsRh^ytvejX2l03 f!QFSd(f%C(CE^4kfX!t<74`f1sS74xTNQj%4 zkBOyaKvZ# zTPG(y1EcJs;v_%cyLwXQHa4;f3J$KWu_>u>P7Yc+I!5*mpG{=HO_iOhAb7V;NUMUF)dn+p&bMp!b-VzC34_;0wB_$OlB?Vd888L#g3=BqkdOmJ$eX@dK zf}A>9TBZgDqJn}>wzjSg4!iBt{eZ4#E(!7rW?-21SnAVyAorrDi(`ny<=hE3Cp8%e zxO(a>=seV*{ciU;r87I4x_(%=q=w^U?iJF|)RxVk_S&ZC-5p@4s`}-u3K} WJ^Ttk6#{O9V#?Fi&t;ucLK6V*#jC&o literal 929 zcmV;S177@zP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZRCwC7l}~RQRTRa4cRVv0XFSO`iQP11+2;j zv0=fkQNIEUmhD#n!3GH-byJX7psJ`v3KXyCqA0E$CvDRvj_t8M9(x`OVz7wqno7OW zlis}h=V;D7?_E(!@ghy*1=~OX5xFKJs%NeB_}2d8QzDY-Tc;mIBGQ*PrIZZw1N%xT zcis(Z zc9tujzDKFJiD?)tEH3utOz(H-I1WK8K-YD?{`M9ifa1)lQ=k;3?QOpN<|Y6a-hGEK z3=xsh0d!qQL|9sWmE~*}!?JjE_ctPTj4L}Ee3DM{QEr7N7z6BEp&T=Q*BA zp_IakMxnfqdh!SW&$Os&I!(Vp5Cm)&ixf6C4$1itMM|lYB2rdLP2T?=Bp z4(pqWxn!H{7a5Y_9@)htTbr8z50p}wk(vx#1FjZ|J1k_TF@qLA{5+0#M`yj(q$3({ z1Vy&232xrL*Uc&XpSS2LfIE>S3`1tTD%a}?Ui)y2rJTk0kA3{(FJW00v&m#P=iJCL z?OJAjo|@;OMLqrmfx(g`33| zZ4q6vc(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ-Z%IT!RCwC7ls`y9Q543%YleRaCA5edY7q&7B*|)%rf6zxi)w9ZaSei&7N^EA zXb2i|wHktGipZ^{p(GG2Qy)GbTJg1X<@FMuR`1c0H$Th#pe%X4s{qs!rh<4=FSGP z=P$TEH842Z`{!Tu2mq;rD#9^0)>oY<0 z+T+w5q%{OkZg-!gEnp15g%nIAR_OJ(qW?1NHCL(Qnmv+Tcjax@xM zJ1QFWx>~^7yJEmouB;ZI8?R~sq0qQmKt5kk3#jRuT0lkX{uiN>b~nu)8C#v)vzRo2B=I=_OgnuXK0|`h00000NkvXXu0mjf^mfC= From 49138527f8fb6a8da13d5382bf03080bf2d0ad76 Mon Sep 17 00:00:00 2001 From: wrightmalone Date: Sat, 19 Dec 2020 20:21:52 -0500 Subject: [PATCH 08/53] xp globes: add option to show virtual level in tooltip Co-authored-by: Adam --- .../plugins/xpglobes/XpGlobesConfig.java | 25 ++- .../plugins/xpglobes/XpGlobesPlugin.java | 12 +- .../plugins/xpglobes/XpGlobesPluginTest.java | 162 ++++++++++++++++++ 3 files changed, 190 insertions(+), 9 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/xpglobes/XpGlobesPluginTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java index c32a8c598a..2a956da851 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesConfig.java @@ -89,11 +89,22 @@ public interface XpGlobesConfig extends Config return false; } + @ConfigItem( + keyName = "showVirtualLevel", + name = "Show virtual level", + description = "Shows virtual level if over 99 in a skill and Hide maxed skill is not checked", + position = 5 + ) + default boolean showVirtualLevel() + { + return false; + } + @ConfigItem( keyName = "enableCustomArcColor", name = "Enable custom arc color", description = "Enables the custom coloring of the globe's arc instead of using the skill's default color.", - position = 5 + position = 6 ) default boolean enableCustomArcColor() { @@ -105,7 +116,7 @@ public interface XpGlobesConfig extends Config keyName = "Progress arc color", name = "Progress arc color", description = "Change the color of the progress arc in the xp orb", - position = 6 + position = 7 ) default Color progressArcColor() { @@ -117,7 +128,7 @@ public interface XpGlobesConfig extends Config keyName = "Progress orb outline color", name = "Progress orb outline color", description = "Change the color of the progress orb outline", - position = 7 + position = 8 ) default Color progressOrbOutLineColor() { @@ -129,7 +140,7 @@ public interface XpGlobesConfig extends Config keyName = "Progress orb background color", name = "Progress orb background color", description = "Change the color of the progress orb background", - position = 8 + position = 9 ) default Color progressOrbBackgroundColor() { @@ -140,7 +151,7 @@ public interface XpGlobesConfig extends Config keyName = "Progress arc width", name = "Progress arc width", description = "Change the stroke width of the progress arc", - position = 9 + position = 10 ) @Units(Units.PIXELS) default int progressArcStrokeWidth() @@ -152,7 +163,7 @@ public interface XpGlobesConfig extends Config keyName = "Orb size", name = "Size of orbs", description = "Change the size of the xp orbs", - position = 10 + position = 11 ) @Units(Units.PIXELS) default int xpOrbSize() @@ -164,7 +175,7 @@ public interface XpGlobesConfig extends Config keyName = "Orb duration", name = "Duration of orbs", description = "Change the duration the xp orbs are visible", - position = 11 + position = 12 ) @Units(Units.SECONDS) default int xpOrbDuration() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java index 46b514151e..39b947616a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java @@ -106,9 +106,17 @@ public class XpGlobesPlugin extends Plugin return; } - if (config.hideMaxed() && currentLevel >= Experience.MAX_REAL_LEVEL) + if (currentLevel >= Experience.MAX_REAL_LEVEL) { - return; + if (config.hideMaxed()) + { + return; + } + + if (config.showVirtualLevel()) + { + currentLevel = Experience.getLevelForXp(currentXp); + } } if (cachedGlobe != null) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/xpglobes/XpGlobesPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/xpglobes/XpGlobesPluginTest.java new file mode 100644 index 0000000000..bfc5de4b0d --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/xpglobes/XpGlobesPluginTest.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2021, Wright + * 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.xpglobes; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import javax.inject.Inject; +import net.runelite.api.Experience; +import net.runelite.api.Skill; +import net.runelite.api.events.StatChanged; +import net.runelite.client.plugins.xptracker.XpTrackerService; +import net.runelite.client.ui.overlay.OverlayManager; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class XpGlobesPluginTest +{ + private static final int VIRTUAL_LEVEL_TOTAL_XP = Experience.getXpForLevel(Experience.MAX_REAL_LEVEL + 1); + + @Inject + private XpGlobesPlugin xpGlobesPlugin; + + @Mock + @Bind + private OverlayManager overlayManager; + + @Mock + @Bind + private XpGlobesOverlay xpGlobesOverlay; + + @Mock + @Bind + private XpTrackerService xpTrackerService; + + @Mock + @Bind + private XpGlobesConfig xpGlobesConfig; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP, Skill.AGILITY); + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + } + + @Test + public void testVirtualLevelInGlobeIsNotShownByDefault() + { + when(xpGlobesConfig.showVirtualLevel()).thenReturn(false); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP + 1, Skill.AGILITY); + + assertEquals(Experience.MAX_REAL_LEVEL, xpGlobesPlugin.getXpGlobes().get(0).getCurrentLevel()); + } + + @Test + public void testVirtualLevelInGlobeIsShownWhenConfigured() + { + when(xpGlobesConfig.showVirtualLevel()).thenReturn(true); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP + 1, Skill.AGILITY); + + assertEquals(Experience.getLevelForXp(VIRTUAL_LEVEL_TOTAL_XP + 1), xpGlobesPlugin.getXpGlobes().get(0).getCurrentLevel()); + } + + @Test + public void testGlobeIsNotShownWhenHideMaxAndShowVirtualLevelConfigured() + { + when(xpGlobesConfig.hideMaxed()).thenReturn(true); + lenient().when(xpGlobesConfig.showVirtualLevel()).thenReturn(true); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP + 1, Skill.AGILITY); + + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + } + + @Test + public void testGlobeIsNotShownWhenHideMaxConfigured() + { + when(xpGlobesConfig.hideMaxed()).thenReturn(true); + + statChanged(VIRTUAL_LEVEL_TOTAL_XP + 1, Skill.AGILITY); + + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + } + + @Test + public void testGlobeIsShownOnXpGainBelowMaxWhenHideMaxConfigured() + { + lenient().when(xpGlobesConfig.hideMaxed()).thenReturn(true); + + int totalXp = 1; + statChanged(totalXp, Skill.FARMING); + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + + statChanged(totalXp + 150, Skill.FARMING); + + assertEquals(Experience.getLevelForXp(totalXp + 150), xpGlobesPlugin.getXpGlobes().get(0).getCurrentLevel()); + } + + @Test + public void testStatChangesFromBoostDoNotAffectXpGlobes() + { + statChanged(VIRTUAL_LEVEL_TOTAL_XP, Skill.AGILITY, 5); + + assertTrue(xpGlobesPlugin.getXpGlobes().isEmpty()); + } + + private void statChanged(int totalXp, Skill skill) + { + statChanged(totalXp, skill, 0); + } + + private void statChanged(int totalXp, Skill skill, int boostedLevel) + { + // A statChanged event uses the max real level + int statChangedLevel = Math.min(Experience.getLevelForXp(totalXp), Experience.MAX_REAL_LEVEL); + + StatChanged firstStatChangedEvent = new StatChanged( + skill, + totalXp, + statChangedLevel, + boostedLevel + ); + + // The first xp change is cached + xpGlobesPlugin.onStatChanged(firstStatChangedEvent); + } +} From a5b6e279a818945ce7768bacf8bf9c7e0a7765a7 Mon Sep 17 00:00:00 2001 From: Cyborger1 <45152844+Cyborger1@users.noreply.github.com> Date: Mon, 25 Jan 2021 03:05:55 -0500 Subject: [PATCH 09/53] idle notifier: Add low & high energy notifications (#12995) Co-authored-by: Reasel --- .../idlenotifier/IdleNotifierConfig.java | 31 +++++++++- .../idlenotifier/IdleNotifierPlugin.java | 58 +++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java index b7ab769756..99f0a5b55f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierConfig.java @@ -27,6 +27,7 @@ package net.runelite.client.plugins.idlenotifier; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; +import net.runelite.client.config.Range; import net.runelite.client.config.Units; @ConfigGroup("idlenotifier") @@ -110,10 +111,36 @@ public interface IdleNotifierConfig extends Config return 0; } + @ConfigItem( + keyName = "lowEnergy", + name = "Low Energy Threshold", + description = "The amount of energy points remaining to send a notification at. A value of 100 will disable notification.", + position = 8 + ) + @Units(Units.PERCENT) + @Range(max = 100) + default int getLowEnergyThreshold() + { + return 100; + } + + @ConfigItem( + keyName = "highEnergy", + name = "High Energy Threshold", + description = "The amount of energy points reached to send a notification. A value of 0 will disable notification.", + position = 9 + ) + @Units(Units.PERCENT) + @Range(max = 100) + default int getHighEnergyThreshold() + { + return 0; + } + @ConfigItem( keyName = "oxygen", name = "Oxygen Threshold", - position = 8, + position = 10, description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification." ) @Units(Units.PERCENT) @@ -125,7 +152,7 @@ public interface IdleNotifierConfig extends Config @ConfigItem( keyName = "spec", name = "Spec Threshold", - position = 9, + position = 11, description = "The amount of special attack energy reached to send a notification at. A value of 0 will disable notification." ) @Units(Units.PERCENT) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java index ee084f3c44..e9d2d01896 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java @@ -93,6 +93,8 @@ public class IdleNotifierPlugin extends Plugin private boolean notifyPosition = false; private boolean notifyHitpoints = true; private boolean notifyPrayer = true; + private boolean shouldNotifyLowEnergy = false; + private boolean shouldNotifyHighEnergy = false; private boolean notifyOxygen = true; private boolean notifyIdleLogout = true; private boolean notify6HourLogout = true; @@ -471,6 +473,16 @@ public class IdleNotifierPlugin extends Plugin notifier.notify("[" + local.getName() + "] has low prayer!"); } + if (checkLowEnergy()) + { + notifier.notify("[" + local.getName() + "] has low run energy!"); + } + + if (checkHighEnergy()) + { + notifier.notify("[" + local.getName() + "] has restored run energy!"); + } + if (checkLowOxygen()) { notifier.notify("[" + local.getName() + "] has low oxygen!"); @@ -572,6 +584,52 @@ public class IdleNotifierPlugin extends Plugin return false; } + private boolean checkLowEnergy() + { + if (config.getLowEnergyThreshold() >= 100) + { + return false; + } + + if (client.getEnergy() <= config.getLowEnergyThreshold()) + { + if (shouldNotifyLowEnergy) + { + shouldNotifyLowEnergy = false; + return true; + } + } + else + { + shouldNotifyLowEnergy = true; + } + + return false; + } + + private boolean checkHighEnergy() + { + if (config.getHighEnergyThreshold() == 0) + { + return false; + } + + if (client.getEnergy() >= config.getHighEnergyThreshold()) + { + if (shouldNotifyHighEnergy) + { + shouldNotifyHighEnergy = false; + return true; + } + } + else + { + shouldNotifyHighEnergy = true; + } + + return false; + } + private boolean checkInteractionIdle(Duration waitDuration, Player local) { if (lastInteract == null) From d61c6b91a7159fb0cde4a3909ed86c666eb6ef9e Mon Sep 17 00:00:00 2001 From: zeruth Date: Mon, 25 Jan 2021 13:06:20 -0500 Subject: [PATCH 10/53] api: develop --- .../client/graphics/ModelOutlineRenderer.java | 1113 +++++++++++++++++ .../client/ui/overlay/OverlayUtil.java | 54 +- .../com/openosrs/client/util/ImageUtil.java | 134 ++ .../runelite/client/config/ConfigItem.java | 8 + .../runelite/client/config/ConfigSection.java | 7 + .../net/runelite/client/config/Units.java | 4 + 6 files changed, 1314 insertions(+), 6 deletions(-) create mode 100644 runelite-client/src/main/java/com/openosrs/client/graphics/ModelOutlineRenderer.java diff --git a/runelite-client/src/main/java/com/openosrs/client/graphics/ModelOutlineRenderer.java b/runelite-client/src/main/java/com/openosrs/client/graphics/ModelOutlineRenderer.java new file mode 100644 index 0000000000..5e2f10445f --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/graphics/ModelOutlineRenderer.java @@ -0,0 +1,1113 @@ +/* + * Copyright (c) 2018, Woox + * 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 com.openosrs.client.graphics; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import lombok.RequiredArgsConstructor; +import lombok.Value; +import net.runelite.api.Client; +import net.runelite.api.DecorativeObject; +import net.runelite.api.GameObject; +import net.runelite.api.GroundObject; +import net.runelite.api.MainBufferProvider; +import net.runelite.api.Model; +import net.runelite.api.NPC; +import net.runelite.api.NPCComposition; +import net.runelite.api.Perspective; +import net.runelite.api.Player; +import net.runelite.api.ItemLayer; +import net.runelite.api.TileObject; +import net.runelite.api.WallObject; +import net.runelite.api.coords.LocalPoint; +import net.runelite.client.task.Schedule; + +@Singleton +public class ModelOutlineRenderer +{ + /* + * This class doesn't really "need" static variables, but they are + * static for performance reasons. Arrays are kept outside methods + * to avoid frequent big allocations. Arrays should mostly be seen + * as ArrayLists. The size of them is increased whenever they need + * to become bigger. + */ + + private final Client client; + + private boolean isReset; + private boolean usedSinceLastCheck; + + // Dimensions of the underlying image + private int imageWidth; + private int imageHeight; + + // Boundaries for the current rasterization + private int clipX1; + private int clipY1; + private int clipX2; + private int clipY2; + + // Pixel points that would be rendered to + private int[] visited; + private int currentVisitedNumber = 0; + + // Transformed vertex positions + private int[] projectedVerticesX; + private int[] projectedVerticesY; + private boolean[] projectedVerticesRenderable; + + // An array of pixel points to raster onto the image. These are checked against + // clip boundaries and the visited array to prevent drawing on top of the model + // and outside the scene area. They are grouped per distance to the closest pixel + // drawn on the model. + private int[][] outlinePixels; + private int[] outlinePixelsLengths; // outlinePixelsLength[i] is the used length of outlinePixels[i] + private int outlineArrayWidth; + + // A list of pixel distances ordered from shortest to longest distance for + // each outline width. These are calculated once upon first usage and then + // stored here to prevent reevaluation. + private List> precomputedDistancePriorities; + + @Inject + private ModelOutlineRenderer(Client client) + { + this.client = client; + + reset(); + } + + @Schedule(period = 5, unit = ChronoUnit.SECONDS) + public void checkUsage() + { + if (!isReset && !usedSinceLastCheck) + { + // Reset memory allocated when the rasterizer becomes inactive + reset(); + } + usedSinceLastCheck = false; + } + + /** + * Reset memory used by the rasterizer + */ + private void reset() + { + visited = new int[0]; + projectedVerticesX = new int[0]; + projectedVerticesY = new int[0]; + projectedVerticesRenderable = new boolean[0]; + outlinePixels = new int[0][]; + outlinePixelsLengths = new int[0]; + precomputedDistancePriorities = new ArrayList<>(0); + isReset = true; + } + + /** + * Calculate the next power of two of a value + * + * @param value The value to find the next power of two of + * @return Returns the next power of two + */ + private static int nextPowerOfTwo(int value) + { + value--; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value++; + return value; + } + + /** + * Determine if a triangle goes counter clockwise + * + * @return Returns true if the triangle goes counter clockwise and should be culled, otherwise false + */ + private static boolean cullFace(int x1, int y1, int x2, int y2, int x3, int y3) + { + return + (y2 - y1) * (x3 - x2) - + (x2 - x1) * (y3 - y2) < 0; + } + + /** + * Gets the list of pixel distances ordered by distance from closest pixel for a specific outline width. + * + * @param outlineWidth The outline width + * @return Returns the list of pixel distances + */ + private List getPriorityList(int outlineWidth) + { + while (precomputedDistancePriorities.size() <= outlineWidth) + { + precomputedDistancePriorities.add(null); + } + + // Grab the cached outline width if we have one + if (precomputedDistancePriorities.get(outlineWidth) != null) + { + return precomputedDistancePriorities.get(outlineWidth); + } + + List ps = new ArrayList<>(); + for (int x = 0; x <= outlineWidth; x++) + { + for (int y = 0; y <= outlineWidth; y++) + { + if (x == 0 && y == 0) + { + continue; + } + + double dist = Math.sqrt(x * x + y * y); + if (dist > outlineWidth) + { + continue; + } + + int outerAlpha = outlineWidth == 1 ? 255 // For preventing division by 0 + : (int) (255 * (dist - 1) / (outlineWidth - 1)); + ps.add(new PixelDistanceAlpha(outerAlpha, x + y * outlineArrayWidth)); + } + } + ps.sort(Comparator.comparingDouble(PixelDistanceAlpha::getOuterAlpha)); + precomputedDistancePriorities.set(outlineWidth, ps); + + return ps; + } + + /** + * Checks that the size of outlinePixels is big enough to hold a specific + * amount of elements. This is used to reduce the amount of if checks needed + * when adding elements to outlinePixels. + * + * @param distArrayPos The position in the array + * @param additionalMinimumSize The additional minimum size required + */ + private void ensureMinimumOutlineQueueSize(int distArrayPos, int additionalMinimumSize) + { + int minimumSize = outlinePixelsLengths[distArrayPos] + additionalMinimumSize; + while (outlinePixels[distArrayPos].length < minimumSize) + { + int[] newArr = new int[nextPowerOfTwo(minimumSize)]; + System.arraycopy(outlinePixels[distArrayPos], 0, newArr, 0, + outlinePixels[distArrayPos].length); + outlinePixels[distArrayPos] = newArr; + } + } + + /** + * Resets the visited flag for a specific amount of pixels + * + * @param pixelAmount The amount of pixels to reset + */ + private void resetVisited(int pixelAmount) + { + // The visited array is essentially a boolean array, but by + // making it an int array and checking if visited[i] == currentVisitedNumber + // and changing currentVisitedNumber for every new outline, we can essentially + // reset the whole array without having to iterate over every element + + if (visited.length < pixelAmount) + { + visited = new int[nextPowerOfTwo(pixelAmount)]; + currentVisitedNumber = 0; + } + + currentVisitedNumber++; + } + + /** + * Resets the pixels that are queued for outlining + * + * @param outlineWidth The width of the outline to reset pixels for + */ + private void resetOutline(int outlineWidth) + { + outlineArrayWidth = outlineWidth + 2; + + int arraySizes = outlineArrayWidth * outlineArrayWidth; + if (outlinePixels.length < arraySizes) + { + outlinePixels = new int[arraySizes][]; + outlinePixelsLengths = new int[arraySizes]; + for (int i = 0; i < arraySizes; i++) + { + outlinePixels[i] = new int[4]; + } + } + else + { + for (int i = 0; i < arraySizes; i++) + { + outlinePixelsLengths[i] = 0; + } + } + } + + /** + * Simulates a horizontal line rasterization and adds the pixels to the left + * and to the right to the outline queue if they are within the clip area. + * + * @param pixelPos The pixel position in the line where x == 0 + * @param x1 The starting x position + * @param x2 The ending x position + */ + private void simulateHorizontalLineRasterizationForOutline(int pixelPos, int x1, int x2) + { + if (x2 > clipX2) + { + x2 = clipX2; + } + if (x1 < clipX1) + { + x1 = clipX1; + } + if (x1 >= x2) + { + return; + } + + // Queue the pixel positions to the left and to the right of the line + ensureMinimumOutlineQueueSize(1, 2); + if (x2 < clipX2) + { + outlinePixels[1][outlinePixelsLengths[1]++] = pixelPos + x2; + } + if (x1 > clipX1) + { + outlinePixels[1][outlinePixelsLengths[1]++] = pixelPos + x1 - 1; + } + + // Divide by 4 to account for loop unrolling + int xDist = x2 - x1 >> 2; + pixelPos += x1; + + // This loop could run over 100m times per second without loop unrolling in some cases, + // so unrolling it can give a noticeable performance boost. + while (xDist-- > 0) + { + visited[pixelPos++] = currentVisitedNumber; + visited[pixelPos++] = currentVisitedNumber; + visited[pixelPos++] = currentVisitedNumber; + visited[pixelPos++] = currentVisitedNumber; + } + + // Draw up to 3 more pixels if there were any left + xDist = (x2 - x1) & 3; + while (xDist-- > 0) + { + visited[pixelPos++] = currentVisitedNumber; + } + } + + /** + * Queues the pixel positions above and below two horizontal lines, excluding those + * where the x positions of the lines intersect. + * + * @param pixelPos The pixel position at x == 0 of the second line + * @param x1 The starting x position of the first line + * @param x2 The ending x position of the first line + * @param x3 The starting x position of the second line + * @param x4 The ending x position of the second line + */ + private void outlineAroundHorizontalLine(int pixelPos, int x1, int x2, int x3, int x4) + { + if (x1 < clipX1) + { + x1 = clipX1; + } + if (x2 < clipX1) + { + x2 = clipX1; + } + if (x3 < clipX1) + { + x3 = clipX1; + } + if (x4 < clipX1) + { + x4 = clipX1; + } + + if (x1 > clipX2) + { + x1 = clipX2; + } + if (x2 > clipX2) + { + x2 = clipX2; + } + if (x3 > clipX2) + { + x3 = clipX2; + } + if (x4 > clipX2) + { + x4 = clipX2; + } + + if (x1 < x3) + { + ensureMinimumOutlineQueueSize(outlineArrayWidth, x3 - x1); + for (int x = x1; x < x3; x++) + { + outlinePixels[outlineArrayWidth][outlinePixelsLengths[outlineArrayWidth]++] = pixelPos - imageWidth + x; + } + } + else + { + ensureMinimumOutlineQueueSize(outlineArrayWidth, x1 - x3); + for (int x = x3; x < x1; x++) + { + outlinePixels[outlineArrayWidth][outlinePixelsLengths[outlineArrayWidth]++] = pixelPos + x; + } + } + + if (x2 < x4) + { + ensureMinimumOutlineQueueSize(outlineArrayWidth, x4 - x2); + for (int x = x2; x < x4; x++) + { + outlinePixels[outlineArrayWidth][outlinePixelsLengths[outlineArrayWidth]++] = pixelPos + x; + } + } + else + { + ensureMinimumOutlineQueueSize(outlineArrayWidth, x2 - x4); + for (int x = x4; x < x2; x++) + { + outlinePixels[outlineArrayWidth][outlinePixelsLengths[outlineArrayWidth]++] = pixelPos - imageWidth + x; + } + } + } + + /** + * Simulates rasterization of a triangle and adds every pixel outside the triangle + * to the outline queue. + * + * @param x1 The x position of the first vertex in the triangle + * @param y1 The y position of the first vertex in the triangle + * @param x2 The x position of the second vertex in the triangle + * @param y2 The y position of the second vertex in the triangle + * @param x3 The x position of the third vertex in the triangle + * @param y3 The y position of the third vertex in the triangle + */ + private void simulateTriangleRasterizationForOutline(int x1, int y1, int x2, int y2, int x3, int y3) + { + // Swap vertices so y1 <= y2 <= y3 using bubble sort + if (y1 > y2) + { + int yp = y1; + int xp = x1; + y1 = y2; + y2 = yp; + x1 = x2; + x2 = xp; + } + if (y2 > y3) + { + int yp = y2; + int xp = x2; + y2 = y3; + y3 = yp; + x2 = x3; + x3 = xp; + } + if (y1 > y2) + { + int yp = y1; + int xp = x1; + y1 = y2; + y2 = yp; + x1 = x2; + x2 = xp; + } + + if (y1 > clipY2) + { + // All points are outside clip boundaries + return; + } + + int slope1 = 0; + if (y1 != y2) + { + slope1 = (x2 - x1 << 14) / (y2 - y1); + } + + int slope2 = 0; + if (y3 != y2) + { + slope2 = (x3 - x2 << 14) / (y3 - y2); + } + + int slope3 = 0; + if (y1 != y3) + { + slope3 = (x1 - x3 << 14) / (y1 - y3); + } + + if (y2 > clipY2) + { + y2 = clipY2; + } + if (y3 > clipY2) + { + y3 = clipY2; + } + if (y1 == y3 || y3 < 0) + { + return; + } + + x1 <<= 14; + x2 <<= 14; + x3 = x1; + + if (y1 < 0) + { + x3 -= y1 * slope3; + x1 -= y1 * slope1; + y1 = 0; + } + if (y2 < 0) + { + x2 -= slope2 * y2; + y2 = 0; + } + + int pixelPos = y1 * imageWidth; + int currX1; + int currX2; + if (y1 != y2 && slope3 < slope1 || y1 == y2 && slope3 > slope2) + { + int height1 = y2 - y1; + int height2 = y3 - y2; + + int prevX1; + int prevX2; + if (height1 <= 0) + { + prevX1 = x3 >> 14; + prevX2 = x2 >> 14; + } + else + { + prevX1 = x3 >> 14; + prevX2 = x1 >> 14; + } + + outlineAroundHorizontalLine(pixelPos, prevX1, prevX2, prevX2, prevX2); + + while (height1-- > 0) + { + currX1 = x3 >> 14; + currX2 = x1 >> 14; + outlineAroundHorizontalLine(pixelPos, currX1, currX2, prevX1, prevX2); + simulateHorizontalLineRasterizationForOutline(pixelPos, currX1, currX2); + x3 += slope3; + x1 += slope1; + pixelPos += imageWidth; + prevX1 = currX1; + prevX2 = currX2; + } + + while (height2-- > 0) + { + currX1 = x3 >> 14; + currX2 = x2 >> 14; + outlineAroundHorizontalLine(pixelPos, currX1, currX2, prevX1, prevX2); + simulateHorizontalLineRasterizationForOutline(pixelPos, currX1, currX2); + x3 += slope3; + x2 += slope2; + pixelPos += imageWidth; + prevX1 = currX1; + prevX2 = currX2; + } + + outlineAroundHorizontalLine(pixelPos, prevX1, prevX1, prevX1, prevX2); + } + else + { + int height1 = y2 - y1; + int height2 = y3 - y2; + + int prevX1; + int prevX2; + if (height1 <= 0) + { + prevX1 = x2 >> 14; + prevX2 = x3 >> 14; + } + else + { + prevX1 = x1 >> 14; + prevX2 = x3 >> 14; + } + + outlineAroundHorizontalLine(pixelPos, prevX1, prevX2, prevX2, prevX2); + + while (height1-- > 0) + { + currX1 = x1 >> 14; + currX2 = x3 >> 14; + outlineAroundHorizontalLine(pixelPos, currX1, currX2, prevX1, prevX2); + simulateHorizontalLineRasterizationForOutline(pixelPos, currX1, currX2); + x1 += slope1; + x3 += slope3; + pixelPos += imageWidth; + prevX1 = currX1; + prevX2 = currX2; + } + + while (height2-- > 0) + { + currX1 = x2 >> 14; + currX2 = x3 >> 14; + outlineAroundHorizontalLine(pixelPos, currX1, currX2, prevX1, prevX2); + simulateHorizontalLineRasterizationForOutline(pixelPos, currX1, currX2); + x3 += slope3; + x2 += slope2; + pixelPos += imageWidth; + prevX1 = currX1; + prevX2 = currX2; + } + + outlineAroundHorizontalLine(pixelPos, prevX1, prevX1, prevX1, prevX2); + } + } + + /** + * Translates the vertices 3D points to the screen canvas 2D points + * + * @param localX The local x position of the vertices + * @param localY The local y position of the vertices + * @param localZ The local z position of the vertices + * @param vertexOrientation The orientation of the vertices + * @return Returns true if any of them are inside the clip area, otherwise false + */ + private boolean projectVertices(Model model, final int localX, final int localY, final int localZ, final int vertexOrientation) + { + final int cameraX = client.getCameraX(); + final int cameraY = client.getCameraY(); + final int cameraZ = client.getCameraZ(); + final int cameraYaw = client.getCameraYaw(); + final int cameraPitch = client.getCameraPitch(); + final int scale = client.getScale(); + final int orientationSin = Perspective.SINE[vertexOrientation]; + final int orientationCos = Perspective.COSINE[vertexOrientation]; + final int pitchSin = Perspective.SINE[cameraPitch]; + final int pitchCos = Perspective.COSINE[cameraPitch]; + final int yawSin = Perspective.SINE[cameraYaw]; + final int yawCos = Perspective.COSINE[cameraYaw]; + final int vertexCount = model.getVerticesCount(); + final int[] verticesX = model.getVerticesX(); + final int[] verticesY = model.getVerticesY(); + final int[] verticesZ = model.getVerticesZ(); + + boolean anyVisible = false; + + // Make sure the arrays are big enough + while (projectedVerticesX.length < vertexCount) + { + int newSize = nextPowerOfTwo(vertexCount); + projectedVerticesX = new int[newSize]; + projectedVerticesY = new int[newSize]; + projectedVerticesRenderable = new boolean[newSize]; + } + + for (int i = 0; i < vertexCount; i++) + { + int vx = verticesX[i]; + int vy = verticesZ[i]; + int vz = verticesY[i]; + int vh; // Value holder + + // Rotate based on orientation + vh = vx * orientationCos + vy * orientationSin >> 16; + vy = vy * orientationCos - vx * orientationSin >> 16; + vx = vh; + + // Translate to local coords + vx += localX; + vy += localY; + vz += localZ; + + // Translate to camera + vx -= cameraX; + vy -= cameraY; + vz -= cameraZ; + + // Transform to canvas + vh = vx * yawCos + vy * yawSin >> 16; + vy = vy * yawCos - vx * yawSin >> 16; + vx = vh; + vh = vz * pitchCos - vy * pitchSin >> 16; + vz = vz * pitchSin + vy * pitchCos >> 16; + vy = vh; + + if (vz >= 50) + { + projectedVerticesX[i] = (clipX1 + clipX2) / 2 + vx * scale / vz; + projectedVerticesY[i] = (clipY1 + clipY2) / 2 + vy * scale / vz; + + projectedVerticesRenderable[i] = true; + anyVisible |= + projectedVerticesX[i] >= clipX1 && projectedVerticesX[i] < clipX2 && + projectedVerticesY[i] >= clipY1 && projectedVerticesY[i] < clipY2; + } + else + { + projectedVerticesRenderable[i] = false; + } + } + + return anyVisible; + } + + /** + * Simulate rendering of the model and puts every pixel of the wireframe of + * the non-culled and non-transparent faces into the outline pixel queue. + */ + private void simulateModelRasterizationForOutline(Model model) + { + final int triangleCount = model.getTrianglesCount(); + final int[] indices1 = model.getTrianglesX(); + final int[] indices2 = model.getTrianglesY(); + final int[] indices3 = model.getTrianglesZ(); + final byte[] triangleTransparencies = model.getTriangleTransparencies(); + + for (int i = 0; i < triangleCount; i++) + { + if (projectedVerticesRenderable[indices1[i]] && + projectedVerticesRenderable[indices2[i]] && + projectedVerticesRenderable[indices3[i]] && + // 254 and 255 counts as fully transparent + (triangleTransparencies == null || (triangleTransparencies[i] & 255) < 254)) + { + final int index1 = indices1[i]; + final int index2 = indices2[i]; + final int index3 = indices3[i]; + final int v1x = projectedVerticesX[index1]; + final int v1y = projectedVerticesY[index1]; + final int v2x = projectedVerticesX[index2]; + final int v2y = projectedVerticesY[index2]; + final int v3x = projectedVerticesX[index3]; + final int v3y = projectedVerticesY[index3]; + + if (!cullFace(v1x, v1y, v2x, v2y, v3x, v3y)) + { + simulateTriangleRasterizationForOutline( + v1x, v1y, v2x, v2y, v3x, v3y); + } + } + } + } + + /** + * Draws an outline of the pixels in the outline queue to an image + * + * @param image The image to draw the outline to + * @param outlineWidth The width of the outline + * @param innerColor The color of the pixels of the outline closest to the model + * @param outerColor The color of the pixels of the outline furthest away from the model + */ + private void renderOutline(BufferedImage image, int outlineWidth, Color innerColor, Color outerColor) + { + int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); + List ps = getPriorityList(outlineWidth); + + for (PixelDistanceAlpha p : ps) + { + int color; + int alpha; + if (outlineWidth == 1) + { + color = + ((innerColor.getRed() + outerColor.getRed()) << 15) | + ((innerColor.getGreen() + outerColor.getGreen() << 7)) | + ((innerColor.getBlue() + outerColor.getBlue() >> 1)); + alpha = (innerColor.getAlpha() + outerColor.getAlpha()) >> 1; + } + else + { + int outerAlpha = p.getOuterAlpha(); + int innerAlpha = 255 - outerAlpha; + int innerAlphaFraction = (innerAlpha * innerColor.getAlpha()) / 255; + int outerAlphaFraction = (outerAlpha * outerColor.getAlpha()) / 255; + alpha = innerAlphaFraction + outerAlphaFraction; + if (alpha != 0) + { + color = + ((innerColor.getRed() * innerAlphaFraction + + outerColor.getRed() * outerAlphaFraction) / alpha << 16) | + ((innerColor.getGreen() * innerAlphaFraction + + outerColor.getGreen() * outerAlphaFraction) / alpha << 8) | + ((innerColor.getBlue() * innerAlphaFraction + + outerColor.getBlue() * outerAlphaFraction) / alpha); + } + else + { + color = 0; + } + } + + final int distArrayPos = p.getDistArrayPos(); + final int nextDistArrayPosY = distArrayPos + outlineArrayWidth; + final int nextDistArrayPosX = distArrayPos + 1; + ensureMinimumOutlineQueueSize(nextDistArrayPosX, outlinePixelsLengths[distArrayPos] * 2); + ensureMinimumOutlineQueueSize(nextDistArrayPosY, outlinePixelsLengths[distArrayPos] * 2); + + // The following 3 branches do the same thing, but when the requirements are simple, + // there are less checks needed which can give a performance boost. + if (alpha == 255) + { + if (outlineWidth == 1) + { + for (int i2 = 0; i2 < outlinePixelsLengths[distArrayPos]; i2++) + { + int pixelPos = outlinePixels[distArrayPos][i2]; + int x = pixelPos % imageWidth; + int y = pixelPos / imageWidth; + if (x < clipX1 || x >= clipX2 || + y < clipY1 || y >= clipY2 || + visited[pixelPos] == currentVisitedNumber) + { + continue; + } + + imageData[pixelPos] = color; + } + } + else + { + for (int i2 = 0; i2 < outlinePixelsLengths[distArrayPos]; i2++) + { + int pixelPos = outlinePixels[distArrayPos][i2]; + int x = pixelPos % imageWidth; + int y = pixelPos / imageWidth; + if (x < clipX1 || x >= clipX2 || + y < clipY1 || y >= clipY2 || + visited[pixelPos] == currentVisitedNumber) + { + continue; + } + visited[pixelPos] = currentVisitedNumber; + + imageData[pixelPos] = color; + + if (pixelPos % imageWidth != 0) + { + outlinePixels[nextDistArrayPosX][outlinePixelsLengths[nextDistArrayPosX]++] = pixelPos - 1; + } + if ((pixelPos + 1) % imageWidth != 0) + { + outlinePixels[nextDistArrayPosX][outlinePixelsLengths[nextDistArrayPosX]++] = pixelPos + 1; + } + outlinePixels[nextDistArrayPosY][outlinePixelsLengths[nextDistArrayPosY]++] = pixelPos - imageWidth; + outlinePixels[nextDistArrayPosY][outlinePixelsLengths[nextDistArrayPosY]++] = pixelPos + imageWidth; + } + } + } + else + { + for (int i2 = 0; i2 < outlinePixelsLengths[distArrayPos]; i2++) + { + int pixelPos = outlinePixels[distArrayPos][i2]; + int x = pixelPos % imageWidth; + int y = pixelPos / imageWidth; + if (x < clipX1 || x >= clipX2 || + y < clipY1 || y >= clipY2 || + visited[pixelPos] == currentVisitedNumber) + { + continue; + } + visited[pixelPos] = currentVisitedNumber; + + imageData[pixelPos] = + ((((color & 0xFF0000) * alpha + (imageData[pixelPos] & 0xFF0000) * (255 - alpha)) / 255) & 0xFF0000) + + ((((color & 0xFF00) * alpha + (imageData[pixelPos] & 0xFF00) * (255 - alpha)) / 255) & 0xFF00) + + ((((color & 0xFF) * alpha + (imageData[pixelPos] & 0xFF) * (255 - alpha)) / 255) & 0xFF); + + if (pixelPos % imageWidth != 0) + { + outlinePixels[nextDistArrayPosX][outlinePixelsLengths[nextDistArrayPosX]++] = pixelPos - 1; + } + if ((pixelPos + 1) % imageWidth != 0) + { + outlinePixels[nextDistArrayPosX][outlinePixelsLengths[nextDistArrayPosX]++] = pixelPos + 1; + } + outlinePixels[nextDistArrayPosY][outlinePixelsLengths[nextDistArrayPosY]++] = pixelPos - imageWidth; + outlinePixels[nextDistArrayPosY][outlinePixelsLengths[nextDistArrayPosY]++] = pixelPos + imageWidth; + } + } + } + } + + /** + * Draws an outline around a model to an image + * + * @param localX The local x position of the model + * @param localY The local y position of the model + * @param localZ The local z position of the model + * @param orientation The orientation of the model + * @param outlineWidth The width of the outline + * @param innerColor The color of the pixels of the outline closest to the model + * @param outerColor The color of the pixels of the outline furthest away from the model + */ + private void drawModelOutline(Model model, int localX, int localY, int localZ, int orientation, int outlineWidth, Color innerColor, Color outerColor) + { + if (outlineWidth <= 0) + { + return; + } + + isReset = false; + usedSinceLastCheck = true; + + MainBufferProvider bufferProvider = (MainBufferProvider) client.getBufferProvider(); + BufferedImage image = (BufferedImage) bufferProvider.getImage(); + + clipX1 = client.getViewportXOffset(); + clipY1 = client.getViewportYOffset(); + clipX2 = client.getViewportWidth() + clipX1; + clipY2 = client.getViewportHeight() + clipY1; + imageWidth = image.getWidth(); + imageHeight = image.getHeight(); + final int pixelAmount = imageWidth * imageHeight; + + resetVisited(pixelAmount); + resetOutline(outlineWidth); + + if (!projectVertices(model, + localX, localY, localZ, orientation)) + { + // No vertex of the model is visible on the screen, so we can + // assume there are no parts of the model to outline. + return; + } + + simulateModelRasterizationForOutline(model); + + renderOutline(image, outlineWidth, innerColor, outerColor); + } + + public void drawOutline(NPC npc, int outlineWidth, Color color) + { + drawOutline(npc, outlineWidth, color, color); + } + + public void drawOutline(NPC npc, int outlineWidth, Color innerColor, Color outerColor) + { + int size = 1; + NPCComposition composition = npc.getTransformedComposition(); + if (composition != null) + { + size = composition.getSize(); + } + + LocalPoint lp = npc.getLocalLocation(); + if (lp != null) + { + // NPCs z position are calculated based on the tile height of the northeastern tile + final int northEastX = lp.getX() + Perspective.LOCAL_TILE_SIZE * (size - 1) / 2; + final int northEastY = lp.getY() + Perspective.LOCAL_TILE_SIZE * (size - 1) / 2; + final LocalPoint northEastLp = new LocalPoint(northEastX, northEastY); + + drawModelOutline(npc.getModel(), lp.getX(), lp.getY(), + Perspective.getTileHeight(client, northEastLp, client.getPlane()), + npc.getCurrentOrientation(), outlineWidth, innerColor, outerColor); + } + } + + public void drawOutline(Player player, int outlineWidth, Color color) + { + drawOutline(player, outlineWidth, color, color); + } + + public void drawOutline(Player player, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = player.getLocalLocation(); + if (lp != null) + { + drawModelOutline(player.getModel(), lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, client.getPlane()), + player.getCurrentOrientation(), outlineWidth, innerColor, outerColor); + } + } + + public void drawOutline(GameObject gameObject, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = gameObject.getLocalLocation(); + if (lp != null) + { + drawModelOutline(gameObject.getModel(), lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, gameObject.getPlane()), + gameObject.getRsOrientation(), outlineWidth, innerColor, outerColor); + } + } + + public void drawOutline(GroundObject groundObject, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = groundObject.getLocalLocation(); + if (lp != null) + { + drawModelOutline(groundObject.getModel(), lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, client.getPlane()), + 0, outlineWidth, innerColor, outerColor); + } + } + + private void drawOutline(ItemLayer tileItemPile, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = tileItemPile.getLocalLocation(); + if (lp != null) + { + Model model = tileItemPile.getModelBottom(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, tileItemPile.getPlane()), + 0, outlineWidth, innerColor, outerColor); + } + + model = tileItemPile.getModelMiddle(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, tileItemPile.getPlane()), + 0, outlineWidth, innerColor, outerColor); + } + + model = tileItemPile.getModelTop(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, tileItemPile.getPlane()), + 0, outlineWidth, innerColor, outerColor); + } + } + } + + private void drawOutline(DecorativeObject decorativeObject, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = decorativeObject.getLocalLocation(); + if (lp != null) + { + Model model = decorativeObject.getModel1(); + if (model != null) + { + drawModelOutline(model, + lp.getX() + decorativeObject.getXOffset(), + lp.getY() + decorativeObject.getYOffset(), + Perspective.getTileHeight(client, lp, decorativeObject.getPlane()), + decorativeObject.getOrientation(), outlineWidth, innerColor, outerColor); + } + + model = decorativeObject.getModel2(); + if (model != null) + { + // Offset is not used for the second model + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, decorativeObject.getPlane()), + decorativeObject.getOrientation(), outlineWidth, innerColor, outerColor); + } + } + } + + private void drawOutline(WallObject wallObject, int outlineWidth, Color innerColor, Color outerColor) + { + LocalPoint lp = wallObject.getLocalLocation(); + if (lp != null) + { + Model model = wallObject.getModelA(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, wallObject.getPlane()), + wallObject.getOrientationA(), outlineWidth, innerColor, outerColor); + } + + model = wallObject.getModelB(); + if (model != null) + { + drawModelOutline(model, lp.getX(), lp.getY(), + Perspective.getTileHeight(client, lp, wallObject.getPlane()), + wallObject.getOrientationB(), outlineWidth, innerColor, outerColor); + } + } + } + + public void drawOutline(TileObject tileObject, int outlineWidth, Color color) + { + drawOutline(tileObject, outlineWidth, color, color); + } + + public void drawOutline(TileObject tileObject, + int outlineWidth, Color innerColor, Color outerColor) + { + if (tileObject instanceof GameObject) + { + drawOutline((GameObject) tileObject, outlineWidth, innerColor, outerColor); + } + else if (tileObject instanceof GroundObject) + { + drawOutline((GroundObject) tileObject, outlineWidth, innerColor, outerColor); + } + else if (tileObject instanceof ItemLayer) + { + drawOutline((ItemLayer) tileObject, outlineWidth, innerColor, outerColor); + } + else if (tileObject instanceof DecorativeObject) + { + drawOutline((DecorativeObject) tileObject, outlineWidth, innerColor, outerColor); + } + else if (tileObject instanceof WallObject) + { + drawOutline((WallObject) tileObject, outlineWidth, innerColor, outerColor); + } + } + + @Value + @RequiredArgsConstructor + class PixelDistanceAlpha + { + private final int outerAlpha; + private final int distArrayPos; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java index 06fd875d6d..0b21683877 100644 --- a/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java @@ -1,13 +1,14 @@ package com.openosrs.client.ui.overlay; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.Polygon; -import net.runelite.api.Client; -import net.runelite.api.Perspective; + +import net.runelite.api.*; +import net.runelite.api.Point; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.vars.InterfaceTab; +import net.runelite.api.widgets.Widget; + +import java.awt.*; public class OverlayUtil extends net.runelite.client.ui.overlay.OverlayUtil { @@ -39,4 +40,45 @@ public class OverlayUtil extends net.runelite.client.ui.overlay.OverlayUtil graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); graphics.fill(poly); } + + public static Rectangle renderPrayerOverlay(Graphics2D graphics, Client client, Prayer prayer, Color color) + { + Widget widget = client.getWidget(prayer.getWidgetInfo()); + + if (widget == null || client.getVar(VarClientInt.INVENTORY_TAB) != InterfaceTab.PRAYER.getId()) + { + return null; + } + + Rectangle bounds = widget.getBounds(); + renderPolygon(graphics, rectangleToPolygon(bounds), color); + return bounds; + } + + private static Polygon rectangleToPolygon(Rectangle rect) + { + int[] xpoints = {rect.x, rect.x + rect.width, rect.x + rect.width, rect.x}; + int[] ypoints = {rect.y, rect.y, rect.y + rect.height, rect.y + rect.height}; + + return new Polygon(xpoints, ypoints, 4); + } + + public static void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint, boolean shadows, int yOffset) + { + graphics.setFont(new Font("Arial", fontStyle, fontSize)); + if (canvasPoint != null) + { + final Point canvasCenterPoint = new Point( + canvasPoint.getX(), + canvasPoint.getY() + yOffset); + final Point canvasCenterPoint_shadow = new Point( + canvasPoint.getX() + 1, + canvasPoint.getY() + 1 + yOffset); + if (shadows) + { + renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); + } + renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); + } + } } diff --git a/runelite-client/src/main/java/com/openosrs/client/util/ImageUtil.java b/runelite-client/src/main/java/com/openosrs/client/util/ImageUtil.java index 3282e61c98..599eff1ac4 100644 --- a/runelite-client/src/main/java/com/openosrs/client/util/ImageUtil.java +++ b/runelite-client/src/main/java/com/openosrs/client/util/ImageUtil.java @@ -1,8 +1,12 @@ package com.openosrs.client.util; +import net.runelite.api.Client; +import net.runelite.api.SpritePixels; + import java.awt.Color; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; +import java.util.Arrays; import java.util.function.Predicate; public class ImageUtil extends net.runelite.client.util.ImageUtil @@ -56,4 +60,134 @@ public class ImageUtil extends net.runelite.client.util.ImageUtil } return image; } + + /** + * Draw fg centered on top of bg + */ + public static SpritePixels mergeSprites(final Client client, final SpritePixels bg, final SpritePixels fg) + { + assert fg.getHeight() <= bg.getHeight() && fg.getWidth() <= bg.getWidth() : "Background has to be larger than foreground"; + + final int[] canvas = Arrays.copyOf(bg.getPixels(), bg.getWidth() * bg.getHeight()); + final SpritePixels result = client.createSpritePixels(canvas, bg.getWidth(), bg.getHeight()); + + final int bgWid = bg.getWidth(); + final int fgHgt = fg.getHeight(); + final int fgWid = fg.getWidth(); + + final int xOffset = (bgWid - fgWid) / 2; + final int yOffset = (bg.getHeight() - fgHgt) / 2; + + final int[] fgPixels = fg.getPixels(); + + for (int y1 = yOffset, y2 = 0; y2 < fgHgt; y1++, y2++) + { + int i1 = y1 * bgWid + xOffset; + int i2 = y2 * fgWid; + + for (int x = 0; x < fgWid; x++, i1++, i2++) + { + if (fgPixels[i2] > 0) + { + canvas[i1] = fgPixels[i2]; + } + } + } + + return result; + } + + /** + * Resize Sprite sprite to given width (newW) and height (newH) + */ + public static SpritePixels resizeSprite(final Client client, final SpritePixels sprite, int newW, int newH) + { + assert newW > 0 && newH > 0; + + final int oldW = sprite.getWidth(); + final int oldH = sprite.getHeight(); + + if (oldW == newW && oldH == newH) + { + return sprite; + } + + final int[] canvas = new int[newW * newH]; + final int[] pixels = sprite.getPixels(); + + final SpritePixels result = client.createSpritePixels(canvas, newW, newH); + + int pixelX = 0; + int pixelY = 0; + + final int oldMaxW = sprite.getMaxWidth(); + final int oldMaxH = sprite.getMaxHeight(); + + final int pixelW = (oldMaxW << 16) / newW; + final int pixelH = (oldMaxH << 16) / newH; + + int xOffset = 0; + int yOffset = 0; + + int canvasIdx; + if (sprite.getOffsetX() > 0) + { + canvasIdx = (pixelW + (sprite.getOffsetX() << 16) - 1) / pixelW; + xOffset += canvasIdx; + pixelX += canvasIdx * pixelW - (sprite.getOffsetX() << 16); + } + + if (sprite.getOffsetY() > 0) + { + canvasIdx = (pixelH + (sprite.getOffsetY() << 16) - 1) / pixelH; + yOffset += canvasIdx; + pixelY += canvasIdx * pixelH - (sprite.getOffsetY() << 16); + } + + if (oldW < oldMaxW) + { + newW = (pixelW + ((oldW << 16) - pixelX) - 1) / pixelW; + } + + if (oldH < oldMaxH) + { + newH = (pixelH + ((oldH << 16) - pixelY) - 1) / pixelH; + } + + canvasIdx = xOffset + yOffset * newW; + int canvasOffset = 0; + if (yOffset + newH > newH) + { + newH -= yOffset + newH - newH; + } + + int tmp; + if (yOffset < 0) + { + tmp = -yOffset; + newH -= tmp; + canvasIdx += tmp * newW; + pixelY += pixelH * tmp; + } + + if (newW + xOffset > newW) + { + tmp = newW + xOffset - newW; + newW -= tmp; + canvasOffset += tmp; + } + + if (xOffset < 0) + { + tmp = -xOffset; + newW -= tmp; + canvasIdx += tmp; + pixelX += pixelW * tmp; + canvasOffset += tmp; + } + + client.scaleSprite(canvas, pixels, 0, pixelX, pixelY, canvasIdx, canvasOffset, newW, newH, pixelW, pixelH, oldW); + + return result; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java index a9a511cc08..dfebdb618c 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java @@ -24,6 +24,8 @@ */ package net.runelite.client.config; +import com.openosrs.client.OpenOSRS; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -48,4 +50,10 @@ public @interface ConfigItem boolean secret() default false; String section() default ""; + + /* + OpenOSRS Lazy Helpers tm + */ + Class enumClass() default OpenOSRS.class; + String unhide() default ""; } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java index 4a0f722d3f..6e7b905379 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java @@ -24,6 +24,8 @@ */ package net.runelite.client.config; +import com.openosrs.client.OpenOSRS; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -40,4 +42,9 @@ public @interface ConfigSection int position(); boolean closedByDefault() default false; + + /* + OpenOSRS Lazy Helpers tm + */ + String keyName() default ""; } diff --git a/runelite-client/src/main/java/net/runelite/client/config/Units.java b/runelite-client/src/main/java/net/runelite/client/config/Units.java index 45d54df164..ca872bfa80 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/Units.java +++ b/runelite-client/src/main/java/net/runelite/client/config/Units.java @@ -42,8 +42,12 @@ public @interface Units String MINUTES = " mins"; String PERCENT = "%"; String PIXELS = "px"; + String POINTS = "pt"; String SECONDS = "s"; String TICKS = " ticks"; + String LEVELS = " lvls"; + String FPS = " fps"; + String GP = " GP"; String value(); } From c68e4b2a479ac3f2e19b00a7a279baa545d5edcc Mon Sep 17 00:00:00 2001 From: zeruth Date: Mon, 25 Jan 2021 15:18:43 -0500 Subject: [PATCH 11/53] api: develop --- .../main/java/net/runelite/api/Varbits.java | 291 +++++- .../java/com/openosrs/client/game/Sound.java | 42 + .../openosrs/client/game/SoundManager.java | 95 ++ .../openosrs/client/game/WorldLocation.java | 906 ++++++++++++++++++ .../client/ui/overlay/OverlayUtil.java | 59 +- .../com/openosrs/client/util/PvPUtil.java | 135 +++ .../com/openosrs/client/util/WeaponMap.java | 832 ++++++++++++++++ .../com/openosrs/client/util/WeaponStyle.java | 6 + .../runelite/client/config/ConfigItem.java | 1 + .../runelite/client/config/ConfigSection.java | 3 + 10 files changed, 2364 insertions(+), 6 deletions(-) create mode 100644 runelite-client/src/main/java/com/openosrs/client/game/Sound.java create mode 100644 runelite-client/src/main/java/com/openosrs/client/game/SoundManager.java create mode 100644 runelite-client/src/main/java/com/openosrs/client/game/WorldLocation.java create mode 100644 runelite-client/src/main/java/com/openosrs/client/util/PvPUtil.java create mode 100644 runelite-client/src/main/java/com/openosrs/client/util/WeaponMap.java create mode 100644 runelite-client/src/main/java/com/openosrs/client/util/WeaponStyle.java diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index 418c56bb6c..32b000971e 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -286,7 +286,7 @@ public enum Varbits TITHE_FARM_SACK_AMOUNT(4900), TITHE_FARM_SACK_ICON(5370), TITHE_FARM_POINTS(4893), - + /** * Blast Mine */ @@ -410,7 +410,7 @@ public enum Varbits /** * This varbit tracks how much bonemeal has been redeemed from Robin * The player gets 13 for each diary completed above and including Medium, for a maxiumum of 39 - */ + */ DAILY_BONEMEAL_STATE(4543), DAILY_DYNAMITE_COLLECTED(7939), @@ -560,7 +560,7 @@ public enum Varbits EXPLORER_RING_ALCHS(4554), EXPLORER_RING_RUNENERGY(4553), - WINTERTODT_TIMER(7980), + /** * League relics @@ -596,10 +596,291 @@ public enum Varbits * * @see The OSRS Wiki's Minimap page */ - PVP_SPEC_ORB(8121); + PVP_SPEC_ORB(8121), + + //OPENOSRS + + /** + * Grand Exchange + */ + GRAND_EXCHANGE_PRICE_PER_ITEM(4398), + + /* + * Kharedst's Memoirs Teleport Item + */ + KHAREDSTS_MEMOIRS_CHARGES(6035), + + LMS_POISON_PROGRESS(5317), + + /** + * The y coordinate of the final safespace (world coord) + */ + LMS_SAFE_Y(5320), + + /** + * 1 is true, 0 is false. + */ + GAUNTLET_FINAL_ROOM_ENTERED(9177), + + /** + * 1 is true, 0 is false. + */ + GAUNTLET_ENTERED(9178), + + WITHDRAW_X_AMOUNT(3960), + + IN_PVP_AREA(8121), + + /** + * Value of hotkey varbits can be 0-13 + * 0 corresponds to no hotkey set + * 1-12 correspond to F1-F12 respectively + * 13 corresponds to escape + */ + COMBAT_TAB_HOTKEY(4675), + STATS_TAB_HOTKEY(4676), + QUESTS_TAB_HOTKEY(4677), + INVENTORY_TAB_HOTKEY(4678), + EQUIPMENT_TAB_HOTKEY(4679), + PRAYER_TAB_HOTKEY(4680), + SPELLBOOK_TAB_HOTKEY(4682), + FRIENDS_TAB_HOTKEY(4684), + ACCOUNT_MANAGEMENT_TAB_HOTKEY(6517), + LOGOUT_TAB_HOTKEY(4689), + OPTIONS_TAB_HOTKEY(4686), + EMOTES_TAB_HOTKEY(4687), + CLAN_TAB_HOTKEY(4683), + MUSIC_TAB_HOTKEY(4688), + + /** + * Chat Notifications settings + *
+ * LOOT_DROP_NOTIFICATIONS: 1 is true, 0 is false + * LOOT_DROP_NOTIFICATIONS_VALUE: gp value + * UNTRADEABLE_LOOT_NOTIFICATIONS: 1 is true, 0 is false + * BOSS_KILL_COUNT_UPDATES: 1 is filtered, 0 is unfiltered + * DROP_ITEM_WARNINGS: 1 is true, 0 is false + * DROP_ITEM_WARNINGS_VALUE: gp value + */ + LOOT_DROP_NOTIFICATIONS(5399), + LOOT_DROP_NOTIFICATIONS_VALUE(5400), + UNTRADEABLE_LOOT_NOTIFICATIONS(5402), + BOSS_KILL_COUNT_UPDATES(4930), + DROP_ITEM_WARNINGS(5411), + DROP_ITEM_WARNINGS_VALUE(5412), + /** + * Temple Trekking + */ + TREK_POINTS(1955), + TREK_STARTED(1956), + TREK_EVENT(1958), + TREK_STATUS(6719), + BLOAT_ENTERED_ROOM(6447), + + /** + * f2p Quest varbits, these don't hold the completion value. + */ + QUEST_DEMON_SLAYER(2561), + QUEST_GOBLIN_DIPLOMACY(2378), + QUEST_MISTHALIN_MYSTERY(3468), + QUEST_THE_CORSAIR_CURSE(6071), + QUEST_X_MARKS_THE_SPOT(8063), + QUEST_ERNEST_LEVER_A(1788), + QUEST_ERNEST_LEVER_B(1789), + QUEST_ERNEST_LEVER_C(1790), + QUEST_ERNEST_LEVER_D(1791), + QUEST_ERNEST_LEVER_E(1792), + QUEST_ERNEST_LEVER_F(1793), + + /** + * member Quest varbits, these don't hold the completion value. + */ + QUEST_ANIMAL_MAGNETISM(3185), + QUEST_BETWEEN_A_ROCK(299), + QUEST_CONTACT(3274), + QUEST_ZOGRE_FLESH_EATERS(487), + QUEST_DARKNESS_OF_HALLOWVALE(2573), + QUEST_DEATH_TO_THE_DORGESHUUN(2258), + QUEST_DESERT_TREASURE(358), + QUEST_DEVIOUS_MINDS(1465), + QUEST_EAGLES_PEAK(2780), + QUEST_ELEMENTAL_WORKSHOP_II(2639), + QUEST_ENAKHRAS_LAMENT(1560), + QUEST_ENLIGHTENED_JOURNEY(2866), + QUEST_THE_EYES_OF_GLOUPHRIE(2497), + QUEST_FAIRYTALE_I_GROWING_PAINS(1803), + QUEST_FAIRYTALE_II_CURE_A_QUEEN(2326), + QUEST_THE_FEUD(334), // 14 = able to pickpocket + QUEST_FORGETTABLE_TALE(822), + QUEST_GARDEN_OF_TRANQUILLITY(961), + QUEST_GHOSTS_AHOY(217), + QUEST_THE_GIANT_DWARF(571), + QUEST_THE_GOLEM(346), + QUEST_HORROR_FROM_THE_DEEP(34), + QUEST_ICTHLARINS_LITTLE_HELPER(418), + QUEST_IN_AID_OF_THE_MYREQUE(1990), + QUEST_THE_LOST_TRIBE(532), + QUEST_LUNAR_DIPLOMACY(2448), + QUEST_MAKING_HISTORY(1383), + QUEST_MOUNTAIN_DAUGHTER(260), + QUEST_MOURNINGS_END_PART_II(1103), + QUEST_MY_ARMS_BIG_ADVENTURE(2790), + QUEST_RATCATCHERS(1404), + QUEST_RECIPE_FOR_DISASTER(1850), + QUEST_RECRUITMENT_DRIVE(657), + QUEST_ROYAL_TROUBLE(2140), + QUEST_THE_SLUG_MENACE(2610), + QUEST_SHADOW_OF_THE_STORM(1372), + QUEST_A_SOULS_BANE(2011), + QUEST_SPIRITS_OF_THE_ELID(1444), + QUEST_SWAN_SONG(2098), + QUEST_A_TAIL_OF_TWO_CATS(1028), + QUEST_TEARS_OF_GUTHIX(451), + QUEST_WANTED(1051), + QUEST_COLD_WAR(3293), + QUEST_THE_FREMENNIK_ISLES(3311), + QUEST_TOWER_OF_LIFE(3337), + QUEST_WHAT_LIES_BELOW(3523), + QUEST_OLAFS_QUEST(3534), + QUEST_ANOTHER_SLICE_OF_HAM(3550), + QUEST_DREAM_MENTOR(3618), + QUEST_GRIM_TALES(2783), + QUEST_KINGS_RANSOM(3888), + QUEST_MONKEY_MADNESS_II(5027), + QUEST_CLIENT_OF_KOUREND(5619), + QUEST_BONE_VOYAGE(5795), + QUEST_THE_QUEEN_OF_THIEVES(6037), + QUEST_THE_DEPTHS_OF_DESPAIR(6027), + QUEST_DRAGON_SLAYER_II(6104), + QUEST_TALE_OF_THE_RIGHTEOUS(6358), + QUEST_A_TASTE_OF_HOPE(6396), + QUEST_MAKING_FRIENDS_WITH_MY_ARM(6528), + QUEST_THE_ASCENT_OF_ARCEUUS(7856), + QUEST_THE_FORSAKEN_TOWER(7796), + //TODO + QUEST_SONG_OF_THE_ELVES(7796), + + /** + * mini-quest varbits, these don't hold the completion value. + */ + QUEST_ARCHITECTURAL_ALLIANCE(4982), + QUEST_BEAR_YOUR_SOUL(5078), + QUEST_CURSE_OF_THE_EMPTY_LORD(821), + QUEST_ENCHANTED_KEY(1391), + QUEST_THE_GENERALS_SHADOW(3330), + QUEST_SKIPPY_AND_THE_MOGRES(1344), + QUEST_LAIR_OF_TARN_RAZORLOR(3290), + QUEST_FAMILY_PEST(5347), + QUEST_THE_MAGE_ARENA_II(6067), + //TODO + QUEST_IN_SEARCH_OF_KNOWLEDGE(6067), + + /** + * Spellbook filtering (1 = unfiltered, 0 = filtered) + */ + FILTER_SPELLBOOK(6718), + + /** + * POH Building mode (1 = yes, 0 = no) + */ + BUILDING_MODE(2176), + + WINTERTODT_TIMER(7980), + + /** + * 1 if in game, 0 if not + */ + LMS_IN_GAME(5314), + + /** + * Amount of pvp kills in current game + */ + LMS_KILLS(5315), + + /** + * The x coordinate of the final safespace (world coord) + */ + LMS_SAFE_X(5316), + + /** + * Locked Prayers + * 0-7 = Locked + * 8 = Unlocked + */ + CHIVPIETY_UNLOCKED(3909), + + /** + * Locked Prayers + * 0 = Locked + * 1 = Unlocked + */ + + RIGOUR_UNLOCKED(5451), + AUGURY_UNLOCKED(5452), + PRESERVE_UNLOCKED(5453), + + /** + * Spells being auto-casted + */ + AUTO_CAST_SPELL(276), + + /** + * Theatre of Blood 1=In Party, 2=Inside/Spectator, 3=Dead Spectating + */ + BLOAT_DOOR(6447), + + /** + * Theatre of Blood orb varbits each number stands for the player's health on a scale of 1-27 (I think), 0 hides the orb + */ + THEATRE_OF_BLOOD_ORB_1(6442), + THEATRE_OF_BLOOD_ORB_2(6443), + THEATRE_OF_BLOOD_ORB_3(6444), + THEATRE_OF_BLOOD_ORB_4(6445), + THEATRE_OF_BLOOD_ORB_5(6446), + + //NMZ + NMZ_OVERLOAD(3955), + + //Pyramid Plunder + PYRAMID_PLUNDER_SARCO_OPEN(2362), + PYRAMID_PLUNDER_CHEST_OPEN(2363), + + /** + * Varbit used for Slayer reward points + */ + SLAYER_REWARD_POINTS(4068), + + /** + * 0 = standard + * 1 = ancients + * 2 = lunars + * 3 = arrceus + **/ + SPELLBOOK(4070), + + /** + * Bank settings/flags + **/ + BANK_NOTE_FLAG(3958), + + KINGDOM_WORKERS_WOOD(81), + KINGDOM_WORKERS_HERBS(82), + KINGDOM_WORKERS_FISHING(83), + KINGDOM_WORKERS_MINING(84), + KINGDOM_WORKERS_FISH_COOKED_BUTTON(135), // 0 - Raw, 1 - Cooked + KINGDOM_WORKERS_HARDWOOD(2131), + KINGDOM_WORKERS_FARM(2132), + KINGDOM_WORKERS_HARDWOOD_BUTTON(2133), // 0 - Mahogany, 1 - Teak, 2 - Both + KINGDOM_WORKERS_HERBS_BUTTON(2134), // 0 - Herbs, 1 - Flax + + /** + * In the Wilderness + */ + IN_THE_WILDERNESS(5963), + ; /** * The raw varbit ID. */ private final int id; -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/game/Sound.java b/runelite-client/src/main/java/com/openosrs/client/game/Sound.java new file mode 100644 index 0000000000..24b7588040 --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/game/Sound.java @@ -0,0 +1,42 @@ +package com.openosrs.client.game; + +public enum Sound +{ + FIFTEEN_SECONDS(1, "net/runelite/client/game/sounds/15seconds.wav"), + FIVE_SECONDS(2, "net/runelite/client/game/sounds/5seconds.wav"), + ATTACK_WITH_MAGIC(3, "net/runelite/client/game/sounds/attackmagic.wav"), + ATTACK_WITH_MELEE(4, "net/runelite/client/game/sounds/attackmelee.wav"), + ATTACK_WITH_RANGED(5, "net/runelite/client/game/sounds/attackranged.wav"), + INCOMING(6, "net/runelite/client/game/sounds/incoming.wav"), + MOVE(7, "net/runelite/client/game/sounds/move.wav"), + PRAY_MAGIC(8, "net/runelite/client/game/sounds/praymagic.wav"), + PRAY_MELEE(9, "net/runelite/client/game/sounds/praymelee.wav"), + PRAY_RANGED(10, "net/runelite/client/game/sounds/prayranged.wav"), + REENABLE_PRAYER(11, "net/runelite/client/game/sounds/reenableprayer.wav"), + RUNAWAY(12, "net/runelite/client/game/sounds/runaway.wav"), + LOW_HEATLH(13, "net/runelite/client/game/sounds/lowhealth.wav"), + LOW_PRAYER(14, "net/runelite/client/game/sounds/lowprayer.wav"), + OUT_OF_COMBAT(15, "net/runelite/client/game/sounds/outofcombat.wav"), + RESTORED_SPECIAL_ATTACK(16, "net/runelite/client/game/sounds/restorespec.wav"), + IDLE(17, "net/runelite/client/game/sounds/idle.wav"), + BREAK(18, "net/runelite/client/game/sounds/break.wav"); + + private final String filePath; + private final int id; + + Sound(int id, String filePath) + { + this.id = id; + this.filePath = filePath; + } + + public String getFilePath() + { + return this.filePath; + } + + public int getId() + { + return this.id; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/game/SoundManager.java b/runelite-client/src/main/java/com/openosrs/client/game/SoundManager.java new file mode 100644 index 0000000000..0f46afb1f8 --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/game/SoundManager.java @@ -0,0 +1,95 @@ +package com.openosrs.client.game; + +import com.google.inject.Inject; +import java.io.IOException; +import javax.inject.Singleton; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.BooleanControl; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.FloatControl; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.UnsupportedAudioFileException; +import net.runelite.client.config.RuneLiteConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Singleton +public class SoundManager +{ + private static final Logger log = LoggerFactory.getLogger(SoundManager.class); + private final RuneLiteConfig runeliteConfig; + + @Inject + private SoundManager(RuneLiteConfig runeLiteConfig) + { + this.runeliteConfig = runeLiteConfig; + } + + public void playSound(final Sound sound) + { + new Thread(new Runnable() + { + + @Override + public void run() + { + try + { + AudioInputStream in = AudioSystem.getAudioInputStream(this.getClass().getClassLoader().getResource(sound.getFilePath())); + AudioFormat outFormat = SoundManager.this.getOutFormat(in.getFormat()); + DataLine.Info info = new DataLine.Info(SourceDataLine.class, outFormat); + SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info); + if (line != null) + { + line.open(outFormat, 2200); + if (line.isControlSupported(FloatControl.Type.MASTER_GAIN)) + { + int volume = 50; + FloatControl gainControl = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN); + BooleanControl muteControl = (BooleanControl) line.getControl(BooleanControl.Type.MUTE); + if (volume == 0) + { + muteControl.setValue(true); + } + else + { + muteControl.setValue(false); + gainControl.setValue((float) (Math.log((double) volume / 100.0) / Math.log(10.0) * 20.0)); + } + } + line.start(); + SoundManager.this.stream(AudioSystem.getAudioInputStream(outFormat, in), line); + line.drain(); + line.stop(); + } + } + catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) + { + throw new IllegalStateException(e); + } + } + }).start(); + } + + private AudioFormat getOutFormat(AudioFormat inFormat) + { + int ch = inFormat.getChannels(); + float rate = inFormat.getSampleRate(); + return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, rate, 16, ch, ch * 2, rate, false); + } + + private void stream(AudioInputStream in, SourceDataLine line) throws IOException + { + byte[] buffer = new byte[2200]; + int n = 0; + while (n != -1) + { + line.write(buffer, 0, n); + n = in.read(buffer, 0, buffer.length); + } + } + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/game/WorldLocation.java b/runelite-client/src/main/java/com/openosrs/client/game/WorldLocation.java new file mode 100644 index 0000000000..5a65f8ec98 --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/game/WorldLocation.java @@ -0,0 +1,906 @@ +/******************************************************************************* + * Copyright (c) 2019 openosrs + * Redistributions and modifications of this software are permitted as long as this notice remains in its original unmodified state at the top of this file. + * If there are any questions comments, or feedback about this software, please direct all inquiries directly to the file authors: + * ST0NEWALL#9112 + * Macweese#1169 UID 159941566994186240, macweese@pm.me + * openosrs Discord: https://discord.gg/Q7wFtCe + * openosrs website: https://openosrs.com + ******************************************************************************/ + +package com.openosrs.client.game; + +import com.google.common.collect.ImmutableMap; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.Getter; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import com.openosrs.client.util.PvPUtil; + + /* + * Enums sorted alphabetically by main regions (Kingdoms) and then their sub-regions or notable features + * Example: + * Wilderness + * Mage Bank + */ +public enum WorldLocation +{ + + /*- + * Ape Atoll + * Crash Island + * Marim + */ + APE_ATOLL_TEMPLE("Ape Atoll Temple", new Location(2784, 2802, 2810, 2770), 0), + APE_ATOLL_GATE("Ape Atoll Gate", new Location(2712, 2761, 2730, 2749), 0), + APE_ATOLL_GLIDER("Ape Atoll Glider", new Location(2707, 2808, 2719, 2797), 0), + APE_ATOLL_TEAKS("Ape Atoll Teak Trees", new Location(2756, 2708, 2791, 2689), 0), + CRASH_ISLAND("Crash Island", new Location(2881, 2749, 2943, 2691), 0), + KRUK_DUNGEON_1("Monkey Madness 2 Dungeon", new Location(2689, 9150, 2815, 9088), 0), + KRUK_DUNGEON_2("Monkey Madness 2 Dungeon", new Location(2689, 9150, 2815, 9088), 1), + KRUK_DUNGEON_3("Monkey Madness 2 Dungeon", new Location(2309, 9277, 2454, 9131), 1), + MARIM_NORTH("North Marim", new Location(2731, 2804, 2783, 2786), 0), + MARIM_SOUTH("South Marim", new Location(2731, 2785, 2783, 2762), 0), + MONKEY_MADNESS_DUNGEON("Monkey Madness 1 Dungeon", new Location(2689, 9150, 2815, 9088), 0), + + /*- + * Asgarnia + * Faldor + * Burthorpe + * Edgeville + * Entrana + * Port Sarim + * Rimmington + * Taverly + */ + ASGARNIAN_ICE_DUNGEON_WYVERNS("Asgarnian Ice Dungeon - Skeletal Wyverns", new Location(3022, 9559, 3070, 9537), 0), + ASGARNIAN_ICE_DUNGEON_ICE_MONSTERS("Asgarnian Ice Dungeon - Ice Warriors & Ice Giants", new Location(3043, 9587, 3065, 9570), 0), + ASGARNIAN_ICE_DUNGEON_PIRATES("Asgarnian Ice Dungeon - Pirates", new Location(2986, 9568, 2999, 9585), 0), + BURTHOPRE_GAMES_TELEPORT("Burthorpe Games Tele", new Location(2890, 3557, 2907, 3549), 0), + CRAFTING_GUILD("Crafting Guild", new Location(2921, 3292, 2944, 3275), 0), + EDGEVILLE_MONASTERY("Edgeville Monastery", new Location(3044, 3507, 3060, 3471), 0), + FALADOR_BANK("Fally Bank", new Location(2943, 3372, 2949, 3358), 0), + FALADOR_CENTER("Fally Center", new Location(2959, 3385, 2972, 3374), 0), + FALADOR_EAST_BANK("Fally East Bank", new Location(3008, 3358, 3021, 3353), 0), + FALADOR_FARM("Falador Farm", new Location(3014, 3314, 3067, 3283), 0), + FALADOR_PARK("Fally Park", new Location(2982, 3390, 3025, 3368), 0), + FALADOR_PARTYROOM("Falador Partyroom", new Location(3035, 3386, 3056, 3370), 0), + FALADOR_RESPAWN("Fally Respawn", new Location(2957, 3355, 2998, 3325), 0), + GOBLIN_VILLAGE("Goblin Village", new Location(2948, 3516, 2963, 3493), 0), + HEROES_GUILD("Heroes' Guild", new Location(2881, 3517, 2902, 3504), 0), + HEROES_GUILD_DUNGEON("Heroes' Guild Dungeon", new Location(2885, 9918, 2945, 9882), 0), + ICE_MOUNTAIN("Ice Mountain", new Location(3001, 3508, 3024, 3463), 0), + MIND_ATLAR("Mind Altar", new Location(2970, 3520, 2990, 3509), 0), + MUDSKIPPER_POINT("Mudskipper point", new Location(2980, 3145, 3011, 3104), 0), + PORT_SARIM("Port Sarim", new Location(3024, 3250, 3055, 3192), 0), + PORT_SARIM_JAIL("Port Sarim Jail", new Location(3009, 3193, 3021, 3178), 0), + RIMMINGTON("Rimmington", new Location(2946, 3213, 2970, 3188), 0), + RIMMINGTON_DOCKS("Rimmington Docks", new Location(2905, 3228, 2922, 3222), 0), + RIMMINGTON_MINE("Rimmington Mine", new Location(2968, 3252, 2991, 3230), 0), + RIMMINGTON_PORTAL("Rimmington Portal", new Location(2946, 3228, 2960, 3218), 0), + ROGUES_DEN("Rogue's Den", new Location(3036, 4957, 3067, 4986), 1), + TAVERLY("Taverly", new Location(2880, 3442, 2917, 3409), 0), + TAVERLY_DUNGEON_BLACK_KNGIHTS("Taverly Dungeon - Black Knights", new Location(2883, 9717, 2939, 9667), 0), + TAVERLY_DUNGEON_HILL_GIANTS("Taverly Dungeon - Hill Giants", new Location(2895, 9743, 2920, 9718), 0), + TAVERLY_DUNGEON_BLACK_DRAGONS("Taverly Dungeon - Black Dragons", new Location(2812, 9836, 2846, 9822), 0), + TAVERLY_DUNGEON_HELLHOUNDS("Taverly Dungeon - Hell Hounds", new Location(2847, 9854, 2873, 9822), 0), + TAVERLY_DUNGEON_BLUE_DRAGONS("Taverly Dungeon - Blue Dragons", new Location(2890, 9778, 2923, 9813), 0), + TAVERLY_DUNGEON_BLACK_DEMONS("Taverly Dungeon - Black Demons", new Location(2844, 9800, 2873, 9773), 0), + TAVERLY_DUNGEON_POISON_SPIDERS("Taverly Dungeon - Poison Spiders", new Location(3010, 4756, 3068, 4803), 0), + TAVERLY_DUNGEON_CHAOS_DRUIDS("Taverly Dungeon - Chaos Druids", new Location(2915, 9856, 2944, 9833), 0), + TAVERLY_DUNGEON_LESSER_DEMONS("Taverly Dungeon - Lesser Demons", new Location(2924, 9813, 2946, 9777), 0), + TAVERLY_DUNGEON_MAGIC_AXES("Taverly Dungeon - Magic Axes", new Location(2947, 9798, 2971, 9769), 0), + TAVERLY_DUNGEON_CHAOS_DWARVES("Taverly Dungeon - Chaos Dwarves", new Location(2920, 9776, 2938, 9745), 0), + TAVERLY_DUNGEON_MAIN_CORRIDOR("Taverly Dungeon - Main Corridor", new Location(2880, 9793, 2889, 9850), 0), + TAVERLY_GATE("Taverly Gate", new Location(2931, 3456, 2944, 3444), 0), + TAVERLY_POH_PORTAL("Taverly POH Portal", new Location(2885, 3471, 2899, 3458), 0), + WARRIORS_GUILD("Warriors' Guild", new Location(2838, 3536, 2876, 3555), 0), + WARRIORS_GUILD_BASEMENT("Warriors' Guild Basement (Dragon Defender)", new Location(2904, 9974, 2941, 9956), 0), + + /*- + * Entrana + */ + ENTRANA_BALLOON("Entrana Balloon", new Location(2803, 3359, 2815, 3347), 0), + ENTRANA_CHURCH("Entrana Church", new Location(2840, 3356, 2858, 3341), 0), + ENTRANA_DOCKS("Entrana Docks", new Location(2825, 3338, 2847, 3328), 0), + ENTRANA_NORTH("Entrana (North Portion)", new Location(2541, 2875, 2595, 2837), 0), + + /*- + * Feldip Hills + * Corsair Cove + * Gu'Tanoth + */ + CORSAIR_COVE("Corsair Cove", new Location(2541, 2875, 2595, 2837), 0), + CORSAIR_RESOURCE_AREA("Corsair Resource Area", new Location(2453, 2905, 2488, 2883), 0), + FELDIP_HILLS_GLIDER("Feldip Hills Glider", new Location(2536, 2975, 2546, 2965), 0), + FELDIP_HILLS_RED_CHINS("Feldip Hills Red Chins", new Location(2525, 2935, 2561, 2902), 0), + GU_TANOTH("Gu'Tanoth", new Location(2497, 3060, 2558, 3008), 0), + MYTHS_GUILD("Myth's Guild", new Location(2470, 2872, 2442, 2834), 0), + + /* + * Fossil Island + */ + MUSEUM_CAMP("Fossil Island Museum Camp", new Location(3708, 3797, 3751, 3833), 0), + FOSSIL_ISLAND_HOUSE_ON_THE_HILL("House on the Hill (Fossil Island)", new Location(3747, 3891, 3795, 3855), 0), + FOSSIL_ISLAND_MUSHROOM_FOREST("Fossil Island Mushroom Forest (Herbiboar)", new Location(3670, 3894, 3707, 3814), 0), + FOSSIL_ISLAND_SWAMP_NORTH("Fossil Island Swamp (North half)", new Location(3707, 3758, 3643, 3696), 0), + FOSSIL_ISLAND_SWAMP_SOUTH("Fossil Island Swamp (South half)", new Location(3707, 3813, 3643, 3759), 0), + FOSSIL_ISLAND_VERDANT_VALLEY("Fossil Island Verdant Valley (South East Island)", new Location(3670, 3894, 3707, 3814), 0), + FOSSIL_ISLAND_VOLCANO_BANK("Fossil Island Volcano Bank", new Location(3807, 3818, 3825, 3800), 0), + + /*- + * Fremennik Province + * Fremennik Isles (Neitiznot & Jatizo) + * Fremennik Slayer Dungeon + * Lunar Isle + * Miscellania and Etceteria + * Rellekka + * Waterbirth Island + */ + ETCETERIA("Etceteria", new Location(2626, 3904, 2571, 3861), 0), + ETCETERIA_DOCKS("Etceteria Docks", new Location(2571, 3904, 2626, 3861), 0), + FREMENNIK_BASILISK_KNIGHT_DUNGEON("Fremennik Basilisk Knight Dungeon", new Location(2398, 10468, 2496, 10370), 0), + FREMENNIK_SLAYER_DUNGEON("Fremennik Slayer Dungeon", new Location(2771, 10023, 2811, 9989), 0), + FREMENNIK_SLAYER_DUNGEON_BASILISKS("Fremennik Slayer Dungeon - Baslisks", new Location(2734, 10015, 2751, 9988), 0), + FREMENNIK_SLAYER_DUNGEON_ENTRANCE("Fremennik Slayer Dungeon Entrance", new Location(2776, 3604, 2801, 3626), 0), + FREMENNIK_SLAYER_DUNGEON_JELLIES("Fremennik Slayer Dungeon - Jellies", new Location(2694, 10035, 2733, 10016), 0), + FREMENNIK_SLAYER_DUNGEON_KURASKS("Fremennik Slayer Dungeon - Kurasks", new Location(2708, 10007, 2690, 9988), 0), + FREMENNIK_SLAYER_DUNGEON_PYREFIENDS("Fremennik Slayer Dungeon - Pyrefiends", new Location(2752, 10015, 2770, 9988), 0), + FREMENNIK_SLAYER_DUNGEON_TUROTHS("Fremennik Slayer Dungeon - Turoths", new Location(2709, 10015, 2733, 9988), 0), + JATIZSO("Jatizso", new Location(2369, 3826, 2428, 3776), 0), + KELDAGRIM_EAST("Eastern Keldagrim", new Location(2884, 10236, 2943, 10181), 0), + KELDAGRIM_ENTRANCE("Keldagrim Entrance", new Location(2722, 3720, 2738, 3703), 0), + KELDAGRIM_WEST("Western Keldagrim", new Location(2819, 10236, 2875, 10182), 0), + LUNAR_ISLE_CENTRAL("Lunar Isle Central", new Location(2055, 3933, 2112, 3888), 0), + LUNAR_ISLE_EAST("Lunar Isle East", new Location(2113, 3921, 2185, 3888), 0), + LUNAR_ISLE_NORTH("Lunar Isle North", new Location(2063, 3958, 2112, 3934), 0), + LUNAR_ISLE_NORTH_EAST("Lunar Isle North East", new Location(2113, 3958, 2185, 3922), 0), + LUNAR_ISLE_SOUTH("Lunar Isle South", new Location(2057, 3887, 2112, 3843), 0), + LUNAR_ISLE_SOUTHEAST("Lunar Isle SouthEast", new Location(2113, 3887, 2185, 3843), 0), + MISCELLANIA("Miscellania", new Location(2492, 3904, 2570, 3836), 0), + MISCELLANIA_DOCKS("Miscellania Docks", new Location(2623, 3851, 2603, 3840), 0), + MOUNTAIN_CAMP("Mountain Camp", new Location(2789, 3682, 2813, 3658), 0), + NEITIZNOT("Neitiznot", new Location(2300, 3826, 2368, 3776), 0), + PIRATES_COVE("Pirate's Cove", new Location(2186, 3842, 2228, 3785), 0), + RELLEKKA_MAIN_HALL("Rellekka Main Hall", new Location(2652, 3685, 2670, 3658), 0), + RELLEKKA_MARKET("Rellekka Market", new Location(2629, 3682, 2651, 3654), 0), + RELLEKKA_NORTH_DOCKS("Rellekka North Docks", new Location(2640, 3712, 2651, 3706), 0), + RELLEKKA_NORTH_EAST("Rellekka North East", new Location(2652, 3712, 2690, 3686), 0), + RELLEKKA_POH_PORTAL("Rellekka POH Portal", new Location(2662, 3635, 2676, 3624), 0), + RELLEKKA_SOUTH_DOCKS("Rellekka South Docks", new Location(2619, 3699, 2641, 3681), 0), + RELLEKKA_ZONE("Rellekka", new Location(2600, 3708, 2690, 3645), 0), + ROCK_CRABS_EAST("Rock Crabs East (Near Keldagrim)", new Location(2691, 3738, 2730, 3713), 0), + ROCK_CRABS_WEST("Rock Crabs West (North of Rellekka)", new Location(2650, 3738, 2690, 3713), 0), + VORKATH("Vorkath", new Location(2237, 4096, 2301, 4031), 0), + WATERBIRTH_DUNGEON_ROCK_LOBSTERS("Waterbirth Dungeon - Rock Lobsters", new Location(1875, 4380, 1919, 4412), 0), + WATERBIRTH_DUNGEON_DKS_1("DKS", new Location(2886, 4473, 2941, 4424), 0), // One of these is private, not sure which + WATERBIRTH_DUNGEON_DKS_2("DKS", new Location(2886, 4409, 2941, 4361), 0), // One of these is private, not sure which + WATERBIRTH_DUNGEON_ZONE_1("Waterbirth Dungeon", new Location(2435, 10176, 2558, 10112), 0), + WATERBIRTH_DUNGEON_ZONE_2("Waterbirth Dungeon", new Location(1788, 4413, 1966, 4352), 1), + WATERBIRTH_ISLAND("Waterbirth Island", new Location(2494, 3774, 2562, 3710), 0), + + /*- + * Great Kourend + * Arceuus + * Battlefront + * Catacombs of Kourend + * Crabclaw Caves + * Forthos Dungeon + * Hosidius + * Kebos Lowlands + * Kingstown + * Kourend Woodland + * Lake Molch + * Lizardman Settlement + * Lovakengj + * Mount Karuulm + * Mount Quidamortem + * Northern Tundras + * Port Piscarilius + * Shayzien + * Wintertodt + */ + ARCEUUS("Arceuus", new Location(1620, 3780, 1739, 3708), 0), + ARCEUUS_BANK("Arceuus Bank", new Location(1620, 3754, 1639, 3735), 0), + ARCEUUS_DENSE_ESSENCE_MINE("Arceuus Dense Essence Mine", new Location(1741, 3880, 1786, 3831), 0), + ARCEUUS_LIBRARY("Arceuus Library", new Location(1605, 3833, 1662, 3781), 0), + BATTLEFRONT("Battlefront Teleport", new Location(1344, 3745, 1362, 3726), 0), + BLAST_MINE("Lovakengj Blast Mine", new Location(1467, 3888, 1513, 3840), 0), + BLOOD_ALTAR("Blood Altar", new Location(1710, 3835, 1737, 3822), 0), + CHASM_OF_FIRE("Chasm of Fire", new Location(1411, 10108, 1468, 10050), 1), + COX("CoX", new Location(1226, 3574, 1270, 3559), 0), + CRAB_CLAW_ISLE("Crab Claw Isle", new Location(1745, 3449, 1795, 3399), 0), + DARK_ALTAR("Arceuus Dark Altar", new Location(1699, 3895, 1734, 3869), 0), + FARMING_GUILD("Farming Guild", new Location(1223, 3718, 1273, 3765), 0), + FISHING_HAMLET("Fishing Hamlet (East of Wintertodt Camp)", new Location(1683, 3969, 1720, 3917), 0), + FOODHALL("Piscarilius Foodhall", new Location(1830, 3762, 1854, 3734), 0), + FORTHOS_RUINS("Forthos Ruins", new Location(1666, 3590, 1684, 3561), 0), + FORTHOS_DUNGEON_ALTAR("Forthos Dungeon - Altar", new Location(1794, 9954, 1804, 9946), 0), + FORTHOS_DUNGEON_GRUBBY_CHEST("Forthos Dungeon - Grubby Chest", new Location(1793, 9928, 1799, 9922), 0), + FORTHOS_DUNGEON_LADDER_EAST("Forthos Dungeon - East Ladder", new Location(1825, 9978, 1835, 9969), 0), + FORTHOS_DUNGEON_LADDER_WEST("Forthos Dungeon - West Ladder", new Location(1795, 9972, 1805, 9958), 0), + FORTHOS_DUNGEON_RED_DRAGONS("Forthos Dungeon - Red Dragons", new Location(1807, 9944, 1828, 9933), 0), + FORTHOS_DUNGEON_SARACHNIS("Forthos Dungeon - Sarachnis", new Location(1829, 9890, 1854, 9913), 0), + FORTHOS_DUNGEON_SPIDERS("Forthos Dungeon - Red Spiders", new Location(1830, 9968, 1848, 9947), 0), + FORTHOS_DUNGEON_UNDEAD_DRUIDS_1("Forthos Dungeon - Undead Druids", new Location(1795, 9944, 1806, 9933), 0), + FORTHOS_DUNGEON_UNDEAD_DRUIDS_2("Forthos Dungeon - Undead Druids", new Location(1806, 9973, 1814, 9958), 0), + FORTHOS_DUNGEON_ZONE("Forthos Dungeon", new Location(1789, 9985, 1858, 9914), 0), + HOSIDIUS_BANK("Hosidius Bank", new Location(1743, 3603, 1753, 3594), 0), + HOSIDIUS_FRUIT_STALLS("Hosidius Fruit Stalls", new Location(1790, 3614, 1806, 3603), 0), + HOSIDIUS_KITCHEN("Hosidius Kitchen (Bank)", new Location(1671, 3625, 1687, 3610), 0), + HOSIDIUS_PLOW_FIELD("Hosidius Plow Fields", new Location(1761, 3558, 1781, 3519), 0), + HOSIDIUS_POH_PORTAL("Hosidius POH Portal", new Location(1735, 3522, 1747, 3511), 0), + HOSIDIUS_SQUARE("Hosidius Square", new Location(1754, 3607, 1772, 3589), 0), + HOSIDIUS_VINERY("Hosidius Vinery", new Location(1799, 3573, 1816, 3537), 0), + HOSIDIUS_ZONE("Hosidius", new Location(1737, 3627, 1789, 3582), 0), + KOUREND_CASTLE("Kourend Castle", new Location(1592, 3700, 1692, 3646), 0), + KOUREND_CATACOMBS_ABYSSAL_DEMONS("Kourend Catacombs - Abyssal Demons", new Location(1667, 10101, 1683, 10082), 0), + KOUREND_CATACOMBS_BLACK_DEMONS("Kourend Catacombs - Black Demons", new Location(1713, 10073, 1724, 10086), 0), + KOUREND_CATACOMBS_BRUTAL_BLACK_DRAGONS("Kourend Catacombs - Brutal Black Dragons", new Location(1604, 10105, 1635, 10068), 0), + KOUREND_CATACOMBS_CENTER("Kourend Catacombs Center", new Location(1655, 10055, 1670, 10038), 0), + KOUREND_CATACOMBS_DUST_DEVILS("Kourend Catacombs - Dust Devils", new Location(1704, 10037, 1734, 9985), 0), + KOUREND_CATACOMBS_GREATER_DEMONS("Kourend Catacombs - Greater Demons", new Location(1684, 10105, 1724, 10087), 0), + KOUREND_CATACOMBS_NECHRYAELS("Kourend Catacombs - Nechryaels", new Location(1684, 10086, 1712, 10073), 0), + KOUREND_CATACOMBS_SOUTH("Kourend Catacombs - South", new Location(1639, 10014, 1702, 9985), 0), + KOUREND_CATACOMBS_SOUTH_WEST("Kourend Catacombs South-West Corner", new Location(1596, 10028, 1634, 9984), 0), + KOUREND_CATACOMBS_STEEL_DRAGONS("Kourend Catacombs - Steel Dragons", new Location(1599, 10066, 1630, 10029), 0), + KOUREND_CATACOMBS_ZONE("Kourend Catacombs", new Location(1595, 10106, 1735, 9984), 0), + LANDS_END("Land's End", new Location(1481, 3448, 1527, 3396), 0), + LAKE_MOLCH("Lake Molch", new Location(1357, 3643, 1377, 3624), 0), + LIZARDMAN_SHAMANS("Lizardman Shamans", new Location(1414, 3726, 1461, 3688), 0), + LOVAKENGJ("Lovakengj", new Location(1425, 3810, 1520, 3730), 0), + MOUNT_KARUULM("Mount Karuulm", new Location(1287, 3829, 1331, 3787), 0), + PISCARILIUS_ANGLERFISH("Piscarilius Angler Fishing Spot", new Location(1807, 3779, 1842, 3766), 0), + PISCARILIUS_BANK("Piscarilius Bank", new Location(1793, 3794, 1812, 3782), 0), + PISCARILIUS_PORT("Port Piscarilius", new Location(1788, 3712, 1849, 3673), 0), + PISCARILIUS_ZONE("Piscarilius", new Location(1740, 3814, 1854, 3713), 0), + SANDCRABS_BANK("Sandcrabs Bank", new Location(1706, 3475, 1730, 3455), 0), + SANDCRABS_NORTH("Sandcrabs (East of Vinery)", new Location(1848, 3572, 1884, 3532), 0), + SANDCRABS_SOUTH_1("Sandcrabs (South of Tithe Farm)", new Location(1796, 3468, 1849, 3436), 0), + SANDCRABS_SOUTH_2("Sandcrabs (South Coast)", new Location(1745, 3474, 1795, 3450), 0), + SANDCRABS_SOUTH_EAST("Sandcrabs (East of Tithe Farm)", new Location(1850, 3529, 1884, 3465), 0), + SHAYZIEN_BANK("Shayzien Bank", new Location(1494, 3622, 1515, 3611), 0), + SHAYZIEN_CRYPTS_ENTRANCE("Shayzien Crypts Entrance", new Location(1474, 3570, 1502, 3535), 0), + SHAYZIEN_INFIRMARY("Shayzien Infirmary", new Location(1565, 3574, 1590, 3604), 0), + SHAYZIEN_ZONE("Shayzien", new Location(1472, 3644, 1591, 3521), 0), + SOUL_ALTAR("Soul Altar", new Location(1804, 3869, 1834, 3841), 0), + SULPHUR_MINE("Lovakengj Sulphur Mine", new Location(1415, 3888, 1466, 3840), 0), + SULPHUR_MINE_BANK("Lovakengj Sulphur Mine Bank", new Location(1430, 3838, 1443, 3817), 0), + TITHE_FARM("Tithe Farm", new Location(1794, 3480, 1841, 3517), 0), + WINTERTODT_CAMP("Wintertodt Camp", new Location(1616, 3963, 1645, 3932), 0), + WINTERTODT_ENTRANCE("Wintertodt Entrance", new Location(1617, 3986, 1641, 3964), 0), + WINTERTODT_NORTHEAST("Wintertodt NorthEast", new Location(1630, 4027, 1651, 4008), 0), + WINTERTODT_NORTHWEST("Wintertodt NorthWest", new Location(1608, 4028, 1629, 4008), 0), + WINDERTODT_SOUTH_EAST("Windertodt South East", new Location(1630, 4007, 1651, 3987), 0), + WINTERTODT_SOUTHWEST("Wintertodt SouthWest", new Location(1608, 4007, 1629, 3987), 0), + WOODCUTTING_GUILD_BANK("Woodcutting Guild Bank", new Location(1588, 3481, 1594, 3473), 0), + WOODCUTTING_GUILD_EAST("Woodcutting Guild (East Portion)", new Location(1623, 3519, 1657, 3488), 0), + WOODCUTTING_GUILD_WEST("Woodcutting Guild (Redwoods)", new Location(1562, 3503, 1586, 3476), 0), + WOODCUTTING_GUILD_ZONE("Woodcutting Guild", new Location(1560, 3520, 1659, 3471), 0), + + /*- + * Kandarin + * Ardougne + * Battlefield + * Camelot + * Catherby + * Fishing Guild & McGrubor's Woods + * Observatory + * Ourania + * Piscatoris Fishing Colony + * Port Khazard + * Seers' Village + * Tree Gnome Stronghold + * Tree Gnome Village + * Witchaven + * Yanille + */ + ARDOUGNE_CASTLE("Ardy Castle", new Location(2567, 3311, 2591, 3283), 0), + ARDOUGNE_DOCKS("Ardy Docks", new Location(2660, 3284, 2689, 3264), 0), + ARDOUGNE_MONASTERY("Ardougne Monastery", new Location(2587, 3227, 2623, 3202), 0), + ARDOUGNE_NORTH_BANK("Ardy North Bank", new Location(2611, 3336, 2622, 3329), 0), + ARDOUGNE_SOUTH_BANK("Ardy South Bank", new Location(2645, 3288, 2659, 3279), 0), + ARDOUGNE_STALLS("Ardy Stalls", new Location(2651, 3318, 2673, 3293), 0), + ARDOUGNE_ZOO("Ardy Zoo", new Location(2598, 3288, 2636, 3265), 0), + BARBARIAN_OUTPOST("Barbarian Outpost", new Location(2517, 3580, 2557, 3540), 0), + BAXTORIAN_WATERFALL_DUNGEON("Waterfall Dungeon (Baxtorian Falls)", new Location(2556, 9861, 2594, 9918), 0), + CAMELOT_CASTLE("Camelot Castle", new Location(2743, 3481, 2775, 3468), 0), + CASTLE_WARS_BANK("Castle Wars Bank", new Location(2435, 3100, 2448, 3078), 0), + CASTLE_WARS_ZONE("Castle Wars", new Location(2435, 3127, 2474, 3074), 0), + CATHERBY("Catherby", new Location(2791, 3457, 2833, 3436), 0), + CATHERBY_DOCKS("Catherby Docks", new Location(2790, 3432, 2808, 3409), 0), + CATHERBY_FISHING_SPOTS("Catherby Fishing Spots", new Location(2834, 3441, 2862, 3425), 0), + CATHERBY_FARMING_PATCH("Catherby Farming Patch", new Location(2791, 3472, 2833, 3458), 0), + EAGLES_PEAK("Eagles' Peak", new Location(2308, 3495, 2350, 3479), 0), + FALCONRY_HUNTING_AREA("Falconry Hunting Area", new Location(2365, 3621, 2390, 3572), 0), + FISHING_GUILD("Fishing Guild", new Location(2627, 3426, 2579, 3391), 0), + FISHING_PLATFORM("Fishing Platform", new Location(2763, 3290, 2792, 3273), 0), + GNOME_AGILITY("Gnome Agility", new Location(2469, 3441, 2489, 3412), 0), + GNOME_BALL("Gnome Ball", new Location(2384, 3495, 2408, 3479), 0), + GRAND_TREE("Grand Tree", new Location(2442, 3515, 2490, 3478), 0), + KRAKEN_COVE_DUNGEON("Kraken Dungeon", new Location(2303, 10047, 2240, 9983), 0), + KRAKEN_COVE_ENTRANCE("Kraken Cove Entrance", new Location(2262, 3623, 2295, 3596), 0), + LEGENDS_GUILD("Legends' Guild", new Location(2716, 3388, 2741, 3346), 0), + LEGENDS_GUILD_DUNGEON("Legends' Guild Dungeon", new Location(2690, 9784, 2740, 9730), 0), + LIGHTHOUSE("Lighthouse", new Location(2494, 3649, 2524, 3616), 0), + MCGRUBORS_WOODS("McGrubor's Woods", new Location(2624, 3501, 2647, 3481), 0), + NIEVE("Nieve", new Location(2430, 3425, 2435, 3419), 0), + NIGHTMARE_ZONE("Nightmare Zone", new Location(2599, 3119, 2614, 3111), 0), + OBSERVATORY("Observatory", new Location(2429, 3198, 2452, 3149), 0), + OBSERVATORY_DUNGEON("Obsvervatory Dungeon", new Location(2305, 9406, 2366, 9344), 0), + OTTOS_GROTTO("Barbarian Fishing", new Location(2491, 3519, 2527, 3488), 0), + OURANIA_CAVE("ZMI", new Location(3006, 5567, 3072, 5634), 0), + THE_OUTPOST("The Outpost", new Location(2428, 3356, 2443, 3338), 0), + PISCATORIS_FISHING_COLONY("Piscatoris Fishing Colony", new Location(2302, 3708, 2364, 3653), 0), + PORT_KHAZARD("Port Khazard", new Location(2624, 3182, 2680, 3143), 0), + RANGING_GUILD("Ranging Guild", new Location(2650, 3445, 2685, 3411), 0), + RED_SALAMANDERS("Red Salamanders", new Location(2441, 3229, 2464, 3204), 0), + SEERS_VILLAGE("Seers Village", new Location(2688, 3498, 2742, 3468), 0), + SINCLAIR_MANSION("Sinclair Mansion", new Location(2723, 3584, 2756, 3552), 0), + SMOKE_DEVIL_DUNGEON("CW Smoke Devil Dungeon", new Location(2379, 9467, 2427, 9415), 0), + SMOKE_DEVIL_DUNGEON_BOSS("CW Smoke Dungeon (Boss Room)", new Location(2347, 9462, 2377, 9438), 0), + SMOKE_DEVIL_DUNGEON_ENTRANCE("Smoke Devil Dungeon Entrance", new Location(2430, 3425, 2435, 3419), 0), + TRAINING_GROUND("Training Ground (Caged Ogres)", new Location(2501, 3387, 2534, 3358), 0), + TREE_GNOME_VILLAGE("Tree Gnome Village", new Location(2514, 3175, 2547, 3158), 0), + WEST_ARDOUGNE("West Ardy", new Location(2452, 3336, 2557, 3265), 0), + WITCHAVEN("Witchaven", new Location(2704, 3267, 2741, 3295), 0), + WITCHAVEN_DUNGEON("Witchaven Dungeon", new Location(2750, 9665, 2690, 9719), 0), + WIZARDS_GUILD("Wizards Guild", new Location(2585, 3092, 2596, 3082), 0), + WHITE_WOLF_MOUNTAIN_GNOME_GLIDER("White Wolf Mountain Gnome Glider", new Location(2838, 3509, 2852, 3496), 0), + YANILLE_AGILITY_DUNGEON("Yanille Agilty Dungeon", new Location(2559, 9536, 2624, 9475), 0), + YANILE_BANK("Yanile Bank", new Location(2608, 3097, 2616, 3087), 0), + YANILLE_EAST("Yanille East", new Location(2576, 3110, 2621, 3071), 0), + YANILLE_POH_PORTAL("Yanille POH Portal", new Location(2537, 3108, 2551, 3091), 0), + YANILLE_WEST("Yanille West", new Location(2532, 3110, 2575, 3071), 0), + + /*- + * Karamja + * Brimhaven + * Cairn Isle + * Crandor & Karamja Dungeon + * Kharazi Jungle + * Mor Ul Rel (TzHaar City) + * Musa Point + * Shilo Village + * Ship Yard + * Tai Bwo Wannai + */ + BRIMHAVEN_AGILITY_ARENA("Brimhaven Agility Arena", new Location(2757, 9594, 2809, 9541), 3), + BRIMHAVEN_DOCKS("Brimhaven Docks", new Location(2758, 3241, 2777, 3220), 0), + BRIMHAVEN_DUNGEON("Brimhaven Dungeon - Main Corridor", new Location(2690, 9572, 2714, 9556), 0), + BRIMHAVEN_DUNGEON_BLACK_DEMONS("Brimhaven Dungeon - Black Demons", new Location(2694, 9495, 2726, 9475), 0), + BRIMHAVEN_DUNGEON_BRONZE_DRAGONS("Brimhaven Dungeon - Bronze Dragons", new Location(2727, 9504, 2750, 9475), 0), + BRIMHAVEN_DUNGEON_DOGS("Brimhaven Dungeon - Dogs", new Location(2653, 9530, 2675, 9509), 0), + BRIMHAVEN_DUNGEON_FIRE_GIANTS("Brimhaven Dungeon - Fire Giants", new Location(2638, 9506, 2673, 9476), 0), + BRIMHAVEN_DUNGEON_METAL_DRAGONS_SLAYER("Brimhaven Dungeon - Metal Dragons (Slayer Only)", new Location(2626, 9469, 2685, 9409), 0), + BRIMHAVEN_DUNGEON_METAL_DRAGONS("Brimhaven Dungeon - Metal Dragons", new Location(2693, 9469, 2748, 9412), 0), + BRIMHAVEN_DUNGEON_MOSS_GIANTS("Brimhaven Dungeon - Moss Giants", new Location(2630, 9575, 2670, 9531), 0), + BRIMHAVEN_DUNGEON_RED_DRAGONS("Brimhaven Dungeon - Red Dragons", new Location(2686, 9553, 2726, 9496), 0), + BRIMHAVEN_POH_PORTAL("Brimhaven POH Portal", new Location(2749, 3184, 2765, 3170), 0), + CAIRN_ISLE("Cairn Isle", new Location(2752, 2993, 2775, 2963), 0), + CRANDOR("Crandor", new Location(2813, 3310, 2864, 3231), 0), + HARDWOOD_GROVE("Hardwood Grove", new Location(2815, 3092, 2830, 3073), 0), + KARAMBWAN_FISHING_SPOT("Karambwan Fishing Spot", new Location(2896, 3116, 2920, 3104), 0), + KARAMJA_DOCKS("Karamja Docks", new Location(2813, 3310, 2864, 3231), 0), + KARAMJA_GLORY_TELEPORT("Karamja Glory Tele", new Location(2910, 3177, 2934, 3156), 0), + KARAMJA_GNOME_GLIDER("Karamja Gnome Glider", new Location(2961, 2960, 2984, 2983), 0), + KARAMJA_SHIP_YARD("Karamja Ship Yard", new Location(2949, 3066, 3004, 3016), 0), + KARAMJA_VOLCANO("Karamja Volcano", new Location(2828, 3194, 2866, 3157), 0), + KARAMJA_VOLCANO_DUNGEON("Karamja Dungeon", new Location(2827, 9589, 2866, 9549), 0), + KARAMJA_VOLCANO_DUNGEON_ELVARG("Karamja Dungeon (Elvarg)", new Location(2826, 9661, 2868, 9603), 0), + KHARAZI_JUNGLE_EAST("Kharazi Jungle (Eastern Section)", new Location(2905, 2930, 2976, 2883), 0), + KHARAZI_JUNGLE_CENTER("Kharazi Jungle (Middle Section)", new Location(2816, 2930, 2905, 2883), 0), + KHARAZI_JUNGLE_WEST("Kharazi Jungle (Western Section)", new Location(2756, 2930, 2816, 2883), 0), + MOR_UL_REK_BANK("TzHaar Bank (Inferno)", new Location(2534, 5146, 2547, 5133), 0), + NATURE_ALTAR("Nature Altar", new Location(2841, 3025, 2846, 3020), 0), + SHILO_VILLAGE_NORTH("Shilo Village North", new Location(2817, 3006, 2878, 2973), 0), + SHILO_VILLAGE_SOUTH("Shilo Village South", new Location(2816, 2972, 2879, 2944), 0), + TAI_BWO_WANNAI("Tai Bwo Wannai", new Location(2770, 3105, 2830, 3050), 0), + TZHAAR_BANK("TzHaar Bank (Jad)", new Location(2437, 5184, 2452, 5172), 0), + TZHAAR_EXIT("Tzhaar City Exit", new Location(2471, 5179, 2490, 5162), 0), + TZHAAR_FIGHT_PITS("TzHaar Fight Pit", new Location(2396, 5183, 2403, 5174), 0), + TZHAAR_INNER_SOUTH_EAST("Tzhaar Inner City South-East", new Location(2499, 5112, 2559, 5057), 0), + TZHAAR_INNER_SOUTH_WEST("Tzhaar Inner City South-West", new Location(2444, 5112, 2499, 5058), 0), + + /*- + * Kharidian Desert + * Agility Pyramid + * Al Kharid + * Bandit Camp (Desert) + * Bedabin Camp + * Citharede Abbey + * Duel Arena + * Nardah + * Pollnivneach + * Smoke Dungeon + * Sophanem + * Uzer + */ + AGILITY_PYRAMID("Agility Pyramid", new Location(3334, 2864, 3386, 2819), 0), + AL_KHARID_BANK("Al Kharid Bank", new Location(3265, 3173, 3272, 3161), 0), + AL_KHARID_GATE("Al Kharid Gate", new Location(3263, 3232, 3271, 3223), 0), + AL_KHARID_GLIDER("Al Kharid_Glider", new Location(3276, 3214, 3283, 3209), 0), + AL_KHARID_MINE("Al Kharid Mine", new Location(3295, 3316, 3303, 3278), 0), + AL_KHARID_PALACE("Al Kharid Palace", new Location(3281, 3178, 3304, 3158), 0), + BEDABIN_CAMP("Bedabin Camp", new Location(3157, 3052, 3188, 3019), 0), + CITHAREDE_ABBEY("Citharede Abbey", new Location(3355, 3190, 3425, 3150), 0), + DESERT_BANDIT_CAMP("Desert Bandit Camp", new Location(3154, 2993, 3189, 2963), 0), + DESERT_QUARRY("Desert Granite Quarry", new Location(3156, 2928, 3184, 2897), 0), + DUEL_ARENA("Duel Arena", new Location(3338, 3252, 3391, 3204), 0), // This polygon is deliberately offset + DUEL_ARENA_BANK("Duel Arena Bank", new Location(3379, 3274, 3386, 3265), 0), + DUEL_ARENA_PALM_TREES("Duel Arena Palm Trees", new Location(3340, 3280, 3354, 3264), 0), + DUEL_ARENA_TELEPORT("Duel Arena Tele", new Location(3308, 3246, 3326, 3225), 0), + FIRE_ALTAR("Fire Altar", new Location(3301, 3256, 3307, 3250), 0), + KALPHITE_LAIR("Kalphite Lair Entrance", new Location(3205, 3124, 3253, 3082), 0), + NARDAH_BANK("Nardah Bank", new Location(3417, 2902, 3437, 2883), 0), + NARDAH_ZONE("Nardah", new Location(3397, 2942, 3453, 2882), 0), + POLLNIVNEACH("Pollnivneach", new Location(3331, 2990, 3379, 2945), 0), + POLLNIVNEACH_POH_PORTAL("Pollnivneach POH Portal", new Location(3333, 3008, 3346, 2995), 0), + POLLNIVNEACH_SMOKE_DUNGEON("Pollnivneach Smoke Dungeon", new Location(3199, 9404, 3327, 9345), 0), + POLLNIVNEACH_SMOKE_DUNGEON_ENTRANCE("Pollnivneach Smoke Dungeon Entrance", new Location(3303, 2967, 3314, 2955), 0), + RUINS_OF_UZER("Uzer", new Location(3463, 3114, 3506, 3075), 0), + SHANTAY_PASS("Shantay Pass", new Location(3293, 3137, 3312, 3116), 0), + SOPHANEM("Sophanem", new Location(3272, 2811, 3324, 2751), 0), + + /*- + * Misthalin + * Barbarian Village + * Digsite + * Draynor Village + * Edgeville + * Grand Exchange + * Lumbridge + * Lumbridge Swamp + * Paterdomus + * Silvarea + * Varrock + * Wizards' Tower + */ + BARB_VILLAGE("Barb Village", new Location(3071, 3448, 3092, 3405), 0), + COOKS_GUILD("Cooks Guild", new Location(3135, 3455, 3155, 3427), 0), + CHAMPIONS_GUILD("Champoins' Guild", new Location(3184, 3364, 3199, 3348), 0), + DARK_WIZARDS("Varrock Dark Wizards", new Location(3220, 3377, 3235, 3361), 0), + DIGSITE("Digsite", new Location(3340, 3435, 3380, 3390), 0), + DIGSITE_EXAM_CENTER("Digsite Exam Center", new Location(3357, 3339, 3367, 3331), 0), + DRAYNOR_MANOR("Draynor Manor", new Location(3089, 3375, 3127, 3350), 0), + DRAYNOR_SEWERS("Draynor Sewers", new Location(3077, 9699, 3135, 9642), 0), + DRYANOR_VILLAGE("Dryanor Village", new Location(3074, 3283, 3112, 3241), 0), + EDGEVILLE_BANK("Edge Bank", new Location(3090, 3499, 3099, 3487), 0), + EDGEVILLE_DUNGEON("Edgeville Dungeon - Main Corridor (Paddewwa Tele)", new Location(3091, 9890, 3105, 9866), 0), + EDGEVILLE_DUNGEON_HILLGIANTS("Varrock Underground - Hill Giants", new Location(3095, 9854, 3125, 9821), 0), + EDGEVILLE_DUNGEON_HOB_GOBLINS("Edgeville Dungeon - Hob Goblins", new Location(3115, 9880, 3143, 9857), 0), + EDGEVILLE_DUNGEON_SLAYER_MASTER("Edgeville Dungeon - Slayer Master", new Location(3128, 9917, 3151, 9881), 0), + GRAND_EXCHANGE("Grand Exchange", new Location(3155, 3499, 3174, 3480), 0), + GRAND_EXCHANGE_AGILITY_SHORTCUT("GE Agility Shortcut", new Location(3136, 3518, 3143, 3511), 0), + GRAND_EXCHANGE_ENTRANCE("GE Entrance", new Location(3159, 3472, 3170, 3460), 0), + HAM_DUNGEON("H.A.M. Dungeon", new Location(3138, 9660, 3191, 9604), 0), + HAM_ENTRANCE("H.A.M. Hideout", new Location(3159, 3254, 3172, 3243), 0), + LUMBERYARD("Lumberyard", new Location(3289, 3520, 3327, 3488), 0), + LUMBRIDGE_BASEMENT("Lumbridge Basement", new Location(3206, 9626, 3221, 9613), 0), + LUMBRIDGE_CASTLE("Lumbridge Castle", new Location(3201, 3235, 3225, 3201), 0), + LUMBRIDGE_SWAMP("Lumby Swamp", new Location(3135, 3203, 3245, 3140), 0), + LUMBRIDGE_SWAMP_CAVES("Lumbridge Swamp Caves", new Location(3142, 9598, 3260, 9537), 0), + PATERDOMUS("Priest in Peril Temple", new Location(3404, 3495, 3419, 3481), 0), + SENNTISTEN_TELEPORT("Senntisten Tele", new Location(3305, 3342, 3319, 3328), 0), + SILVAREA("Rag and Bone Man", new Location(3350, 3505, 3378, 3492), 0), + STRONGHOLD_OF_SECURITY_FLOOR_1("Stronghold of Security - Floor 1 (Minatours)", new Location(1855, 5246, 1917, 5183), 0), + STRONGHOLD_OF_SECURITY_FLOOR_2("Stronghold of Security - Floor 2 (Flesh Crawlers)", new Location(1983, 5246, 2049, 5183), 0), + STRONGHOLD_OF_SECURITY_FLOOR_3("Stronghold of Security - Floor 3 (Catablepons)", new Location(2113, 5310, 2178, 5248), 0), + STRONGHOLD_OF_SECURITY_FLOOR_4("Stronghold of Security - Floor 4 (Ankous)", new Location(2302, 5249, 2367, 5185), 0), + VARROCK_CHURCH("Varrock Church", new Location(3249, 3488, 3259, 3471), 0), + VARROCK_BANK_EAST("Varrock East Bank", new Location(3246, 3428, 3261, 3412), 0), + VARROCK_BANK_WEST("Varrock West Bank", new Location(3172, 3450, 3197, 3425), 0), + VARROCK_MAGIC_SHOP("Varrock Magic Shop", new Location(3249, 3405, 3256, 3398), 0), + VARROCK_MINE("Varrock Mine", new Location(3278, 3372, 3294, 3355), 0), + VARROCK_MOSS_GIANTS("Varrock Sewers - Moss Giants", new Location(3190, 9910, 3153, 9876), 0), + VARROCK_MUSEUM("Varrock Museum", new Location(3249, 3455, 3267, 3442), 0), + VARROCK_PALACE("Varrock Palace", new Location(3198, 3502, 3228, 3455), 0), + VARROCK_SEWERS("Varrock Sewers", new Location(3200, 9918, 3285, 9857), 0), + VARROCK_SQUARE("Varrock Square", new Location(3201, 3444, 3229, 3412), 0), + WIZARDS_TOWER("Wizards Tower", new Location(3093, 3171, 3121, 3146), 0), + + /*- + * Morytania + * Abandoned Mine + * Barrows + * Burgh de Rott + * Canifis + * Darkmeyer + * Fenkenstrain's Castle + * Hallowvale + * Haunted Woods + * Meiyerditch + * Mort'ton + * Mort Myre Swamp + * Port Phasmatys + * Slepe + * The Sisterhood Sanctuary (Nightmare Dungeon) + */ + ABANDONED_MINE("Haunted Mine", new Location(3426, 3260, 3459, 3205), 0), + BARROWS("Barrows", new Location(3546, 3314, 3583, 3268), 0), + BARROWS_CRYPT("Barrows Crypt", new Location(3523, 9723, 3580, 9666), 0), + BURGH_DE_ROTT("Burgh de Rott", new Location(3474, 3247, 3535, 3189), 0), + CANIFIS_BANK("Canifis Bank", new Location(3508, 3483, 3516, 3474), 0), + CANIFIS_ZONE("Canifis", new Location(3472, 3506, 3519, 3467), 0), + CROMBWICK_MANOR("Crombwick Manor in Slepe", new Location(3710, 3377, 3742, 3341), 0), + DARKMEYER_BANK("Darkmeyer Bank", new Location(3600, 3370, 3610, 3364), 0), + DARKMEYER_ZONE("Darkmeyer", new Location(3592, 3392, 3662, 3331), 0), + FENKENSTRAINS_CASTLE("Fenkenstrain's Castle", new Location(3533, 3568, 3564, 3534), 0), + ECTOFUNTUS("Ectofuntus", new Location(3651, 3528, 3668, 3510), 0), + HALLOWED_SEPULCHER_ENTRANCE("Hallowed Sepulcher Entrance", new Location(3649, 3389, 3659, 3379), 0), + HALLOWED_SEPULCHER_LOBBY("Hallowed Sepulcher Lobby", new Location(2383, 5996, 2417, 5963), 0), + MORT_TON("Mort'ton", new Location(3473, 3301, 3504, 3271), 0), + MORYTANIA_FARM_PATCH("Morytania Farming Patch", new Location(3596, 3531, 3607, 3520), 0), + MORYTANIA_SWAMP_NORTH("Northern half of Morytania Swamp", new Location(3412, 3450, 3481, 3410), 0), + MORYTANIA_SWAMP_SOUTH("Southern half of Morytania Swamp", new Location(3412, 3410, 3481, 3370), 0), + NATURE_GROTTO("Nature Grotto", new Location(3410, 3356, 3461, 3322), 0), + NIGHTMARE_BOSS("The Nightmare", new Location(3798, 9769, 3818, 9749), 1), + PORT_PHASMATYS_BANK("Port Phasmatys Bank", new Location(3686, 3471, 3699, 3461), 0), + PORT_PHASMATYS_DOCKS("Port Phasmatys Docks", new Location(3689, 3512, 3711, 3481), 0), + PORT_PHASMATYS_PUB("Port Phasmatys Pub", new Location(3671, 3499, 3681, 3489), 0), + PORT_PHASMATYS_SOUTH_GATE("Port Phasmatys South Gate", new Location(3663, 3455, 3674, 3445), 0), + SALVE_GRAVEYARD("Salve Graveyard", new Location(3425, 3468, 3438, 3457), 0), + SISTERHOOD_SANCTUARY("Sisterhood Sanctuary (Slepe Dungeon)", new Location(3720, 9832, 3898, 9690), 1), + SLAYER_TOWER("Slayer Tower", new Location(3403, 3579, 3454, 3530), 0), + SLEPE("Slepe", new Location(3692, 3381, 3750, 3293), 0), + SWAMP_LIZARDS("Swamp Lizards", new Location(3521, 3451, 3568, 3426), 0), + VER_SINHAZA("ToB", new Location(3640, 3236, 3685, 3202), 0), + + /*- + * Tirannwn + * Arandar + * Gwenith + * Iowerth Dungeon + * Isafdar + * Lletya + * Mynydd + * Poison Waste + * Port Tyras + * Prifddinas + * Tyras Camp + * Zul-Andra + */ + LLETYA("Lletya", new Location(2312, 3196, 2362, 3145), 0), + ELF_CAMP("Elf Camp", new Location(2212, 3265, 2182, 3237), 0), + GWENTIH("Gwenith", new Location(2187, 3425, 2220, 3393), 0), + PRIFDDINAS("Prifddinas", new Location(3221, 6056, 3241, 6039), 0), // Fallback if there are gaps + PRIFDDINAS_BANK_NORTH("Prifddinas North Bank", new Location(3254, 6113, 3260, 6101), 0), + PRIFDDINAS_BANK_SOUTH("Prifddinas South Bank", new Location(3288, 6067, 3304, 6052), 0), + PRIFDDINAS_CITY_CENTER("Prifddinas Center", new Location(3246, 6100, 3281, 6065), 0), + PRIFDDINAS_CITY_E("Eastern Part of Prifddinas", new Location(3282, 6100, 3305, 6065), 0), + PRIFDDINAS_CITY_N("Northern Part of Prifddinas", new Location(3246, 6124, 3281, 6101), 0), + PRIFDDINAS_CITY_NE("North-Eastern Prifddinas", new Location(3282, 6136, 3319, 6101), 0), + PRIFDDINAS_CITY_NW("North-Western Prifddinas", new Location(3208, 6135, 3245, 6101), 0), + PRIFDDINAS_CITY_S("Southern Part of Prifddinas", new Location(3246, 6064, 3281, 6040), 0), + PRIFDDINAS_CITY_SE("South-Eastern Prifddinas", new Location(3282, 6039, 3321, 6023), 0), + PRIFDDINAS_CITY_SW("South-Western Prifddinas", new Location(3207, 6064, 3245, 6023), 0), + PRIFDDINAS_CITY_W("Western Part of Prifddinas", new Location(3222, 6100, 3245, 6065), 0), + PRIFDDINAS_GATE_EAST("Prifddinas East Gate (Arandar / Elven Pass)", new Location(2297, 3334, 2323, 3305), 0), + PRIFDDINAS_GATE_EAST_INSIDE("Prifddinas East Gate", new Location(3306, 6100, 3319, 6064), 0), + PRIFDDINAS_GATE_NORTH("Prifddinas North Gate", new Location(2230, 3387, 2249, 3384), 0), + PRIFDDINAS_GATE_NORTH_INSIDE("Prifddinas North Gate", new Location(3246, 6136, 3281, 6125), 0), + PRIFDDINAS_GATE_SOUTH("Prifddinas South Gate", new Location(2229, 3270, 2252, 3251), 0), + PRIFDDINAS_GATE_SOUTH_INSIDE("Prifddinas South Gate", new Location(3246, 6039, 3281, 6024), 0), + PRIFDDINAS_GATE_WEST("Prifddinas West Gate (Docks)", new Location(2154, 3338, 2182, 3317), 0), + PRIFDDINAS_GATE_WEST_INSIDE("Prifddinas West Gate", new Location(3207, 6100, 3221, 6065), 0), + PRIFDDINAS_GAUNTLET_PORTAL("Prifddinas Gauntlet Portal", new Location(3224, 6112, 3243, 6087), 0), + PRIFDDINAS_POH_PORTAL("Prifddinas POH Portal", new Location(3230, 6081, 3247, 6067), 0), + PRIFDDINAS_RED_CHINS("Prifddinas Red Chins", new Location(2255, 3418, 2283, 3397), 0), + PRIFDDINAS_SLAYER_CAVE_ENTRANCE("Prifddinas Slayer Cave Entrance", new Location(3221, 6056, 3241, 6039), 0), + PRIFDDINAS_ZALCANO_ENTRANCE("Prifddinas Zalcano Entrance", new Location(3277, 6065, 3287, 6053), 0), + TYRAS_CAMP("Tyras Camp", new Location(2168, 3163, 2201, 3134), 0), + TYRAS_DOCKS("Port Tyras", new Location(2135, 3133, 2167, 3110), 0), + ZALCANO("Zalcano", new Location(3019, 6074, 3048, 6035), 0), + GAUNTLET_LOBBY("Gauntlet Lobby", new Location(3025, 6130, 3040, 6115), 1), + ZUL_ANDRA("Zul-Andra", new Location(2182, 3070, 2214, 3042), 0), + + /*- + * Troll Country + * Death Plateau + * God Wars Dungeon + * Ice Path + * Troll Stronghold + * Trollheim + * Trollweiss Mountain + * Weiss + */ + DEATH_PLATEAU("Death Plateau", new Location(2838, 3610, 2880, 3580), 0), + GOD_WARS_DUNGEON("GWD", new Location(2820, 5375, 2944, 5253), 2), + GOD_WARS_DUNGEON_ENTRANCE("GWD Entrance", new Location(2904, 3756, 2921, 3742), 0), + TROLL_STRONGHOLD("Troll Stronghold", new Location(2836, 3698, 2862, 3659), 0), + TROLLHEIM_TELEPORT("Trollheim Tele", new Location(2882, 3685, 2899, 3669), 0), + WEISS("Weiss", new Location(2837, 3967, 2890, 3914), 0), + + /* + * Dungeons, Caves, Islands and other miscellaneous areas + */ + ABYSS("Abyss", new Location(3010, 4862, 3068, 4804), 0), + ABYSSAL_AREA("Abyssal Area", new Location(3008, 4926, 3071, 4864), 0), + ABYSSAL_NEXUS("Abyssal Nexus", new Location(3010, 4803, 3068, 4756), 0), + BLAST_FURNACE("Blast Furnace", new Location(1934, 4974, 1958, 4955), 0), + CAVE_HORROR_ENTRANCE("Mos Le'Harmless Cave Entrance (Cave Horrors)", new Location(3737, 2986, 3759, 2961), 0), + COSMIC_ALTAR("Zanaris Cosmic Altar", new Location(2400, 4387, 2425, 4367), 0), + DWARVEN_MINE_CAMP("Dwarven Mine - North Exit", new Location(3013, 9854, 3033, 9820), 0), + DWARVEN_MINE_CART("Dwarven Mine - Cart Transport", new Location(2988, 9849, 3006, 9821), 0), + DWARVEN_MINE_FALADOR("Dwarven Mine - Falador Exit", new Location(3030, 9788, 3062, 9758), 0), + GORAK_PLANE("Gorak Plane", new Location(3006, 5377, 3070, 5313), 0), + FISHER_REALM("Fisher Realm (Fairy Ring BJR)", new Location(2622, 4738, 2688, 4667), 0), + HARMONY("Harmony Island", new Location(3778, 2879, 3835, 2816), 0), + MINING_GUILD("Mining Guild", new Location(3008, 9756, 3061, 9698), 0), + MOLE_LAIR("Mole Lair", new Location(1730, 5246, 1787, 5131), 0), + MOS_LE_HARMLESS("Mos Le'Harmless", new Location(3649, 3005, 3709, 2958), 0), + MOS_LE_HARMLESS_DOCKS("Mos Le'Harmless Docks", new Location(3664, 2957, 3692, 2929), 0), + MOTHERLODE_MINE("Motherlode Mine", new Location(3713, 5695, 3777, 5632), 0), + PEST_CONTROL("Pest Control", new Location(2630, 2679, 2682, 2627), 0), + PURO_PURO("Puro-Puro", new Location(2561, 4349, 2622, 4289), 0), + SORCERESS_GARDEN("Sorceress's Garden", new Location(2884, 5499, 2938, 5444), 0), + TROUBLE_BREWING("Trouble Brewing", new Location(3774, 3024, 3843, 2942), 0), + ZANARIS_BANK("Zanaris Bank", new Location(2374, 4468, 2390, 4451), 0), + ZANARIS("Zanaris", new Location(2398, 4478, 2460, 4419), 0), + + /* + * Wilderness Locations + */ + ANNAKARL_TELEPORT("GDZ", new Location(3279, 3895, 3296, 3875), 0), + AXE_HUT("Axe Hut", new Location(3187, 3962, 3194, 3957), 0), + BANDIT_CAMP("Bandit Camp", new Location(3017, 3712, 3059, 3681), 0), + BLACK_SALAMANDERS("Black Salamanders", new Location(3291, 3677, 3301, 3664), 0), + CALLISTO("Callisto", new Location(3266, 3863, 3315, 3827), 0), + CEMETERY("Cemetery", new Location(2956, 3767, 2996, 3736), 0), + CHAOS_ALTAR_PRAYER("Chaos Altar", new Location(2945, 3826, 2970, 3813), 0), + CHAOS_ALTAR_RUNECRAFT("Chaos Runecrafting Altar", new Location(3055, 3596, 3067, 3585), 0), + CHAOS_FANATIC("Chaos Fanatic", new Location(2971, 3854, 2992, 3834), 0), + CHAOS_TEMPLE("Chaos Temple", new Location(3220, 3632, 3255, 3593), 0), + BLACK_CHINCHOMPAS("Chins", new Location(3128, 3792, 3160, 3754), 0), + CORP_CAVE("Corp Cave", new Location(3201, 3684, 3219, 3672), 0), + CRAZY_ARCHAEOLOGIST("Crazy Archaeologist", new Location(2952, 3709, 2985, 3678), 0), + DARK_CRAB_TELEPORT("Dark Crab Tele", new Location(3343, 3800, 3355, 3780), 0), + DARK_WARRIORS("Dark Warriors", new Location(3014, 3648, 3046, 3616), 0), + DEEP_WILDERNESS_DUNGEON("Deep Wilderness Dungeon", new Location(3038, 10330, 3053, 10305), 0), + DEEP_WILDERNESS_DUNGEON_ENTRANCE("Deep Wild Dungeon", new Location(3042, 3929, 3051, 3920), 0), + DEEP_WILDERNESS_DUNGEON_FIRE_GIANTS("Deep Wilderness Dungeon Fire Giants", new Location(3035, 10349, 3060, 10331), 0), + DEEP_WILDERNESS_DUNGEON_WINES("Deep Wilderness Dungeon Wines", new Location(3013, 10365, 3060, 10350), 0), + DWARVES("Dwarves", new Location(3230, 3805, 3264, 3779), 0), + EDGEVILLE_DUNGEON_EARTH_WARRIORS("Edgeville Dungeon - Earth Warriors", new Location(3114, 9999, 3129, 9960), 0), + EDGEVILLE_DUNGEON_CHAOS_DRUIDS("Edgeville Dungeon - Chaos Druids", new Location(3104, 9944, 3135, 9923), 0), + EDGEVILLE_DUNGEON_SPIDERS("Edgeville Dungeon - Spiders", new Location(3104, 9959, 3135, 9945), 0), + EDGEVILLE_DUNGEON_BLACK_DEMONS("Edgeville Dungeon - Black Demons", new Location(3077, 9966, 3103, 9941), 0), + // is this label description intuitive? + ENTS("Ents", new Location(3300, 3627, 3320, 3584), 0), + FEROX_ENCLAVE("Ferox Enclave", new Location(3119, 3646, 3160, 3616), 0), + GLORY_HILL("Glory Hill", new Location(3331, 3890, 3348, 3866), 0), + GLORY_HOLE("Glory Hole", new Location(3352, 3897, 3386, 3869), 0), + CARRALLANGAR_GRAVES("Graves", new Location(3128, 3686, 3181, 3658), 0), + GREEN_DRAGONS_EAST("East Drags", new Location(3326, 3704, 3365, 3671), 0), + GREEN_DRAGONS_GRAVEYARD("Graveyard Drags", new Location(3129, 3717, 3172, 3691), 0), + GREEN_DRAGONS_WEST("West Drags", new Location(2960, 3627, 2992, 3598), 0), + HOBGOBLINS("Hobgoblins", new Location(3073, 3775, 3104, 3745), 0), + ICE_GATE("Ice Gate", new Location(2945, 3913, 2978, 3878), 0), + ICE_ROCK("Ice Rock", new Location(2957, 3942, 2984, 3929), 0), + KBD_CAGE("KBD CAGE", new Location(3007, 3855, 3021, 3839), 0), + LAVA_DRAGON_GAP("Gap", new Location(3238, 3855, 3258, 3841), 0), + LAVA_DRAGON_ISLE("Lava Drags", new Location(3175, 3857, 3221, 3805), 0), + LAVA_MAZE_DUNGEON("Lava Maze Dungeon", new Location(3075, 10239, 3008, 10291), 0), + LAVA_MAZE_TELE("Lava Maze Tele", new Location(3019, 3842, 3044, 3812), 0), + MAGE_ARENA("Mage Arena", new Location(3088, 3949, 3123, 3919), 0), + MAGE_BANK("Mage Bank", new Location(3082, 3960, 3103, 3952), 0), + MAGE_BANK_SAFE_ZONE("Mage Bank Safe Zone", new Location(2526, 4727, 2550, 4707), 0), + NEW_GATE("New Gate", new Location(3348, 3890, 3325, 3911), 0), + OBELISK_13("13s Port", new Location(3152, 3624, 3160, 3616), 0), + OBELISK_19("19s", new Location(3220, 3672, 3234, 3660), 0), +// OBELISK_27("27 GWDs Portal", new Location(3031, 3736, 3039, 3728), 0), + OBELISK_35("36 Port", new Location(3097, 3804, 3115, 3785), 0), + OBELISK_44("44s", new Location(2973, 3870, 2987, 3859), 0), + OBELISK_50("50 ports", new Location(3301, 3923, 3315, 3909), 0), + OLD_GATE("Old Gate", new Location(3211, 3906, 3238, 3882), 0), + PIRATE_HUT("Pirate Hut", new Location(3037, 3959, 3045, 3948), 0), + POISON_SPIDERS("Poison Spiders", new Location(3282, 3803, 3302, 3785), 0), + REV_CAVE_AGILITY_65("Rev Cave Green Dragon Agility Jump", new Location(3216, 10090, 3226, 10080), 0), + REV_CAVE_AGILITY_75_1("Rev Cave 75 Agility Jump", new Location(3195, 10200, 3212, 10190), 0), + REV_CAVE_AGILITY_75_2("Rev Cave 75 Agility Jump (North of Ankous)", new Location(3173, 10214, 3186, 10205), 0), + REV_CAVE_AGILITY_89("Rev Cave 89 Agility Jump", new Location(3233, 10148, 3244, 10140), 0), + REV_CAVE_ANKOUS("Rev Cave Ankous", new Location(3160, 10204, 3191, 10177), 0), + REV_CAVE_BLACK_DEMONS("Rev Cave Black Demons", new Location(3158, 10171, 3187, 10145), 0), + REV_CAVE_BLACK_DRAGS("Rev Cave Black Drags", new Location(3223, 10216, 3254, 10190), 0), + REV_CAVE_CORRIDOR_NORTH("Revenant Cave Corridor", new Location(3255, 10213, 3263, 10191), 0), + REV_CAVE_CORRIDOR_SOUTH("Rev Cave Green Dragon Corridor", new Location(3238, 10106, 3252, 10077), 0), + REV_CAVE_ENTRANCE_NORTH("Rev Entrance", new Location(3118, 3837, 3142, 3818), 0), + REV_CAVE_ENTRANCE_SOUTH("South Rev Entrance", new Location(3071, 3660, 3092, 3645), 0), + REV_CAVE_EXIT_NORTH("Rev Cave North Exit", new Location(3238, 10236, 3243, 10231), 0), + REV_CAVE_EXIT_SOUTH("Rev Cave South Exit", new Location(3190, 10062, 3215, 10052), 0), + REV_CAVE_GREATER_DEMONS("Rev Cave Greater Demons", new Location(3210, 10140, 3240, 10115), 0), + REV_CAVE_GREEN_DRAGONS_1("Rev Cave Green Dragons", new Location(3215, 10078, 3234, 10052), 0), + REV_CAVE_GREEN_DRAGONS_2("Rev Cave Green Dragons", new Location(3200, 10106, 3231, 10091), 0), + REV_CAVE_HELL_HOUNDS("Rev Cave Hell Hounds", new Location(3190, 10078, 3210, 10063), 0), + REV_CAVE_ICE_GIANTS("Rev Cave Ice Giants", new Location(3200, 10173, 3221, 10155), 0), + REV_CAVE_LESSER_DEMONS("Rev Cave Lesser Demons", new Location(3143, 10125, 3176, 10104), 0), + REVENANT_DARK_BEAST("Revenant Dark Beast", new Location(3244, 10154, 3260, 10136), 0), + REVENANT_MAIN_CHAMBER("Main Rev Chamber", new Location(3227, 10187, 3261, 10157), 0), + ROGUE_CASTLE("Rogue Castle", new Location(3275, 3947, 3299, 3920), 0), + RUNE_ROCKS("Rune Rocks", new Location(3055, 3890, 3072, 3876), 0), + SCORPIA("Scorpia", new Location(3216, 3949, 3248, 3935), 0), + SPERM_HILL("Sperm Hill", new Location(3282, 3687, 3300, 3677), 0), + SPIDER_HILL("Spider Hill", new Location(3156, 3896, 3182, 3871), 0), + VENENATIS("Venenatis", new Location(3298, 3759, 3353, 3722), 0), + VETTION("Vet'tion", new Location(3183, 3796, 3227, 3765), 0), + VOLCANO("Volcano", new Location(3345, 3957, 3390, 3916), 0), + WEB("Web", new Location(3153, 3961, 3163, 3948), 0), + WILDY_AGILITY_COURSE("Wildy Agility Course", new Location(2988, 3967, 3008, 3906), 0), + WILDERNESS_GOD_WARS_DUNGEON("God Wars Dungeon", new Location(3010, 3745, 3027, 3727), 0), + WILDERNESS_GOD_WARS("Wildy GWD Chamber", new Location(3012, 10168, 3068, 10113), 0), + WILDERNESS_LEVER("Lever", new Location(3149, 3933, 3162, 3917), 0), + WILDERNESS_RESOURCE_AREA("Resource Area", new Location(3174, 3946, 3195, 3923), 0), + ZAMORAK_MAGE("Zammy Mage", new Location(3099, 3561, 3107, 3553), 0); + + @Getter + private final String name; + @Getter + private final WorldArea worldArea; + @Getter + private final Location location; + @Getter + private static final Map LOCATION_MAP; + + static + { + ImmutableMap.Builder builder = ImmutableMap.builder(); + + for (WorldLocation value : values()) + { + builder.put(value.getWorldArea(), value.getName()); + } + + LOCATION_MAP = builder.build(); + } + + /** + * Creates a location used to get the name of a location by a WorldPoint + * + * @param name - The name that is used to represent the area in overlays etc + * @param location - A Location made out of 4 points on the world map + * @param plane - The plane of the World Area + */ + WorldLocation(String name, Location location, int plane) + { + this.name = name; + this.location = location; + this.worldArea = new WorldArea(location.x, location.y, location.width, location.height, plane); + } + + /** + * Returns all locations that aren't in the wild + * + * @return - A Collection of non-wilderness WorldLocations + */ + public static Collection getNonWildernessLocations() + { + return Arrays.stream(WorldLocation.values()).filter(loc -> + PvPUtil.getWildernessLevelFrom(loc.worldArea.toWorldPoint()) < 0).collect(Collectors.toList()); + } + + /** + * Returns only the WorldLocations that are in the wilderness + * + * @return - A Collection of WorldLocations in the wilderness + */ + public static Collection getWildernessLocations() + { + return Arrays.stream(WorldLocation.values()).filter(loc -> + PvPUtil.getWildernessLevelFrom(loc.worldArea.toWorldPoint()) > 0).collect(Collectors.toList()); + } + + /** + * Returns the WorldLocation that a WorldPoint is in, or the closest WorldLocation to the point + * + * @param worldPoint - the WorldPoint to find the WorldLocation of + * @return - Containing location or closest location if it isn't in any + */ + public static String location(WorldPoint worldPoint) + { + int dist = 128; // x2 Region lengths + String s = ""; + WorldArea closestArea = null; + + for (Map.Entry entry : LOCATION_MAP.entrySet()) + { + final WorldArea worldArea = entry.getKey(); + + if (worldArea.toWorldPointList().contains(worldPoint)) + { + s = entry.getValue(); + return s; + } + + final int distTo = worldArea.distanceTo(worldPoint); + + if (distTo < dist) + { + dist = distTo; + closestArea = worldArea; + } + } + + if (closestArea == null) + { + return s; + } + + if (worldPoint.getY() > closestArea.toWorldPoint().getY() + closestArea.getHeight()) + { + s = s + "N"; + } + + if (worldPoint.getY() < closestArea.toWorldPoint().getY()) + { + s = s + "S"; + } + + if (worldPoint.getX() < closestArea.toWorldPoint().getX()) + { + s = s + "W"; + } + + if (worldPoint.getX() > (closestArea.toWorldPoint().getX() + closestArea.getWidth())) + { + s = s + "E"; + } + + s = s + " of "; + s = s + LOCATION_MAP.get(closestArea); + + if (s.startsWith(" of ")) + { + s = s.substring(3); + } + + return s; + } + + + public static class Location + { + @Getter + private final int x; + @Getter + private final int y; + @Getter + private final int x1; + @Getter + private final int y1; + final int width; + final int height; + + Location(int x, int y, int x1, int y1) + { + this.x = Math.min(x, x1); + this.y = Math.min(y, y1); + this.x1 = Math.max(x, x1); + this.y1 = Math.max(y, y1); + this.width = Math.abs(x1 - x); + this.height = Math.abs(y1 - y); + } + + @Override + public String toString() + { + return "Location{" + + "x=" + x + + ", y=" + y + + ", width=" + width + + ", height=" + height + + '}'; + } + } + + @Override + public String toString() + { + return "WorldLocation{" + + "name='" + name + '\'' + + ", worldArea=" + worldArea + + '}'; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java b/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java index 0b21683877..0c4f611be5 100644 --- a/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java +++ b/runelite-client/src/main/java/com/openosrs/client/ui/overlay/OverlayUtil.java @@ -1,14 +1,24 @@ package com.openosrs.client.ui.overlay; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.image.BufferedImage; +import java.util.List; import net.runelite.api.*; import net.runelite.api.Point; import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; import net.runelite.api.coords.WorldPoint; import net.runelite.api.vars.InterfaceTab; import net.runelite.api.widgets.Widget; -import java.awt.*; public class OverlayUtil extends net.runelite.client.ui.overlay.OverlayUtil { @@ -81,4 +91,51 @@ public class OverlayUtil extends net.runelite.client.ui.overlay.OverlayUtil renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); } } + + public static void setProgressIcon(Graphics2D graphics, Point point, BufferedImage currentPhaseIcon, int totalWidth, int bgPadding, int currentPosX, Color colorIconBackground, int overlayIconDistance, Color colorIconBorder, Color colorIconBorderFill) + { + graphics.setStroke(new BasicStroke(2)); + graphics.setColor(colorIconBackground); + graphics.fillOval( + point.getX() - totalWidth / 2 + currentPosX - bgPadding, + point.getY() - currentPhaseIcon.getHeight() / 2 - overlayIconDistance - bgPadding, + currentPhaseIcon.getWidth() + bgPadding * 2, + currentPhaseIcon.getHeight() + bgPadding * 2); + + graphics.setColor(colorIconBorder); + graphics.drawOval( + point.getX() - totalWidth / 2 + currentPosX - bgPadding, + point.getY() - currentPhaseIcon.getHeight() / 2 - overlayIconDistance - bgPadding, + currentPhaseIcon.getWidth() + bgPadding * 2, + currentPhaseIcon.getHeight() + bgPadding * 2); + + graphics.drawImage( + currentPhaseIcon, + point.getX() - totalWidth / 2 + currentPosX, + point.getY() - currentPhaseIcon.getHeight() / 2 - overlayIconDistance, + null); + + graphics.setColor(colorIconBorderFill); + } + + public static List getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder) + { + List little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList(); + List big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList(); + if (!includeUnder) + { + big.removeIf(little::contains); + } + return big; + } + + public static void renderFilledPolygon(Graphics2D graphics, Shape poly, Color color) + { + graphics.setColor(color); + final Stroke originalStroke = graphics.getStroke(); + graphics.setStroke(new BasicStroke(2)); + graphics.draw(poly); + graphics.fill(poly); + graphics.setStroke(originalStroke); + } } diff --git a/runelite-client/src/main/java/com/openosrs/client/util/PvPUtil.java b/runelite-client/src/main/java/com/openosrs/client/util/PvPUtil.java new file mode 100644 index 0000000000..1f0120c75a --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/util/PvPUtil.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2019. PKLite - All Rights Reserved + * Unauthorized modification, distribution, or possession of this source file, via any medium is strictly prohibited. + * Proprietary and confidential. Refer to PKLite License file for more information on + * full terms of this copyright and to determine what constitutes authorized use. + * Written by PKLite(ST0NEWALL, others) , 2019 + * + */ +package com.openosrs.client.util; + +import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemComposition; +import net.runelite.api.Player; +import net.runelite.api.Varbits; +import net.runelite.api.WorldType; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.geometry.Cuboid; +import net.runelite.client.game.ItemManager; +import net.runelite.client.util.QuantityFormatter; +import org.apache.commons.lang3.ArrayUtils; +import java.awt.Polygon; +import java.util.Comparator; +import java.util.Objects; +import java.util.TreeMap; + +public class PvPUtil +{ + private static final Polygon NOT_WILDERNESS_BLACK_KNIGHTS = new Polygon( // this is black knights castle + new int[]{2994, 2995, 2996, 2996, 2994, 2994, 2997, 2998, 2998, 2999, 3000, 3001, 3002, 3003, 3004, 3005, 3005, + 3005, 3019, 3020, 3022, 3023, 3024, 3025, 3026, 3026, 3027, 3027, 3028, 3028, 3029, 3029, 3030, 3030, 3031, + 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3037}, + new int[]{3525, 3526, 3527, 3529, 3529, 3534, 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541, 3542, 3543, 3544, + 3545, 3545, 3546, 3546, 3545, 3544, 3543, 3543, 3542, 3541, 3540, 3539, 3537, 3536, 3535, 3534, 3533, 3532, + 3531, 3530, 3529, 3528, 3527, 3526, 3526, 3525}, + 43 + ); + private static final Cuboid MAIN_WILDERNESS_CUBOID = new Cuboid(2944, 3525, 0, 3391, 4351, 3); + private static final Cuboid GOD_WARS_WILDERNESS_CUBOID = new Cuboid(3008, 10112, 0, 3071, 10175, 3); + private static final Cuboid WILDERNESS_UNDERGROUND_CUBOID = new Cuboid(2944, 9920, 0, 3391, 10879, 3); + + /** + * Gets the wilderness level based on a world point + * Java reimplementation of clientscript 384 [proc,wilderness_level] + * + * @param point the point in the world to get the wilderness level for + * @return the int representing the wilderness level + */ + public static int getWildernessLevelFrom(WorldPoint point) + { + if (MAIN_WILDERNESS_CUBOID.contains(point)) + { + if (NOT_WILDERNESS_BLACK_KNIGHTS.contains(point.getX(), point.getY())) + { + return 0; + } + + return ((point.getY() - 3520) / 8) + 1; // calc(((coordz(coord) - (55 * 64)) / 8) + 1) + } + else if (GOD_WARS_WILDERNESS_CUBOID.contains(point)) + { + return ((point.getY() - 9920) / 8) - 1; // calc(((coordz(coord) - (155 * 64)) / 8) - 1) + } + else if (WILDERNESS_UNDERGROUND_CUBOID.contains(point)) + { + return ((point.getY() - 9920) / 8) + 1; // calc(((coordz(coord) - (155 * 64)) / 8) + 1) + } + return 0; + } + + /** + * Determines if another player is attackable based off of wilderness level and combat levels + * + * @param client The client of the local player + * @param player the player to determine attackability + * @return returns true if the player is attackable, false otherwise + */ + public static boolean isAttackable(Client client, Player player) + { + int wildernessLevel = 0; + + if (WorldType.isDeadmanWorld(client.getWorldType())) + { + return true; + } + if (WorldType.isPvpWorld(client.getWorldType())) + { + wildernessLevel += 15; + } + if (client.getVar(Varbits.IN_WILDERNESS) == 1) + { + wildernessLevel += getWildernessLevelFrom(client.getLocalPlayer().getWorldLocation()); + } + return wildernessLevel != 0 && Math.abs(client.getLocalPlayer().getCombatLevel() - player.getCombatLevel()) <= wildernessLevel; + } + + public static int calculateRisk(Client client, ItemManager itemManager) + { + if (client.getItemContainer(InventoryID.EQUIPMENT) == null) + { + return 0; + } + if (client.getItemContainer(InventoryID.INVENTORY).getItems() == null) + { + return 0; + } + Item[] items = ArrayUtils.addAll(Objects.requireNonNull(client.getItemContainer(InventoryID.EQUIPMENT)).getItems(), + Objects.requireNonNull(client.getItemContainer(InventoryID.INVENTORY)).getItems()); + TreeMap priceMap = new TreeMap<>(Comparator.comparingInt(Integer::intValue)); + int wealth = 0; + for (Item i : items) + { + int value = (itemManager.getItemPrice(i.getId()) * i.getQuantity()); + + final ItemComposition itemComposition = itemManager.getItemComposition(i.getId()); + if (!itemComposition.isTradeable() && value == 0) + { + value = itemComposition.getPrice() * i.getQuantity(); + priceMap.put(value, i); + } + else + { + value = itemManager.getItemPrice(i.getId()) * i.getQuantity(); + if (i.getId() > 0 && value > 0) + { + priceMap.put(value, i); + } + } + wealth += value; + } + return Integer.parseInt(QuantityFormatter.quantityToRSDecimalStack(priceMap.keySet().stream().mapToInt(Integer::intValue).sum())); + + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/util/WeaponMap.java b/runelite-client/src/main/java/com/openosrs/client/util/WeaponMap.java new file mode 100644 index 0000000000..8dda59ad46 --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/util/WeaponMap.java @@ -0,0 +1,832 @@ +package com.openosrs.client.util; + +import java.util.HashMap; +import net.runelite.api.ItemID; + +public class WeaponMap +{ + public static HashMap StyleMap = new HashMap<>(); + + static + { + //Melee + StyleMap.put(ItemID._3RD_AGE_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID._3RD_AGE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID._3RD_AGE_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_BLUDGEON, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_DAGGER_P, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_DAGGER_P_13269, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_DAGGER_P_13271, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_TENTACLE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_WHIP, WeaponStyle.MELEE); + StyleMap.put(ItemID.ABYSSAL_WHIP_20405, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_DAGGERP_5676, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_DAGGERP_5694, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SPEARP_5712, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SPEARP_5726, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ADAMANT_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ALE_OF_THE_GODS, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANCIENT_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANGER_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANGER_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANGER_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ANGER_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.AMYS_SAW, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARCEUUS_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARCLIGHT, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARMADYL_GODSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARMADYL_GODSWORD_20593, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARMADYL_GODSWORD_22665, WeaponStyle.MELEE); + StyleMap.put(ItemID.ARMADYL_GODSWORD_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ASSORTED_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BANDOS_GODSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BANDOS_GODSWORD_20782, WeaponStyle.MELEE); + StyleMap.put(ItemID.BANDOS_GODSWORD_21060, WeaponStyle.MELEE); + StyleMap.put(ItemID.BANDOS_GODSWORD_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BARBTAIL_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.BARRELCHEST_ANCHOR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BEACH_BOXING_GLOVES, WeaponStyle.MELEE); + StyleMap.put(ItemID.BEACH_BOXING_GLOVES_11706, WeaponStyle.MELEE); + StyleMap.put(ItemID.BIRTHDAY_BALLOONS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BIRTHDAY_CAKE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_DAGGERP_5682, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_DAGGERP_5700, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SALAMANDER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SPEARP_5734, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SPEARP_5736, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLACK_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLADE_OF_SAELDOR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLADE_OF_SAELDOR_C, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLADE_OF_SAELDOR_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLESSED_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLISTERWOOD_SICKLE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLUE_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLUE_FLOWERS_8936, WeaponStyle.MELEE); + StyleMap.put(ItemID.BLURITE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_CLUB, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_DAGGER_P, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_DAGGER_P_8876, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_DAGGER_P_8878, WeaponStyle.MELEE); + StyleMap.put(ItemID.BONE_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BOXING_GLOVES, WeaponStyle.MELEE); + StyleMap.put(ItemID.BOXING_GLOVES_7673, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRINE_SABRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_DAGGERP_5670, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_DAGGERP_5688, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SPEARP_5704, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SPEARP_5718, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRONZE_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.BRUMA_TORCH, WeaponStyle.MELEE); + StyleMap.put(ItemID.BUTTERFLY_NET, WeaponStyle.MELEE); + StyleMap.put(ItemID.CANDY_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CATTLEPROD, WeaponStyle.MELEE); + StyleMap.put(ItemID.CHAOTIC_HANDEGG, WeaponStyle.MELEE); + StyleMap.put(ItemID.CLEAVER, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_HALBERD_ATTUNED, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_HALBERD_BASIC, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_HALBERD_PERFECTED, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CORRUPTED_SCEPTRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRIER_BELL, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_AXE_23862, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_AXE_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_110, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_110_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_210, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_210_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_24125, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_310, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_310_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_410, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_410_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_510, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_510_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_610, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_610_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_710, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_710_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_810, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_810_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_910, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_910_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_ATTUNED, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_BASIC, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_FULL, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_FULL_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HALBERD_PERFECTED, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HARPOON_23864, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_HARPOON_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_PICKAXE_23863, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_PICKAXE_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CRYSTAL_SCEPTRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.CURSED_GOBLIN_HAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.DARKLIGHT, WeaponStyle.MELEE); + StyleMap.put(ItemID.DARK_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.DECORATIVE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DECORATIVE_SWORD_4503, WeaponStyle.MELEE); + StyleMap.put(ItemID.DECORATIVE_SWORD_4508, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_0, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_100, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_25, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_50, WeaponStyle.MELEE); + StyleMap.put(ItemID.DHAROKS_GREATAXE_75, WeaponStyle.MELEE); + StyleMap.put(ItemID.DINHS_BULWARK, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_2H_SWORD_20559, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_CLAWS_20784, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGER_20407, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGERP_5680, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_DAGGERP_5698, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTAKP, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTAP, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTAP_22737, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HASTAP_22740, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_HUNTER_LANCE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_PICKAXE_12797, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_PICKAXE_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SCIMITAR_20406, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SCIMITAR_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SPEARP_5716, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SPEARP_5730, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.DRAGON_WARHAMMER_20785, WeaponStyle.MELEE); + StyleMap.put(ItemID.EASTER_BASKET, WeaponStyle.MELEE); + StyleMap.put(ItemID.EGG_WHISK, WeaponStyle.MELEE); + StyleMap.put(ItemID.ELDER_MAUL, WeaponStyle.MELEE); + StyleMap.put(ItemID.ELDER_MAUL_21205, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE1, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE2, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE3, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE4, WeaponStyle.MELEE); + StyleMap.put(ItemID.ENCHANTED_LYRE5, WeaponStyle.MELEE); + StyleMap.put(ItemID.EVENT_RPG, WeaponStyle.MELEE); + StyleMap.put(ItemID.EXCALIBUR, WeaponStyle.MELEE); + StyleMap.put(ItemID.EXCALIBUR_8280, WeaponStyle.MELEE); + StyleMap.put(ItemID.FLAMTAER_HAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.FREMENNIK_BLADE, WeaponStyle.MELEE); + StyleMap.put(ItemID.FROZEN_ABYSSAL_WHIP, WeaponStyle.MELEE); + StyleMap.put(ItemID.GADDERHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GHRAZI_RAPIER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GHRAZI_RAPIER_23628, WeaponStyle.MELEE); + StyleMap.put(ItemID.GILDED_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.GILDED_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.GILDED_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.GILDED_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.GLOWING_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GOLDEN_TENCH, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_HAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL_12848, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL_20557, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL_24225, WeaponStyle.MELEE); + StyleMap.put(ItemID.GRANITE_MAUL_24227, WeaponStyle.MELEE); + StyleMap.put(ItemID.GREEN_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_0, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_100, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_25, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_50, WeaponStyle.MELEE); + StyleMap.put(ItemID.GUTHANS_WARSPEAR_75, WeaponStyle.MELEE); + StyleMap.put(ItemID.HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.HARRYS_CUTLASS, WeaponStyle.MELEE); + StyleMap.put(ItemID.HAM_JOINT, WeaponStyle.MELEE); + StyleMap.put(ItemID.HAND_FAN, WeaponStyle.MELEE); + StyleMap.put(ItemID.HILL_GIANT_CLUB, WeaponStyle.MELEE); + StyleMap.put(ItemID.HOLY_HANDEGG, WeaponStyle.MELEE); + StyleMap.put(ItemID.HOSIDIUS_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_AXE_UNCHARGED, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_HARPOON_UNCHARGED, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.INFERNAL_PICKAXE_UNCHARGED, WeaponStyle.MELEE); + StyleMap.put(ItemID.INQUISITORS_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_DAGGERP_5668, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_DAGGERP_5686, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SPEARP_5706, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SPEARP_5720, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.IRON_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.JADE_MACHETE, WeaponStyle.MELEE); + StyleMap.put(ItemID.KATANA, WeaponStyle.MELEE); + StyleMap.put(ItemID.KITCHEN_KNIFE, WeaponStyle.MELEE); + StyleMap.put(ItemID.KERIS, WeaponStyle.MELEE); + StyleMap.put(ItemID.LARGE_SPADE, WeaponStyle.MELEE); + StyleMap.put(ItemID.LEAFBLADED_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.LEAFBLADED_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.LEAFBLADED_SPEAR_4159, WeaponStyle.MELEE); + StyleMap.put(ItemID.LEAFBLADED_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.LOVAKENGJ_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.LUCKY_CUTLASS, WeaponStyle.MELEE); + StyleMap.put(ItemID.LYRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MACHETE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAGIC_BUTTERFLY_NET, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAGIC_SECATEURS, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAGIC_SECATEURS_NZ, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAPLE_BLACKJACK, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAPLE_BLACKJACKD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MAPLE_BLACKJACKO, WeaponStyle.MELEE); + StyleMap.put(ItemID.MEAT_TENDERISER, WeaponStyle.MELEE); + StyleMap.put(ItemID.MERFOLK_TRIDENT, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_DAGGERP_5674, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_DAGGERP_5692, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SPEARP_5710, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SPEARP_5724, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.MITHRIL_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.MIXED_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.MOUSE_TOY, WeaponStyle.MELEE); + StyleMap.put(ItemID.NEW_CRYSTAL_HALBERD_FULL, WeaponStyle.MELEE); + StyleMap.put(ItemID.NEW_CRYSTAL_HALBERD_FULL_I, WeaponStyle.MELEE); + StyleMap.put(ItemID.NEW_CRYSTAL_HALBERD_FULL_16893, WeaponStyle.MELEE); + StyleMap.put(ItemID.NEW_CRYSTAL_HALBERD_FULL_I_16892, WeaponStyle.MELEE); + StyleMap.put(ItemID.NOOSE_WAND, WeaponStyle.MELEE); + StyleMap.put(ItemID.NUNCHAKU, WeaponStyle.MELEE); + StyleMap.put(ItemID.OAK_BLACKJACK, WeaponStyle.MELEE); + StyleMap.put(ItemID.OAK_BLACKJACKD, WeaponStyle.MELEE); + StyleMap.put(ItemID.OAK_BLACKJACKO, WeaponStyle.MELEE); + StyleMap.put(ItemID.OILY_FISHING_ROD, WeaponStyle.MELEE); + StyleMap.put(ItemID.OILY_PEARL_FISHING_ROD, WeaponStyle.MELEE); + StyleMap.put(ItemID.OPAL_MACHETE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ORANGE_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.ORANGE_SALAMANDER, WeaponStyle.MELEE); + StyleMap.put(ItemID.PEACEFUL_HANDEGG, WeaponStyle.MELEE); + StyleMap.put(ItemID.PET_ROCK, WeaponStyle.MELEE); + StyleMap.put(ItemID.PISCARILIUS_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.PROP_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.PURPLE_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAPIER, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6774, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6775, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6776, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6777, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6778, WeaponStyle.MELEE); + StyleMap.put(ItemID.RAT_POLE_6779, WeaponStyle.MELEE); + StyleMap.put(ItemID.RED_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.RED_FLOWERS_8938, WeaponStyle.MELEE); + StyleMap.put(ItemID.RED_SALAMANDER, WeaponStyle.MELEE); + StyleMap.put(ItemID.RED_TOPAZ_MACHETE, WeaponStyle.MELEE); + StyleMap.put(ItemID.ROCK_HAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.ROYAL_SCEPTRE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUBBER_CHICKEN, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUBBER_CHICKEN_22666, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_BATTLEAXE_20552, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_DAGGERP_5678, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_DAGGERP_5696, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR_20402, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR_23330, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR_23332, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SCIMITAR_23334, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SPEARP_5714, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SPEARP_5728, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.RUNE_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMINS_BLESSED_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMIN_GODSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMIN_GODSWORD_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMIN_MJOLNIR, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARADOMIN_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SARAS_BLESSED_SWORD_FULL, WeaponStyle.MELEE); + StyleMap.put(ItemID.SCYTHE, WeaponStyle.MELEE); + StyleMap.put(ItemID.SCYTHE_OF_VITUR, WeaponStyle.MELEE); + StyleMap.put(ItemID.SCYTHE_OF_VITUR_22664, WeaponStyle.MELEE); + StyleMap.put(ItemID.SCYTHE_OF_VITUR_UNCHARGED, WeaponStyle.MELEE); + StyleMap.put(ItemID.SEVERED_LEG_24792, WeaponStyle.MELEE); + StyleMap.put(ItemID.SHADOW_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SHAYZIEN_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVERLIGHT, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVERLIGHT_6745, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVERLIGHT_8279, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVER_SICKLE, WeaponStyle.MELEE); + StyleMap.put(ItemID.SILVER_SICKLE_B, WeaponStyle.MELEE); + StyleMap.put(ItemID.SNOWBALL, WeaponStyle.MELEE); + StyleMap.put(ItemID.SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.STALE_BAGUETTE, WeaponStyle.MELEE); + StyleMap.put(ItemID.STATIUSS_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.STATIUSS_WARHAMMER_23620, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_DAGGERP_5672, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_DAGGERP_5690, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SPEARP, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SPEARP_5708, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SPEARP_5722, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.STEEL_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.STONE_BOWL, WeaponStyle.MELEE); + StyleMap.put(ItemID.SWAMP_LIZARD, WeaponStyle.MELEE); + StyleMap.put(ItemID.SWIFT_BLADE, WeaponStyle.MELEE); + StyleMap.put(ItemID.TOKTZXILAK, WeaponStyle.MELEE); + StyleMap.put(ItemID.TOKTZXILAK_20554, WeaponStyle.MELEE); + StyleMap.put(ItemID.TOKTZXILEK, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_0, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_100, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_25, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_50, WeaponStyle.MELEE); + StyleMap.put(ItemID.TORAGS_HAMMERS_75, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAINING_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_AXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_CANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_HARPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.TRAILBLAZER_PICKAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.TROLLWEISS, WeaponStyle.MELEE); + StyleMap.put(ItemID.TWISTED_BANNER, WeaponStyle.MELEE); + StyleMap.put(ItemID.TZHAARKETEM, WeaponStyle.MELEE); + StyleMap.put(ItemID.TZHAARKETOM, WeaponStyle.MELEE); + StyleMap.put(ItemID.TZHAARKETOM_T, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_0, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_100, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_25, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_50, WeaponStyle.MELEE); + StyleMap.put(ItemID.VERACS_FLAIL_75, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_BLIGHTED_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_LONGSWORD_INACTIVE, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_LONGSWORD_23615, WeaponStyle.MELEE); + StyleMap.put(ItemID.VESTAS_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.VIGGORAS_CHAINMACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.VIGGORAS_CHAINMACE_U, WeaponStyle.MELEE); + StyleMap.put(ItemID.VOLCANIC_ABYSSAL_WHIP, WeaponStyle.MELEE); + StyleMap.put(ItemID.WESTERN_BANNER_1, WeaponStyle.MELEE); + StyleMap.put(ItemID.WESTERN_BANNER_2, WeaponStyle.MELEE); + StyleMap.put(ItemID.WESTERN_BANNER_3, WeaponStyle.MELEE); + StyleMap.put(ItemID.WESTERN_BANNER_4, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_2H_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_BATTLEAXE, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_CLAWS, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_DAGGER, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_DAGGERP, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_DAGGERP_6595, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_DAGGERP_6597, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_HALBERD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_LONGSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_MACE, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_SCIMITAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WHITE_WARHAMMER, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILDERNESS_SWORD_1, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILDERNESS_SWORD_2, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILDERNESS_SWORD_3, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILDERNESS_SWORD_4, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILLOW_BLACKJACK, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILLOW_BLACKJACKD, WeaponStyle.MELEE); + StyleMap.put(ItemID.WILLOW_BLACKJACKO, WeaponStyle.MELEE); + StyleMap.put(ItemID.WOLFBANE, WeaponStyle.MELEE); + StyleMap.put(ItemID.WOODEN_SPOON, WeaponStyle.MELEE); + StyleMap.put(ItemID.WOODEN_SWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.YELLOW_FLOWERS, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZAMORAKIAN_HASTA, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZAMORAKIAN_SPEAR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZAMORAK_GODSWORD, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZAMORAK_GODSWORD_OR, WeaponStyle.MELEE); + StyleMap.put(ItemID.ZOMBIE_HEAD, WeaponStyle.MELEE); + + //Ranged + StyleMap.put(ItemID._3RD_AGE_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_DARTP_5633, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_DARTP_5640, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_KNIFEP_5659, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_KNIFEP_5666, WeaponStyle.RANGE); + StyleMap.put(ItemID.ADAMANT_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.ARMADYL_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.ARMADYL_CROSSBOW_23611, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_CHINCHOMPA, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_DARTP_5631, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_DARTP_5638, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_KNIFEP_5658, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLACK_KNIFEP_5665, WeaponStyle.RANGE); + StyleMap.put(ItemID.BLURITE_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_DARTP_5628, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_DARTP_5635, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_KNIFEP_5654, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_KNIFEP_5661, WeaponStyle.RANGE); + StyleMap.put(ItemID.BRONZE_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.CHINCHOMPA, WeaponStyle.RANGE); + StyleMap.put(ItemID.CHINCHOMPA_10033, WeaponStyle.RANGE); + StyleMap.put(ItemID.COMP_OGRE_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.CORRUPTED_BOW_ATTUNED, WeaponStyle.RANGE); + StyleMap.put(ItemID.CORRUPTED_BOW_BASIC, WeaponStyle.RANGE); + StyleMap.put(ItemID.CORRUPTED_BOW_PERFECTED, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRAWS_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRAWS_BOW_U, WeaponStyle.RANGE); + StyleMap.put(ItemID.CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_110, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_110_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_210, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_210_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_310, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_310_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_410, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_410_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_510, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_510_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_610, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_610_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_710, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_710_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_810, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_810_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_910, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_910_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_24123, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_ATTUNED, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_BASIC, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_FULL, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_FULL_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_INACTIVE, WeaponStyle.RANGE); + StyleMap.put(ItemID.CRYSTAL_BOW_PERFECTED, WeaponStyle.RANGE); + StyleMap.put(ItemID.CURSED_GOBLIN_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_12765, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_12766, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_12767, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_12768, WeaponStyle.RANGE); + StyleMap.put(ItemID.DARK_BOW_20408, WeaponStyle.RANGE); + StyleMap.put(ItemID.DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.DORGESHUUN_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_DARTP_11233, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_DARTP_11234, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_HUNTER_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_KNIFEP_22808, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_KNIFEP_22810, WeaponStyle.RANGE); + StyleMap.put(ItemID.DRAGON_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.HEAVY_BALLISTA, WeaponStyle.RANGE); + StyleMap.put(ItemID.HEAVY_BALLISTA_23630, WeaponStyle.RANGE); + StyleMap.put(ItemID.HOLY_WATER, WeaponStyle.RANGE); + StyleMap.put(ItemID.HUNTERS_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_DARTP_5629, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_DARTP_5636, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_KNIFEP_5655, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_KNIFEP_5662, WeaponStyle.RANGE); + StyleMap.put(ItemID.IRON_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_0, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_100, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_25, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_50, WeaponStyle.RANGE); + StyleMap.put(ItemID.KARILS_CROSSBOW_75, WeaponStyle.RANGE); + StyleMap.put(ItemID.LIGHT_BALLISTA, WeaponStyle.RANGE); + StyleMap.put(ItemID.LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_COMP_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_SHORTBOW_20558, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAGIC_SHORTBOW_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAPLE_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MAPLE_SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_DARTP_5632, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_DARTP_5639, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_KNIFEP_5657, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_KNIFEP_5664, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.MITHRIL_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.MONKEY_TALISMAN, WeaponStyle.RANGE); + StyleMap.put(ItemID.MORRIGANS_JAVELIN, WeaponStyle.RANGE); + StyleMap.put(ItemID.MORRIGANS_JAVELIN_23619, WeaponStyle.RANGE); + StyleMap.put(ItemID.MORRIGANS_THROWING_AXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.MUD_PIE, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW_4213, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW_16888, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW_I, WeaponStyle.RANGE); + StyleMap.put(ItemID.NEW_CRYSTAL_BOW_I_16889, WeaponStyle.RANGE); + StyleMap.put(ItemID.OAK_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.OAK_SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.OGRE_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.PHOENIX_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.RED_CHINCHOMPA, WeaponStyle.RANGE); + StyleMap.put(ItemID.RED_CHINCHOMPA_10034, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_CROSSBOW_23601, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_DARTP_5634, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_DARTP_5641, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_KNIFEP_5660, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_KNIFEP_5667, WeaponStyle.RANGE); + StyleMap.put(ItemID.RUNE_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.SEERCULL, WeaponStyle.RANGE); + StyleMap.put(ItemID.SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.SIGNED_OAK_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.STARTER_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_CROSSBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_DART, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_DARTP, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_DARTP_5630, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_DARTP_5637, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_KNIFE, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_KNIFEP, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_KNIFEP_5656, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_KNIFEP_5663, WeaponStyle.RANGE); + StyleMap.put(ItemID.STEEL_THROWNAXE, WeaponStyle.RANGE); + StyleMap.put(ItemID.TOKTZXILUL, WeaponStyle.RANGE); + StyleMap.put(ItemID.TOXIC_BLOWPIPE, WeaponStyle.RANGE); + StyleMap.put(ItemID.TOXIC_BLOWPIPE_EMPTY, WeaponStyle.RANGE); + StyleMap.put(ItemID.TRAINING_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.TWISTED_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.WILLOW_COMP_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.WILLOW_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.WILLOW_SHORTBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.YEW_COMP_BOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.YEW_LONGBOW, WeaponStyle.RANGE); + StyleMap.put(ItemID.YEW_SHORTBOW, WeaponStyle.RANGE); + + //Magic + StyleMap.put(ItemID._3RD_AGE_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_0, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_100, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_25, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_50, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_75, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AHRIMS_STAFF_23653, WeaponStyle.MAGIC); + StyleMap.put(ItemID.AIR_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ANCIENT_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ANCIENT_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.APPRENTICE_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ARMADYL_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BANDOS_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BEGINNER_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BLISTERWOOD_FLAIL, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BROKEN_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BRYOPHYTAS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.BRYOPHYTAS_STAFF_UNCHARGED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CORRUPTED_STAFF_ATTUNED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CORRUPTED_STAFF_BASIC, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CORRUPTED_STAFF_PERFECTED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CRYSTAL_STAFF_ATTUNED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CRYSTAL_STAFF_BASIC, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CRYSTAL_STAFF_PERFECTED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.CURSED_GOBLIN_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.DAWNBRINGER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.DRAMEN_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.DUST_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.EARTH_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ELDRITCH_NIGHTMARE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.FIRE_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.GUTHIX_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.GUTHIX_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.HARMONISED_NIGHTMARE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.IBANS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.IBANS_STAFF_1410, WeaponStyle.MAGIC); + StyleMap.put(ItemID.IBANS_STAFF_U, WeaponStyle.MAGIC); + StyleMap.put(ItemID.IVANDIS_FLAIL, WeaponStyle.MAGIC); + StyleMap.put(ItemID.KODAI_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.KODAI_WAND_23626, WeaponStyle.MAGIC); + StyleMap.put(ItemID.LAVA_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.LAVA_BATTLESTAFF_21198, WeaponStyle.MAGIC); + StyleMap.put(ItemID.LUNAR_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MAGIC_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MASTER_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MASTER_WAND_20560, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MIST_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MUD_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_AIR_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_DUST_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_EARTH_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_FIRE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_LAVA_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_LAVA_STAFF_21200, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_MIST_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_MUD_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_SMOKE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_STEAM_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_STEAM_STAFF_12796, WeaponStyle.MAGIC); + StyleMap.put(ItemID.MYSTIC_WATER_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.NIGHTMARE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_1, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_2, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_3, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_4, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_5, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_6, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_7, WeaponStyle.MAGIC); + StyleMap.put(ItemID.PHARAOHS_SCEPTRE_8, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_1, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_10, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_2, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_3, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_4, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_5, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_6, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_7, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_8, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ROD_OF_IVANDIS_9, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SANGUINESTI_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SANGUINESTI_STAFF_UNCHARGED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SARADOMIN_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SARADOMIN_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SKULL_SCEPTRE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SKULL_SCEPTRE_I, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SLAYERS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SLAYERS_STAFF_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.SMOKE_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_AIR, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_BALANCE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_BOB_THE_CAT, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_EARTH, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_FIRE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_LIGHT, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_THE_DEAD, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_THE_DEAD_23613, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STAFF_OF_WATER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STARTER_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STEAM_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.STEAM_BATTLESTAFF_12795, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TEACHER_WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.THAMMARONS_SCEPTRE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.THAMMARONS_SCEPTRE_U, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TOKTZMEJTAL, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TOXIC_STAFF_OF_THE_DEAD, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TOXIC_STAFF_UNCHARGED, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SEAS, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SEAS_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SEAS_FULL, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SWAMP, WeaponStyle.MAGIC); + StyleMap.put(ItemID.TRIDENT_OF_THE_SWAMP_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.UNCHARGED_TOXIC_TRIDENT, WeaponStyle.MAGIC); + StyleMap.put(ItemID.UNCHARGED_TOXIC_TRIDENT_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.UNCHARGED_TRIDENT, WeaponStyle.MAGIC); + StyleMap.put(ItemID.UNCHARGED_TRIDENT_E, WeaponStyle.MAGIC); + StyleMap.put(ItemID.VOID_KNIGHT_MACE, WeaponStyle.MAGIC); + StyleMap.put(ItemID.VOID_KNIGHT_MACE_BROKEN, WeaponStyle.MAGIC); + StyleMap.put(ItemID.VOLATILE_NIGHTMARE_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.WAND, WeaponStyle.MAGIC); + StyleMap.put(ItemID.WATER_BATTLESTAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.WHITE_MAGIC_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ZAMORAK_CROZIER, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ZAMORAK_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ZURIELS_STAFF, WeaponStyle.MAGIC); + StyleMap.put(ItemID.ZURIELS_STAFF_23617, WeaponStyle.MAGIC); + //what the fuck... + StyleMap.put(ItemID.GNOMEBALL, WeaponStyle.MAGIC); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/com/openosrs/client/util/WeaponStyle.java b/runelite-client/src/main/java/com/openosrs/client/util/WeaponStyle.java new file mode 100644 index 0000000000..949fdda21f --- /dev/null +++ b/runelite-client/src/main/java/com/openosrs/client/util/WeaponStyle.java @@ -0,0 +1,6 @@ +package com.openosrs.client.util; + +public enum WeaponStyle +{ + MAGIC, RANGE, MELEE +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java index dfebdb618c..f76f32154a 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java @@ -56,4 +56,5 @@ public @interface ConfigItem */ Class enumClass() default OpenOSRS.class; String unhide() default ""; + String hide() default ""; } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java index 6e7b905379..0765779b48 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java @@ -47,4 +47,7 @@ public @interface ConfigSection OpenOSRS Lazy Helpers tm */ String keyName() default ""; + String section() default ""; + boolean hidden() default false; + String unhide() default ""; } From 5f89e0089156aeacb92e9aa98219adb42e84be90 Mon Sep 17 00:00:00 2001 From: zeruth Date: Mon, 25 Jan 2021 15:54:24 -0500 Subject: [PATCH 12/53] api: develop --- .../openosrs/api/{widgets => }/Varbits.java | 2 +- .../com/openosrs/api/widgets/WidgetID.java | 673 ------------------ .../com/openosrs/api/widgets/WidgetInfo.java | 488 ------------- .../main/java/net/runelite/api/Client.java | 9 - .../java/net/runelite/api/kit/KitType.java | 2 +- .../runelite/api/queries/ShopItemQuery.java | 2 +- .../net/runelite/api/widgets/WidgetID.java | 465 +++++++++++- .../net/runelite/api/widgets/WidgetInfo.java | 397 +++++++++++ .../net/runelite/mixins/RSClientMixin.java | 10 - 9 files changed, 863 insertions(+), 1185 deletions(-) rename runelite-api/src/main/java/com/openosrs/api/{widgets => }/Varbits.java (99%) delete mode 100644 runelite-api/src/main/java/com/openosrs/api/widgets/WidgetID.java delete mode 100644 runelite-api/src/main/java/com/openosrs/api/widgets/WidgetInfo.java diff --git a/runelite-api/src/main/java/com/openosrs/api/widgets/Varbits.java b/runelite-api/src/main/java/com/openosrs/api/Varbits.java similarity index 99% rename from runelite-api/src/main/java/com/openosrs/api/widgets/Varbits.java rename to runelite-api/src/main/java/com/openosrs/api/Varbits.java index 805f65efb0..bc98952741 100644 --- a/runelite-api/src/main/java/com/openosrs/api/widgets/Varbits.java +++ b/runelite-api/src/main/java/com/openosrs/api/Varbits.java @@ -1,4 +1,4 @@ -package com.openosrs.api.widgets; +package com.openosrs.api; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/runelite-api/src/main/java/com/openosrs/api/widgets/WidgetID.java b/runelite-api/src/main/java/com/openosrs/api/widgets/WidgetID.java deleted file mode 100644 index 6b5b3797e2..0000000000 --- a/runelite-api/src/main/java/com/openosrs/api/widgets/WidgetID.java +++ /dev/null @@ -1,673 +0,0 @@ -package com.openosrs.api.widgets; - -public class WidgetID extends net.runelite.api.widgets.WidgetID -{ - public static final int BANK_PIN_GROUP_ID = 213; - public static final int PLAYER_TRADE_CONFIRM_GROUP_ID = 334; - public static final int PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID = 243; - public static final int DIALOG_MINIGAME_GROUP_ID = 229; - public static final int BA_HORN_OF_GLORY = 484; - public static final int MOTHERLODE_MINE_FULL_INVENTORY_GROUP_ID = 229; - public static final int DIALOG_PLAYER_GROUP_ID = 217; - public static final int DIALOG_NOTIFICATION_GROUP_ID = 229; - public static final int FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID = 608; - public static final int PERFORMERS_FOR_THE_THEATRE_GROUPS_GROUP_ID = 364; - public static final int PERFORMERS_FOR_THE_THEATRE_PLAYERS_GROUP_ID = 50; - public static final int DIALOG_SPRITE2_ID = 11; - public static final int EQUIPMENT_PAGE_GROUP_ID = 84; - public static final int QUESTTAB_GROUP_ID = 629; - public static final int MUSICTAB_GROUP_ID = 239; - public static final int JEWELLERY_BOX_GROUP_ID = 590; - public static final int OPTIONS_GROUP_ID = 261; - public static final int MULTISKILL_MENU_GROUP_ID = 270; - public static final int THEATRE_OF_BLOOD_PARTY_GROUP_ID = 28; - public static final int GWD_KC_GROUP_ID = 406; - public static final int GAUNTLET_MAP_GROUP_ID = 638; - - public static final int SETTINGS_SIDE_GROUP_ID = 116; - public static final int SETTINGS_GROUP_ID = 134; - - static class SettingsSide - { - static final int CAMERA_ZOOM_SLIDER_TRACK = 59; - static final int MUSIC_SLIDER = 13; - static final int SOUND_EFFECT_SLIDER = 17; - static final int AREA_SOUND_SLIDER = 21; - } - - static class Settings - { - static final int INIT = 1; - } - - static class DialogPlayer - { - static final int HEAD_MODEL = 1; - static final int NAME = 2; - static final int CONTINUE = 3; - static final int TEXT = 4; - } - - static class DialogNotification - { - static final int TEXT = 0; - static final int CONTINUE = 1; - } - - static class DialogOption - { - static final int TEXT = 0; - static final int OPTION1 = 1; - static final int OPTION2 = 2; - static final int OPTION3 = 3; - static final int OPTION4 = 4; - static final int OPTION5 = 5; - } - - static class PestControlBoat - { - static final int INFO = 3; - - static final int NEXT_DEPARTURE = 4; - static final int PLAYERS_READY = 5; - static final int POINTS = 6; - } - - static class PestControlExchangeWindow - { - static final int ITEM_LIST = 2; - static final int BOTTOM = 5; - static final int POINTS = 8; - static final int CONFIRM_BUTTON = 6; - } - - static class MinigameDialog - { - static final int TEXT = 1; - static final int CONTINUE = 2; - } - - static class PestControl - { - static final int INFO = 3; - - static final int TIME = 6; - - static final int ACTIVITY_BAR = 12; - static final int ACTIVITY_PROGRESS = 14; - - static final int PURPLE_SHIELD = 15; - static final int BLUE_SHIELD = 16; - static final int YELLOW_SHIELD = 17; - static final int RED_SHIELD = 18; - - static final int PURPLE_ICON = 19; - static final int BLUE_ICON = 20; - static final int YELLOW_ICON = 21; - static final int RED_ICON = 22; - - static final int PURPLE_HEALTH = 23; - static final int BLUE_HEALTH = 24; - static final int YELLOW_HEALTH = 25; - static final int RED_HEALTH = 26; - } - - static class Bank - { - static final int BANK_CONTAINER = 1; - static final int INVENTORY_ITEM_CONTAINER = 3; - static final int BANK_TITLE_BAR = 3; - static final int TUTORIAL_BUTTON = 4; - static final int ITEM_COUNT_TOP = 5; - static final int ITEM_COUNT_BAR = 6; - static final int ITEM_COUNT_BOTTOM = 7; - static final int CONTENT_CONTAINER = 9; - static final int TAB_CONTAINER = 10; - static final int ITEM_CONTAINER = 12; - static final int SCROLLBAR = 13; - static final int UNNOTED_BUTTON = 21; - static final int NOTED_BUTTON = 23; - static final int SEARCH_BUTTON_BACKGROUND = 39; - static final int DEPOSIT_INVENTORY = 41; - static final int DEPOSIT_EQUIPMENT = 43; - static final int INCINERATOR = 45; - static final int INCINERATOR_CONFIRM = 46; - static final int EQUIPMENT_CONTENT_CONTAINER = 68; - static final int SETTINGS_BUTTON = 111; - static final int EQUIPMENT_BUTTON = 112; - } - - static class GrandExchange - { - static final int WINDOW_CONTAINER = 0; - static final int WINDOW_BORDERS = 2; - static final int HISTORY_BUTTON = 3; - static final int BACK_BUTTON = 4; - static final int OFFER1 = 7; - static final int OFFER2 = 8; - static final int OFFER3 = 9; - static final int OFFER4 = 10; - static final int OFFER5 = 11; - static final int OFFER6 = 12; - static final int OFFER7 = 13; - static final int OFFER8 = 14; - static final int OFFER_CONTAINER = 24; - static final int OFFER_DESCRIPTION = 25; - static final int OFFER_PRICE = 26; - static final int OFFER_CONFIRM_BUTTON = 27; - } - - static class Shop - { - static final int ITEMS_CONTAINER = 2; - static final int INVENTORY_ITEM_CONTAINER = 0; - } - - static class Smithing - { - static final int INVENTORY_ITEM_CONTAINER = 0; - - static final int QTY_1 = 3; - static final int QTY_5 = 4; - static final int QTY_10 = 5; - static final int QTY_X = 6; - static final int QTY_ALL = 7; - - static final int DAGGER = 9; - static final int SWORD = 10; - static final int SCIMITAR = 11; - static final int LONG_SWORD = 12; - static final int TWO_H_SWORD = 13; - static final int AXE = 14; - static final int MACE = 15; - static final int WARHAMMER = 16; - static final int BATTLE_AXE = 17; - static final int CLAWS = 18; - static final int CHAIN_BODY = 19; - static final int PLATE_LEGS = 20; - static final int PLATE_SKIRT = 21; - static final int PLATE_BODY = 22; - static final int NAILS = 23; - static final int MED_HELM = 24; - static final int FULL_HELM = 25; - static final int SQ_SHIELD = 26; - static final int KITE_SHIELD = 27; - static final int EXCLUSIVE1 = 28; - static final int DART_TIPS = 29; - static final int ARROW_HEADS = 30; - static final int KNIVES = 31; - static final int EXCLUSIVE2 = 32; - static final int JAVELIN_HEADS = 33; - static final int BOLTS = 34; - static final int LIMBS = 35; - } - - static class Equipment - { - static final int HELMET = 14; - static final int CAPE = 15; - static final int AMULET = 16; - static final int WEAPON = 17; - static final int BODY = 18; - static final int SHIELD = 19; - static final int LEGS = 20; - static final int GLOVES = 21; - static final int BOOTS = 22; - static final int RING = 23; - static final int AMMO = 24; - static final int INVENTORY_ITEM_CONTAINER = 0; - } - - static class Minimap - { - static final int XP_ORB = 1; - static final int HEALTH_ORB = 2; - static final int PRAYER_ORB = 12; - static final int QUICK_PRAYER_ORB = 14; // Has the "Quick-prayers" name - static final int PRAYER_ORB_TEXT = 15; - static final int RUN_ORB = 20; - static final int TOGGLE_RUN_ORB = 22; // Has the "Toggle run" name - static final int RUN_ORB_TEXT = 23; - static final int SPEC_ORB = 28; - static final int SPEC_CLICKBOX = 30; - static final int WORLDMAP_ORB = 41; - static final int WIKI_BANNER = 43; - } - - static class Combat - { - static final int WEAPON_NAME = 1; - static final int LEVEL = 3; - static final int STYLE_ONE = 4; - static final int STYLE_TWO = 8; - static final int STYLE_THREE = 12; - static final int STYLE_FOUR = 16; - static final int SPELLS = 20; - static final int DEFENSIVE_SPELL_BOX = 21; - static final int DEFENSIVE_SPELL_ICON = 23; - static final int DEFENSIVE_SPELL_SHIELD = 24; - static final int DEFENSIVE_SPELL_TEXT = 25; - static final int SPELL_BOX = 26; - static final int SPELL_ICON = 28; - static final int SPELL_TEXT = 29; - static final int AUTO_RETALIATE = 30; - static final int SPECIAL_ATTACK_BAR = 34; - static final int SPECIAL_ATTACK_CLICKBOX = 36; - static final int TOOLTIP = 41; - } - - static class BarbarianAssault - { - static class ATK - { - static final int LISTEN_TOP = 7; - static final int LISTEN_BOTTOM = 8; - static final int TO_CALL_WIDGET = 9; - static final int TO_CALL = 10; - static final int ROLE_SPRITE = 11; - static final int ROLE = 12; - } - static class HLR - { - static final int TEAMMATE1 = 18; - static final int TEAMMATE2 = 22; - static final int TEAMMATE3 = 26; - static final int TEAMMATE4 = 30; - } - static class HORN_GLORY - { - static final int ATTACKER = 5; - static final int DEFENDER = 6; - static final int COLLECTOR = 7; - static final int HEALER = 8; - } - static class REWARD_VALUES - { - static final int RUNNERS_PASSED = 14; - static final int HITPOINTS_REPLENISHED = 19; - static final int WRONG_POISON_PACKS_USED = 20; - static final int EGGS_COLLECTED = 21; - static final int FAILED_ATTACKER_ATTACKS = 22; - static final int RUNNERS_PASSED_POINTS = 24; - static final int RANGERS_KILLED = 25; - static final int FIGHTERS_KILLED = 26; - static final int HEALERS_KILLED = 27; - static final int RUNNERS_KILLED = 28; - static final int HITPOINTS_REPLENISHED_POINTS = 29; - static final int WRONG_POISON_PACKS_USED_POINTS = 30; - static final int EGGS_COLLECTED_POINTS = 31; - static final int FAILED_ATTACKER_ATTACKS_POINTS = 32; - static final int BASE_POINTS = 33; - static final int HONOUR_POINTS_REWARD = 49; - } - static final int CORRECT_STYLE = 3; - static final int GAME_WIDGET = 3; - static final int CURRENT_WAVE_WIDGET = 4; - static final int CURRENT_WAVE = 5; - static final int LISTEN_WIDGET = 6; - static final int LISTEN = 7; - static final int TO_CALL_WIDGET = 8; - static final int TO_CALL = 9; - static final int ROLE_SPRITE = 10; - static final int ROLE = 11; - static final int REWARD_TEXT = 57; - } - - static class LevelUp - { - static final int SKILL = 1; - static final int LEVEL = 2; - static final int CONTINUE = 3; - } - - static class TheatreOfBlood - { - static final int RAIDING_PARTY = 9; - static final int ORB_BOX = 10; - static final int BOSS_HEALTH_BAR = 35; - } - - static class TheatreOfBloodParty - { - static final int CONTAINER = 10; - } - - static class LightBox - { - static final int LIGHT_BOX = 1; - static final int LIGHT_BOX_WINDOW = 2; - static final int LIGHT_BULB_CONTAINER = 3; - static final int LIGHT_BOX_BUTTON_CONTAINER = 6; - static final int BUTTON_A = 8; - static final int BUTTON_B = 9; - static final int BUTTON_C = 10; - static final int BUTTON_D = 11; - static final int BUTTON_E = 12; - static final int BUTTON_F = 13; - static final int BUTTON_G = 14; - static final int BUTTON_H = 15; - } - - static class EquipmentWidgetIdentifiers - { - static final int EQUIP_YOUR_CHARACTER = 3; - static final int STAB_ATTACK_BONUS = 24; - static final int SLASH_ATTACK_BONUS = 25; - static final int CRUSH_ATTACK_BONUS = 26; - static final int MAGIC_ATTACK_BONUS = 27; - static final int RANGED_ATTACK_BONUS = 28; - static final int STAB_DEFENCE_BONUS = 30; - static final int SLASH_DEFENCE_BONUS = 31; - static final int CRUSH_DEFENCE_BONUS = 32; - static final int MAGIC_DEFENCE_BONUS = 33; - static final int RANGED_DEFENCE_BONUS = 34; - static final int MELEE_STRENGTH = 36; - static final int RANGED_STRENGTH = 37; - static final int MAGIC_DAMAGE = 38; - static final int PRAYER_BONUS = 39; - static final int UNDEAD_DAMAGE_BONUS = 41; - static final int SLAYER_DAMAGE_BONUS = 42; - static final int WEIGHT = 49; - } - - static class WorldSwitcher - { - static final int CONTAINER = 1; - static final int WORLD_LIST = 16; - static final int LOGOUT_BUTTON = 23; - } - - static class FossilMushroomTeleport - { - static final int ROOT = 2; - static final int HOUSE_ON_HILL = 4; - static final int VERDANT_VALLEY = 8; - static final int SWAMP = 12; - static final int MUSHROOM_MEADOW = 16; - } - - static class SpellBook - { - static final int FILTERED_SPELLS_BOUNDS = 3; - static final int TOOLTIP = 189; - - // NORMAL SPELLS - static final int LUMBRIDGE_HOME_TELEPORT = 5; - static final int WIND_STRIKE = 6; - static final int CONFUSE = 7; - static final int ENCHANT_CROSSBOW_BOLT = 8; - static final int WATER_STRIKE = 9; - static final int LVL_1_ENCHANT = 10; - static final int EARTH_STRIKE = 11; - static final int WEAKEN = 12; - static final int FIRE_STRIKE = 13; - static final int BONES_TO_BANANAS = 14; - static final int WIND_BOLT = 15; - static final int CURSE = 16; - static final int BIND = 17; - static final int LOW_LEVEL_ALCHEMY = 18; - static final int WATER_BOLT = 19; - static final int VARROCK_TELEPORT = 20; - static final int LVL_2_ENCHANT = 21; - static final int EARTH_BOLT = 22; - static final int LUMBRIDGE_TELEPORT = 23; - static final int TELEKINETIC_GRAB = 24; - static final int FIRE_BOLT = 25; - static final int FALADOR_TELEPORT = 26; - static final int CRUMBLE_UNDEAD = 27; - static final int TELEPORT_TO_HOUSE = 28; - static final int WIND_BLAST = 29; - static final int SUPERHEAT_ITEM = 30; - static final int CAMELOT_TELEPORT = 31; - static final int WATER_BLAST = 32; - static final int LVL_3_ENCHANT = 33; - static final int IBAN_BLAST = 34; - static final int SNARE = 35; - static final int MAGIC_DART = 36; - static final int ARDOUGNE_TELEPORT = 37; - static final int EARTH_BLAST = 38; - static final int HIGH_LEVEL_ALCHEMY = 39; - static final int CHARGE_WATER_ORB = 40; - static final int LVL_4_ENCHANT = 41; - static final int WATCHTOWER_TELEPORT = 42; - static final int FIRE_BLAST = 43; - static final int CHARGE_EARTH_ORB = 44; - static final int BONES_TO_PEACHES = 45; - static final int SARADOMIN_STRIKE = 46; - static final int CLAWS_OF_GUTHIX = 47; - static final int FLAMES_OF_ZAMORAK = 48; - static final int TROLLHEIM_TELEPORT = 49; - static final int WIND_WAVE = 50; - static final int CHARGE_FIRE_ORB = 51; - static final int TELEPORT_TO_APE_ATOLL = 52; - static final int WATER_WAVE = 53; - static final int CHARGE_AIR_ORB = 54; - static final int VULNERABILITY = 55; - static final int LVL_5_ENCHANT = 56; - static final int TELEPORT_TO_KOUREND = 57; - static final int EARTH_WAVE = 58; - static final int ENFEEBLE = 59; - static final int TELEOTHER_LUMBRIDGE = 60; - static final int FIRE_WAVE = 61; - static final int ENTANGLE = 62; - static final int STUN = 63; - static final int CHARGE = 64; - static final int WIND_SURGE = 65; - static final int TELEOTHER_FALADOR = 66; - static final int WATER_SURGE = 67; - static final int TELE_BLOCK = 68; - static final int BOUNTY_TARGET_TELEPORT = 69; - static final int LVL_6_ENCHANT = 70; - static final int TELEOTHER_CAMELOT = 71; - static final int EARTH_SURGE = 72; - static final int LVL_7_ENCHANT = 73; - static final int FIRE_SURGE = 74; - - // ANCIENT SPELLS - static final int ICE_RUSH = 75; - static final int ICE_BLITZ = 76; - static final int ICE_BURST = 77; - static final int ICE_BARRAGE = 78; - static final int BLOOD_RUSH = 79; - static final int BLOOD_BLITZ = 80; - static final int BLOOD_BURST = 81; - static final int BLOOD_BARRAGE = 82; - static final int SMOKE_RUSH = 83; - static final int SMOKE_BLITZ = 84; - static final int SMOKE_BURST = 85; - static final int SMOKE_BARRAGE = 86; - static final int SHADOW_RUSH = 87; - static final int SHADOW_BLITZ = 88; - static final int SHADOW_BURST = 89; - static final int SHADOW_BARRAGE = 90; - static final int PADDEWWA_TELEPORT = 91; - static final int SENNTISTEN_TELEPORT = 92; - static final int KHARYRLL_TELEPORT = 93; - static final int LASSAR_TELEPORT = 94; - static final int DAREEYAK_TELEPORT = 95; - static final int CARRALLANGER_TELEPORT = 96; - static final int ANNAKARL_TELEPORT = 97; - static final int GHORROCK_TELEPORT = 98; - static final int EDGEVILLE_HOME_TELEPORT = 99; - - // LUNAR SPELLS - static final int LUNAR_HOME_TELEPORT = 100; - static final int BAKE_PIE = 101; - static final int CURE_PLANT = 102; - static final int MONSTER_EXAMINE = 103; - static final int NPC_CONTACT = 104; - static final int CURE_OTHER = 105; - static final int HUMIDIFY = 106; - static final int MOONCLAN_TELEPORT = 107; - static final int TELE_GROUP_MOONCLAN = 108; - static final int CURE_ME = 109; - static final int HUNTER_KIT = 110; - static final int WATERBIRTH_TELEPORT = 111; - static final int TELE_GROUP_WATERBIRTH = 112; - static final int CURE_GROUP = 113; - static final int STAT_SPY = 114; - static final int BARBARIAN_TELEPORT = 115; - static final int TELE_GROUP_BARBARIAN = 116; - static final int SUPERGLASS_MAKE = 117; - static final int TAN_LEATHER = 118; - static final int KHAZARD_TELEPORT = 119; - static final int TELE_GROUP_KHAZARD = 120; - static final int DREAM = 121; - static final int STRING_JEWELLERY = 122; - static final int STAT_RESTORE_POT_SHARE = 123; - static final int MAGIC_IMBUE = 124; - static final int FERTILE_SOIL = 125; - static final int BOOST_POTION_SHARE = 126; - static final int FISHING_GUILD_TELEPORT = 127; - static final int TELE_GROUP_FISHING_GUILD = 128; - static final int PLANK_MAKE = 129; - static final int CATHERBY_TELEPORT = 130; - static final int TELE_GROUP_CATHERBY = 131; - static final int RECHARGE_DRAGONSTONE = 132; - static final int ICE_PLATEAU_TELEPORT = 133; - static final int TELE_GROUP_ICE_PLATEAU = 134; - static final int ENERGY_TRANSFER = 135; - static final int HEAL_OTHER = 136; - static final int VENGEANCE_OTHER = 137; - static final int VENGEANCE = 138; - static final int HEAL_GROUP = 139; - static final int SPELLBOOK_SWAP = 140; - static final int GEOMANCY = 141; - static final int SPIN_FLAX = 142; - static final int OURANIA_TELEPORT = 143; - - // ARCEUUS SPELLS - static final int ARCEUUS_HOME_TELEPORT = 144; - static final int BATTLEFRONT_TELEPORT = 179; - // HEADS - static final int REANIMATE_GOBLIN = 145; - static final int REANIMATE_MONKEY = 147; - static final int REANIMATE_IMP = 148; - static final int REANIMATE_MINOTAUR = 149; - static final int REANIMATE_SCORPION = 151; - static final int REANIMATE_BEAR = 152; - static final int REANIMATE_UNICORN = 153; - static final int REANIMATE_DOG = 154; - static final int REANIMATE_CHAOS_DRUID = 156; - static final int REANIMATE_GIANT = 158; - static final int REANIMATE_OGRE = 160; - static final int REANIMATE_ELF = 161; - static final int REANIMATE_TROLL = 162; - static final int REANIMATE_HORROR = 164; - static final int REANIMATE_KALPHITE = 165; - static final int REANIMATE_DAGANNOTH = 167; - static final int REANIMATE_BLOODVELD = 168; - static final int REANIMATE_TZHAAR = 170; - static final int REANIMATE_DEMON = 172; - static final int REANIMATE_AVIANSIE = 173; - static final int REANIMATE_ABYSSAL = 176; - static final int REANIMATE_DRAGON = 178; - - } - - static class Pvp - { - static final int FOG_OVERLAY = 1; - static final int PVP_WIDGET_CONTAINER = 54; // OUTDATED? - static final int SKULL = 56; // OUTDATED? - static final int ATTACK_RANGE = 59; // OUTDATED? - static final int BOUNTY_HUNTER_INFO = 6; - static final int KILLDEATH_RATIO = 28; - static final int SKULL_CONTAINER = 48; - static final int SAFE_ZONE = 50; - static final int WILDERNESS_LEVEL = 53; // this can also be the Deadman Mode "Protection" text - } - - static class DialogSprite2 - { - static final int SPRITE1 = 1; - static final int TEXT = 2; - static final int SPRITE2 = 3; - static final int CONTINUE = 4; - } - - static class QuestTab - { - static final int QUEST_TAB = 3; - } - - public static class TradeScreen - { - public static final int FIRST_TRADING_WITH = 31; - public static final int SECOND_ACCEPT_FUNC = 13; - public static final int SECOND_DECLINE_FUNC = 14; - public static final int SECOND_MY_OFFER = 23; - public static final int SECOND_THEIR_OFFER = 24; - public static final int SECOND_ACCEPT_TEXT = 25; - public static final int SECOND_DECLINE_TEXT = 26; - public static final int SECOND_MY_ITEMS = 28; - public static final int SECOND_THEIR_ITEMS = 29; - public static final int SECOND_TRADING_WITH = 30; - } - - public static class DuelConfig - { - public static final int CONFIG_GROUP_IP = 482; - public static final int TITLE = 35; - public static final int OPPONENT_ATT = 9; - public static final int OPPONENT_STR = 13; - public static final int OPPONENT_DEF = 17; - public static final int OPPONENT_HP = 21; - } - - public static class DuelResult - { - public static final int RESULT_GROUP_ID = 372; - public static final int TITLE = 16; - public static final int TOTAL_STAKED = 32; - public static final int TOTAL_TAX = 39; - public static final int WINNINGS = 40; - } - - // Also used for many other interfaces! - static class BankPin - { - static final int CONTAINER = 0; - static final int TOP_LEFT_TEXT = 2; - static final int FIRST_ENTERED = 3; - static final int SECOND_ENTERED = 4; - static final int THIRD_ENTERED = 5; - static final int FOURTH_ENTERED = 6; - static final int INSTRUCTION_TEXT = 10; - static final int EXIT_BUTTON = 13; - static final int FORGOT_BUTTON = 15; - static final int BUTTON_1 = 16; - static final int BUTTON_2 = 18; - static final int BUTTON_3 = 20; - static final int BUTTON_4 = 22; - static final int BUTTON_5 = 24; - static final int BUTTON_6 = 26; - static final int BUTTON_7 = 28; - static final int BUTTON_8 = 30; - static final int BUTTON_9 = 32; - static final int BUTTON_10 = 34; - } - - static class JewelBox - { - static final int DUEL_RING = 2; - static final int GAME_NECK = 3; - static final int COMB_BRAC = 4; - static final int SKIL_NECK = 5; - static final int RING_OFGP = 6; - static final int AMUL_GLOR = 7; // yes - } - - static class Options - { - static final int CAMERA_ZOOM_SLIDER_HANDLE = 15; - static final int MUSIC_SLIDER = 37; - static final int SOUND_EFFECT_SLIDER = 43; - static final int AREA_SOUND_SLIDER = 49; - } - - static class GauntletMap - { - static final int CONTAINER = 4; - } -} diff --git a/runelite-api/src/main/java/com/openosrs/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/com/openosrs/api/widgets/WidgetInfo.java deleted file mode 100644 index 57e164273e..0000000000 --- a/runelite-api/src/main/java/com/openosrs/api/widgets/WidgetInfo.java +++ /dev/null @@ -1,488 +0,0 @@ -package com.openosrs.api.widgets; - - -public enum WidgetInfo -{ - WORLD_MAP_BUTTON_BORDER(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), - - EQUIPMENT_HELMET(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.HELMET), - EQUIPMENT_CAPE(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.CAPE), - EQUIPMENT_AMULET(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.AMULET), - EQUIPMENT_WEAPON(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.WEAPON), - EQUIPMENT_BODY(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.BODY), - EQUIPMENT_SHIELD(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.SHIELD), - EQUIPMENT_LEGS(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.LEGS), - EQUIPMENT_GLOVES(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.GLOVES), - EQUIPMENT_BOOTS(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.BOOTS), - EQUIPMENT_RING(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.RING), - EQUIPMENT_AMMO(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.AMMO), - - MINIGAME_DIALOG(WidgetID.DIALOG_MINIGAME_GROUP_ID, 0), - MINIGAME_DIALOG_TEXT(WidgetID.DIALOG_MINIGAME_GROUP_ID, WidgetID.MinigameDialog.TEXT), - MINIGAME_DIALOG_CONTINUE(WidgetID.DIALOG_MINIGAME_GROUP_ID, WidgetID.MinigameDialog.CONTINUE), - PEST_CONTROL_EXCHANGE_WINDOW(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, 0), - PEST_CONTROL_EXCHANGE_WINDOW_POINTS(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, WidgetID.PestControlExchangeWindow.POINTS), - - PEST_CONTROL_BOAT_INFO_POINTS(WidgetID.PEST_CONTROL_BOAT_GROUP_ID, WidgetID.PestControlBoat.POINTS), - PEST_CONTROL_INFO_TIME(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.TIME), - - BANK_UNNOTED_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.UNNOTED_BUTTON), - BANK_NOTED_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.NOTED_BUTTON), - - GRAND_EXCHANGE_HISTORY_BUTTON(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.HISTORY_BUTTON), - GRAND_EXCHANGE_BACK_BUTTON(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.BACK_BUTTON), - GRAND_EXCHANGE_OFFER1(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER1), - GRAND_EXCHANGE_OFFER2(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER2), - GRAND_EXCHANGE_OFFER3(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER3), - GRAND_EXCHANGE_OFFER4(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER4), - GRAND_EXCHANGE_OFFER5(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER5), - GRAND_EXCHANGE_OFFER6(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER6), - GRAND_EXCHANGE_OFFER7(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER7), - GRAND_EXCHANGE_OFFER8(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER8), - - GRAND_EXCHANGE_OFFER_CONFIRM_BUTTON(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER_CONFIRM_BUTTON), - - SMITHING_ANVIL_DAGGER(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.DAGGER), - SMITHING_ANVIL_SWORD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.SWORD), - SMITHING_ANVIL_SCIMITAR(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.SCIMITAR), - SMITHING_ANVIL_LONG_SWORD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.LONG_SWORD), - SMITHING_ANVIL_TWO_H_SWORD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.TWO_H_SWORD), - SMITHING_ANVIL_AXE(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.AXE), - SMITHING_ANVIL_MACE(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.MACE), - SMITHING_ANVIL_WARHAMMER(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.WARHAMMER), - SMITHING_ANVIL_BATTLE_AXE(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.BATTLE_AXE), - SMITHING_ANVIL_CLAWS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.CLAWS), - SMITHING_ANVIL_CHAIN_BODY(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.CHAIN_BODY), - SMITHING_ANVIL_PLATE_LEGS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.PLATE_LEGS), - SMITHING_ANVIL_PLATE_SKIRT(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.PLATE_SKIRT), - SMITHING_ANVIL_PLATE_BODY(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.PLATE_BODY), - SMITHING_ANVIL_NAILS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.NAILS), - SMITHING_ANVIL_MED_HELM(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.MED_HELM), - SMITHING_ANVIL_FULL_HELM(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.FULL_HELM), - SMITHING_ANVIL_SQ_SHIELD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.SQ_SHIELD), - SMITHING_ANVIL_KITE_SHIELD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.KITE_SHIELD), - SMITHING_ANVIL_DART_TIPS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.DART_TIPS), - SMITHING_ANVIL_ARROW_HEADS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.ARROW_HEADS), - SMITHING_ANVIL_KNIVES(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.KNIVES), - SMITHING_ANVIL_JAVELIN_HEADS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.JAVELIN_HEADS), - SMITHING_ANVIL_BOLTS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.BOLTS), - SMITHING_ANVIL_LIMBS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.LIMBS), - SMITHING_ANVIL_EXCLUSIVE1(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.EXCLUSIVE1), - SMITHING_ANVIL_EXCLUSIVE2(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.EXCLUSIVE2), - - MINIMAP_SPEC_CLICKBOX(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.SPEC_CLICKBOX), - - MINIMAP_WORLD_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), - - RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_TAB(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.SPELL_TAB), - - COMBAT_WEAPON(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.WEAPON_NAME), - - COMBAT_SPECIAL_ATTACK(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPECIAL_ATTACK_BAR), - COMBAT_SPECIAL_ATTACK_CLICKBOX(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPECIAL_ATTACK_CLICKBOX), - COMBAT_TOOLTIP(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.TOOLTIP), - - MULTI_SKILL_MENU(WidgetID.MULTISKILL_MENU_GROUP_ID, 0), - - DIALOG2_SPRITE(WidgetID.DIALOG_SPRITE2_ID, 0), - DIALOG2_SPRITE_SPRITE1(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.SPRITE1), - DIALOG2_SPRITE_SPRITE2(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.SPRITE2), - DIALOG2_SPRITE_TEXT(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.TEXT), - DIALOG2_SPRITE_CONTINUE(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.CONTINUE), - - DIALOG_PLAYER_NAME(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.NAME), - DIALOG_PLAYER_TEXT(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.TEXT), - DIALOG_PLAYER_HEAD_MODEL(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.HEAD_MODEL), - DIALOG_PLAYER_CONTINUE(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.CONTINUE), - - DIALOG_NOTIFICATION_TEXT(WidgetID.DIALOG_NOTIFICATION_GROUP_ID, WidgetID.DialogNotification.TEXT), - DIALOG_NOTIFICATION_CONTINUE(WidgetID.DIALOG_NOTIFICATION_GROUP_ID, WidgetID.DialogNotification.CONTINUE), - - DIALOG_OPTION_TEXT(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.TEXT), - DIALOG_OPTION_OPTION1(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION1), - DIALOG_OPTION_OPTION2(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION2), - DIALOG_OPTION_OPTION3(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION3), - DIALOG_OPTION_OPTION4(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION4), - DIALOG_OPTION_OPTION5(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION5), - - BA_RUNNERS_PASSED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RUNNERS_PASSED), - BA_HITPOINTS_REPLENISHED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HITPOINTS_REPLENISHED), - BA_WRONG_POISON_PACKS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.WRONG_POISON_PACKS_USED), - BA_EGGS_COLLECTED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.EGGS_COLLECTED), - BA_FAILED_ATTACKER_ATTACKS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.FAILED_ATTACKER_ATTACKS), - BA_RUNNERS_PASSED_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RUNNERS_PASSED_POINTS), - BA_RANGERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RANGERS_KILLED), - BA_FIGHTERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.FIGHTERS_KILLED), - BA_HEALERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HEALERS_KILLED), - BA_RUNNERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RUNNERS_KILLED), - BA_HITPOINTS_REPLENISHED_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HITPOINTS_REPLENISHED_POINTS), - BA_WRONG_POISON_PACKS_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.WRONG_POISON_PACKS_USED_POINTS), - BA_EGGS_COLLECTED_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.EGGS_COLLECTED_POINTS), - BA_FAILED_ATTACKER_ATTACKS_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.FAILED_ATTACKER_ATTACKS_POINTS), - BA_HONOUR_POINTS_REWARD(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HONOUR_POINTS_REWARD), - BA_BASE_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.BASE_POINTS), - - LEVEL_UP_CONTINUE(WidgetID.LEVEL_UP_GROUP_ID, WidgetID.LevelUp.CONTINUE), - - THEATRE_OF_BLOOD_PARTY(WidgetID.THEATRE_OF_BLOOD_PARTY_GROUP_ID, WidgetID.TheatreOfBloodParty.CONTAINER), - - LIGHT_BOX_BUTTON_CONTAINER(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.LIGHT_BOX_BUTTON_CONTAINER), - - THEATRE_OF_BLOOD_HEALTH_ORBS(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.ORB_BOX), - THEATRE_OF_BLOOD_BOSS_HEALTH(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.BOSS_HEALTH_BAR), - THEATRE_OF_BLOOD_RAIDING_PARTY(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.RAIDING_PARTY), - - WORLD_SWITCHER_CONTAINER(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.CONTAINER), - - WORLD_SWITCHER_LOGOUT_BUTTON(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.LOGOUT_BUTTON), - - FOSSIL_MUSHROOM_TELEPORT(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.ROOT), - FOSSIL_MUSHROOM_HOUSE(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.HOUSE_ON_HILL), - FOSSIL_MUSHROOM_VALLEY(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.VERDANT_VALLEY), - FOSSIL_MUSHROOM_SWAMP(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.SWAMP), - FOSSIL_MUSHROOM_MEADOW(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.MUSHROOM_MEADOW), - - PVP_SKULL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL), - PVP_ATTACK_RANGE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.ATTACK_RANGE), - - SPELLBOOK(WidgetID.SPELLBOOK_GROUP_ID, 0), - SPELLBOOK_FILTERED_BOUNDS(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FILTERED_SPELLS_BOUNDS), - - /* STANDARD SPELL BOOK WIDGETS*/ - SPELL_LUMBRIDGE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LUMBRIDGE_HOME_TELEPORT), - SPELL_WIND_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_STRIKE), - SPELL_CONFUSE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CONFUSE), - SPELL_ENCHANT_CROSSBOW_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENCHANT_CROSSBOW_BOLT), - SPELL_WATER_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_STRIKE), - SPELL_LVL_1_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_1_ENCHANT), - SPELL_EARTH_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_STRIKE), - SPELL_WEAKEN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WEAKEN), - SPELL_FIRE_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_STRIKE), - SPELL_BONES_TO_BANANAS(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BONES_TO_BANANAS), - SPELL_WIND_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_BOLT), - SPELL_CURSE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURSE), - SPELL_BIND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BIND), - SPELL_LOW_LEVEL_ALCHEMY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LOW_LEVEL_ALCHEMY), - SPELL_WATER_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_BOLT), - SPELL_VARROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VARROCK_TELEPORT), - SPELL_LVL_2_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_2_ENCHANT), - SPELL_EARTH_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_BOLT), - SPELL_LUMBRIDGE_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LUMBRIDGE_TELEPORT), - SPELL_TELEKINETIC_GRAB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEKINETIC_GRAB), - SPELL_FIRE_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_BOLT), - SPELL_FALADOR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FALADOR_TELEPORT), - SPELL_CRUMBLE_UNDEAD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CRUMBLE_UNDEAD), - SPELL_TELEPORT_TO_HOUSE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEPORT_TO_HOUSE), - SPELL_WIND_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_BLAST), - SPELL_SUPERHEAT_ITEM(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SUPERHEAT_ITEM), - SPELL_CAMELOT_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CAMELOT_TELEPORT), - SPELL_WATER_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_BLAST), - SPELL_LVL_3_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_3_ENCHANT), - SPELL_IBAN_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.IBAN_BLAST), - SPELL_SNARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SNARE), - SPELL_MAGIC_DART(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MAGIC_DART), - SPELL_ARDOUGNE_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ARDOUGNE_TELEPORT), - SPELL_EARTH_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_BLAST), - SPELL_HIGH_LEVEL_ALCHEMY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HIGH_LEVEL_ALCHEMY), - SPELL_CHARGE_WATER_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_WATER_ORB), - SPELL_LVL_4_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_4_ENCHANT), - SPELL_WATCHTOWER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATCHTOWER_TELEPORT), - SPELL_FIRE_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_BLAST), - SPELL_CHARGE_EARTH_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_EARTH_ORB), - SPELL_BONES_TO_PEACHES(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BONES_TO_PEACHES), - SPELL_SARADOMIN_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SARADOMIN_STRIKE), - SPELL_CLAWS_OF_GUTHIX(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CLAWS_OF_GUTHIX), - SPELL_FLAMES_OF_ZAMORAK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FLAMES_OF_ZAMORAK), - SPELL_TROLLHEIM_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TROLLHEIM_TELEPORT), - SPELL_WIND_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_WAVE), - SPELL_CHARGE_FIRE_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_FIRE_ORB), - SPELL_TELEPORT_TO_APE_ATOLL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEPORT_TO_APE_ATOLL), - SPELL_WATER_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_WAVE), - SPELL_CHARGE_AIR_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_AIR_ORB), - SPELL_VULNERABILITY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VULNERABILITY), - SPELL_LVL_5_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_5_ENCHANT), - SPELL_TELEPORT_TO_KOUREND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEPORT_TO_KOUREND), - SPELL_EARTH_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_WAVE), - SPELL_ENFEEBLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENFEEBLE), - SPELL_FIRE_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_WAVE), - SPELL_ENTANGLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENTANGLE), - SPELL_TELEOTHER_LUMBRIDGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEOTHER_LUMBRIDGE), - SPELL_STUN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STUN), - SPELL_CHARGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE), - SPELL_WIND_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_SURGE), - SPELL_TELEOTHER_FALADOR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEOTHER_FALADOR), - SPELL_WATER_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_SURGE), - SPELL_TELE_BLOCK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_BLOCK), - SPELL_LVL_6_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_6_ENCHANT), - SPELL_TELEOTHER_CAMELOT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEOTHER_CAMELOT), - SPELL_EARTH_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_SURGE), - SPELL_LVL_7_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_7_ENCHANT), - SPELL_FIRE_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_SURGE), - SPELL_BOUNTY_TARGET_TELEPORT2(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), - /* END OF STANDARD SPELL BOOK WIDGETS*/ - - /* ANCIENT SPELL BOOK WIDGETS*/ - SPELL_ICE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_RUSH), - SPELL_ICE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BLITZ), - SPELL_ICE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BURST), - SPELL_ICE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BARRAGE), - SPELL_BLOOD_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_RUSH), - SPELL_BLOOD_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BLITZ), - SPELL_BLOOD_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BURST), - SPELL_BLOOD_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BARRAGE), - SPELL_SMOKE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_RUSH), - SPELL_SMOKE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BLITZ), - SPELL_SMOKE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BURST), - SPELL_SMOKE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BARRAGE), - SPELL_SHADOW_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_RUSH), - SPELL_SHADOW_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BLITZ), - SPELL_SHADOW_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BURST), - SPELL_SHADOW_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BARRAGE), - SPELL_PADDEWWA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.PADDEWWA_TELEPORT), - SPELL_SENNTISTEN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SENNTISTEN_TELEPORT), - SPELL_KHARYRLL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.KHARYRLL_TELEPORT), - SPELL_LASSAR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LASSAR_TELEPORT), - SPELL_DAREEYAK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.DAREEYAK_TELEPORT), - SPELL_CARRALLANGER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CARRALLANGER_TELEPORT), - SPELL_ANNAKARL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ANNAKARL_TELEPORT), - SPELL_GHORROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.GHORROCK_TELEPORT), - SPELL_EDGEVILLE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EDGEVILLE_HOME_TELEPORT), - SPELL_BOUNTY_TARGET_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), - /* END OF ANCIENT SPELL BOOK WIDGETS*/ - - /* LUNAR SPELL BOOK WIDGETS*/ - SPELL_LUNAR_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LUNAR_HOME_TELEPORT), - SPELL_VENGEANCE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VENGEANCE_OTHER), - SPELL_VENGEANCE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VENGEANCE), - SPELL_BOUNTY_TARGET_TELEPORT3(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), - SPELL_BAKE_PIE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BAKE_PIE), - SPELL_CURE_PLANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_PLANT), - SPELL_MONSTER_EXAMINE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MONSTER_EXAMINE), - SPELL_NPC_CONTACT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.NPC_CONTACT), - SPELL_CURE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_OTHER), - SPELL_HUMIDIFY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HUMIDIFY), - SPELL_MOONCLAN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MOONCLAN_TELEPORT), - SPELL_TELE_GROUP_MOONCLAN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_MOONCLAN), - SPELL_CURE_ME(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_ME), - SPELL_HUNTER_KIT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HUNTER_KIT), - SPELL_WATERBIRTH_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATERBIRTH_TELEPORT), - SPELL_TELE_GROUP_WATERBIRTH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_WATERBIRTH), - SPELL_CURE_GROUP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_GROUP), - SPELL_STAT_SPY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STAT_SPY), - SPELL_BARBARIAN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BARBARIAN_TELEPORT), - SPELL_TELE_GROUP_BARBARIAN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_BARBARIAN), - SPELL_SUPERGLASS_MAKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SUPERGLASS_MAKE), - SPELL_TAN_LEATHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TAN_LEATHER), - SPELL_KHAZARD_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.KHAZARD_TELEPORT), - SPELL_TELE_GROUP_KHAZARD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_KHAZARD), - SPELL_DREAM(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.DREAM), - SPELL_STRING_JEWELLERY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STRING_JEWELLERY), - SPELL_STAT_RESTORE_POT_SHARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STAT_RESTORE_POT_SHARE), - SPELL_MAGIC_IMBUE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MAGIC_IMBUE), - SPELL_FERTILE_SOIL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FERTILE_SOIL), - SPELL_BOOST_POTION_SHARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOOST_POTION_SHARE), - SPELL_FISHING_GUILD_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FISHING_GUILD_TELEPORT), - SPELL_TELE_GROUP_FISHING_GUILD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_FISHING_GUILD), - SPELL_PLANK_MAKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.PLANK_MAKE), - SPELL_CATHERBY_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CATHERBY_TELEPORT), - SPELL_TELE_GROUP_CATHERBY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_CATHERBY), - SPELL_RECHARGE_DRAGONSTONE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.RECHARGE_DRAGONSTONE), - SPELL_ICE_PLATEAU_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_PLATEAU_TELEPORT), - SPELL_TELE_GROUP_ICE_PLATEAU(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_ICE_PLATEAU), - SPELL_ENERGY_TRANSFER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENERGY_TRANSFER), - SPELL_HEAL_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HEAL_OTHER), - SPELL_HEAL_GROUP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HEAL_GROUP), - SPELL_SPELLBOOK_SWAP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SPELLBOOK_SWAP), - SPELL_GEOMANCY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.GEOMANCY), - SPELL_SPIN_FLAX(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SPIN_FLAX), - SPELL_OURANIA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.OURANIA_TELEPORT), - /* END OF LUNAR SPELL BOOK WIDGETS*/ - SPELL_TOOLTIP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TOOLTIP), - /* ARCEUUS SPELL BOOK WIDGETS*/ - SPELL_KOUREND_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, net.runelite.api.widgets.WidgetID.StandardSpellBook.KOUREND_HOME_TELEPORT), - SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ARCEUUS_HOME_TELEPORT), - SPELL_BATTLEFRONT_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BATTLEFRONT_TELEPORT), - SPELL_REANIMATE_GOBLIN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_GOBLIN), - SPELL_REANIMATE_MONKEY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_MONKEY), - SPELL_REANIMATE_IMP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_IMP), - SPELL_REANIMATE_MINOTAUR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_MINOTAUR), - SPELL_REANIMATE_SCORPION(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_SCORPION), - SPELL_REANIMATE_BEAR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_BEAR), - SPELL_REANIMATE_UNICORN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_UNICORN), - SPELL_REANIMATE_DOG(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DOG), - SPELL_REANIMATE_CHAOS_DRUID(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_CHAOS_DRUID), - SPELL_REANIMATE_GIANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_GIANT), - SPELL_REANIMATE_OGRE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_OGRE), - SPELL_REANIMATE_ELF(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_ELF), - SPELL_REANIMATE_TROLL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_TROLL), - SPELL_REANIMATE_HORROR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_HORROR), - SPELL_REANIMATE_KALPHITE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_KALPHITE), - SPELL_REANIMATE_DAGANNOTH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DAGANNOTH), - SPELL_REANIMATE_BLOODVELD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_BLOODVELD), - SPELL_REANIMATE_TZHAAR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_TZHAAR), - SPELL_REANIMATE_DEMON(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DEMON), - SPELL_REANIMATE_AVIANSIE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_AVIANSIE), - SPELL_REANIMATE_ABYSSAL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_ABYSSAL), - SPELL_REANIMATE_DRAGON(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DRAGON), - /* END OF ARCEUUS SPELL BOOK WIDGETS*/ - - MULTICOMBAT_FIXED(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.MULTICOMBAT_INDICATOR), - MULTICOMBAT_RESIZEABLE(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR), - - FULLSCREEN_MAP_ROOT(WidgetID.FULLSCREEN_CONTAINER_TLI, WidgetID.FullScreenMap.ROOT), - - MUSICTAB_INTERFACE(WidgetID.MUSICTAB_GROUP_ID, 1), - MUSICTAB_SONG_BOX(WidgetID.MUSICTAB_GROUP_ID, 2), - MUSICTAB_ALL_SONGS(WidgetID.MUSICTAB_GROUP_ID, 3), - MUSICTAB_SCROLLBAR(WidgetID.MUSICTAB_GROUP_ID, 4), - MUSICTAB_PLAYING(WidgetID.MUSICTAB_GROUP_ID, 5), - MUSICTAB_CURRENT_SONG_NAME(WidgetID.MUSICTAB_GROUP_ID, 6), - MUSICTAB_AUTO_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 7), - MUSICTAB_AUTO_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 8), - MUSICTAB_MANUAL_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 9), - MUSICTAB_MANUAL_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 10), - MUSICTAB_LOOP_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 11), - MUSICTAB_LOOP_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 12), - MUSICTAB_UNLOCKED_SONGS(WidgetID.MUSICTAB_GROUP_ID, 13), - - QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB), - - EQUIPMENT_MELEE_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MELEE_STRENGTH), - EQUIPMENT_RANGED_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.RANGED_STRENGTH), - EQUIPMENT_MAGIC_DAMAGE(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MAGIC_DAMAGE), - EQUIP_YOUR_CHARACTER(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.EQUIP_YOUR_CHARACTER), - - BANK_PIN_TOP_LEFT_TEXT(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.TOP_LEFT_TEXT), - BANK_PIN_EXIT_BUTTON(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.EXIT_BUTTON), - BANK_PIN_FORGOT_BUTTON(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.FORGOT_BUTTON), - BANK_PIN_FIRST_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.FIRST_ENTERED), - BANK_PIN_SECOND_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.SECOND_ENTERED), - BANK_PIN_THIRD_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.THIRD_ENTERED), - BANK_PIN_FOURTH_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.FOURTH_ENTERED), - BANK_PIN_INSTRUCTION_TEXT(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.INSTRUCTION_TEXT), - BANK_PIN_1(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_1), - BANK_PIN_2(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_2), - BANK_PIN_3(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_3), - BANK_PIN_4(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_4), - BANK_PIN_5(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_5), - BANK_PIN_6(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_6), - BANK_PIN_7(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_7), - BANK_PIN_8(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_8), - BANK_PIN_9(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_9), - BANK_PIN_10(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_10), - - XP_DROP_1(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_1), - XP_DROP_2(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_2), - XP_DROP_3(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_3), - XP_DROP_4(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_4), - XP_DROP_5(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_5), - XP_DROP_6(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_6), - XP_DROP_7(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_7), - - JEWELLERY_BOX_DUEL_RING(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.DUEL_RING), - JEWELLERY_BOX_GAME_NECK(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.GAME_NECK), - JEWELLERY_BOX_COMB_BRAC(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.COMB_BRAC), - JEWELLERY_BOX_SKIL_NECK(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.SKIL_NECK), - JEWELLERY_BOX_RING_OFGP(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.RING_OFGP), - JEWELLERY_BOX_AMUL_GLOR(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.AMUL_GLOR), - OPTIONS_CAMERA_ZOOM_SLIDER_HANDLE(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.CAMERA_ZOOM_SLIDER_HANDLE), - OPTIONS_MUSIC_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.MUSIC_SLIDER), - OPTIONS_SOUND_EFFECT_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.SOUND_EFFECT_SLIDER), - OPTIONS_AREA_SOUND_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.AREA_SOUND_SLIDER), - - TRADING_WITH(WidgetID.PLAYER_TRADE_SCREEN_GROUP_ID, WidgetID.TradeScreen.FIRST_TRADING_WITH), - SECOND_TRADING_WITH(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_TRADING_WITH), - SECOND_TRADING_WITH_ACCEPT_BUTTON(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_ACCEPT_FUNC), - SECOND_TRADING_WITH_ACCEPT_TEXT(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_ACCEPT_TEXT), - SECOND_TRADING_WITH_DECLINE_BUTTON(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_DECLINE_FUNC), - SECOND_TRADING_WITH_DECLINE_TEXT(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_DECLINE_TEXT), - SECOND_TRADING_WITH_MY_OFFER(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_MY_OFFER), - SECOND_TRADING_WITH_THEIR_OFFER(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_THEIR_OFFER), - SECOND_TRADING_WITH_MY_ITEMS(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_MY_ITEMS), - SECOND_TRADING_WITH_THEIR_ITEMS(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_THEIR_ITEMS), - - GAUNTLET_MAP(WidgetID.GAUNTLET_MAP_GROUP_ID, WidgetID.GauntletMap.CONTAINER), - - SETTINGS_INIT(WidgetID.SETTINGS_GROUP_ID, WidgetID.Settings.INIT), - - SHOP_ITEMS_CONTAINER(WidgetID.SHOP_GROUP_ID, WidgetID.Shop.ITEMS_CONTAINER), - ; - - private final int groupId; - private final int childId; - - WidgetInfo(int groupId, int childId) - { - this.groupId = groupId; - this.childId = childId; - } - - /** - * Gets the ID of the group-child pairing. - * - * @return the ID - */ - public int getId() - { - return groupId << 16 | childId; - } - - /** - * Gets the group ID of the pair. - * - * @return the group ID - */ - public int getGroupId() - { - return groupId; - } - - /** - * Gets the ID of the child in the group. - * - * @return the child ID - */ - public int getChildId() - { - return childId; - } - - /** - * Gets the packed widget ID. - * - * @return the packed ID - */ - public int getPackedId() - { - return groupId << 16 | childId; - } - - public static int PACK(int groupId, int childId) - { - return groupId << 16 | childId; - } - - /** - * Utility method that converts an ID returned by {@link #getId()} back - * to its group ID. - * - * @param id passed group-child ID - * @return the group ID - */ - public static int TO_GROUP(int id) - { - return id >>> 16; - } - - /** - * Utility method that converts an ID returned by {@link #getId()} back - * to its child ID. - * - * @param id passed group-child ID - * @return the child ID - */ - public static int TO_CHILD(int id) - { - return id & 0xFFFF; - } -} diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index ae78f52aa2..5e8c696770 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -513,15 +513,6 @@ public interface Client extends GameShell @Nullable Widget getWidget(WidgetInfo widget); - /** - * Gets a widget from our extended WidgetInfo - * - * @param widget the widget info - * @return the widget - */ - @Nullable - Widget getWidget(com.openosrs.api.widgets.WidgetInfo widget); - /** * Gets a widget by its raw group ID and child ID. *

diff --git a/runelite-api/src/main/java/net/runelite/api/kit/KitType.java b/runelite-api/src/main/java/net/runelite/api/kit/KitType.java index da8f66f46b..930e91d1dc 100644 --- a/runelite-api/src/main/java/net/runelite/api/kit/KitType.java +++ b/runelite-api/src/main/java/net/runelite/api/kit/KitType.java @@ -26,7 +26,7 @@ package net.runelite.api.kit; import lombok.AllArgsConstructor; import lombok.Getter; -import com.openosrs.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetInfo; /** * Represents an equipment slot in a players composition. diff --git a/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java b/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java index a061123d82..a768df8928 100644 --- a/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java +++ b/runelite-api/src/main/java/net/runelite/api/queries/ShopItemQuery.java @@ -32,7 +32,7 @@ import java.util.stream.Collectors; import net.runelite.api.Client; import net.runelite.api.QueryResults; import net.runelite.api.widgets.Widget; -import com.openosrs.api.widgets.WidgetInfo; +import net.runelite.api.widgets.WidgetInfo; import net.runelite.api.widgets.WidgetItem; public class ShopItemQuery extends WidgetItemQuery diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 2df9dcc2b6..fed35c6c11 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -164,6 +164,20 @@ public class WidgetID public static final int DUEL_INVENTORY_GROUP_ID = 421; public static final int DUEL_INVENTORY_OTHER_GROUP_ID = 481; public static final int TRAILBLAZER_AREAS_GROUP_ID = 512; + public static final int DIALOG_MINIGAME_GROUP_ID = 229; + public static final int PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID = 243; + public static final int GAUNTLET_MAP_GROUP_ID = 638; + public static final int PLAYER_TRADE_CONFIRM_GROUP_ID = 334; + public static final int OPTIONS_GROUP_ID = 261; + public static final int JEWELLERY_BOX_GROUP_ID = 590; + public static final int EQUIPMENT_PAGE_GROUP_ID = 84; + public static final int QUESTTAB_GROUP_ID = 629; + public static final int MUSICTAB_GROUP_ID = 239; + public static final int FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID = 608; + public static final int THEATRE_OF_BLOOD_PARTY_GROUP_ID = 28; + public static final int DIALOG_NOTIFICATION_GROUP_ID = 229; + public static final int DIALOG_SPRITE2_ID = 11; + public static final int MULTISKILL_MENU_GROUP_ID = 270; static class WorldMap { @@ -197,12 +211,18 @@ public class WidgetID static class PestControlBoat { static final int INFO = 3; + + static final int NEXT_DEPARTURE = 4; + static final int PLAYERS_READY = 5; + static final int POINTS = 6; } static class PestControl { static final int INFO = 3; + static final int TIME = 6; + static final int ACTIVITY_BAR = 12; static final int ACTIVITY_PROGRESS = 14; @@ -269,6 +289,8 @@ public class WidgetID static final int TAB_CONTAINER = 10; static final int ITEM_CONTAINER = 12; static final int SCROLLBAR = 13; + static final int UNNOTED_BUTTON = 21; + static final int NOTED_BUTTON = 23; static final int SEARCH_BUTTON_BACKGROUND = 39; static final int DEPOSIT_INVENTORY = 41; static final int DEPOSIT_EQUIPMENT = 43; @@ -285,6 +307,14 @@ public class WidgetID static final int WINDOW_BORDERS = 2; static final int HISTORY_BUTTON = 3; static final int BACK_BUTTON = 4; + static final int OFFER1 = 7; + static final int OFFER2 = 8; + static final int OFFER3 = 9; + static final int OFFER4 = 10; + static final int OFFER5 = 11; + static final int OFFER6 = 12; + static final int OFFER7 = 13; + static final int OFFER8 = 14; static final int OFFER_CONTAINER = 24; static final int OFFER_DESCRIPTION = 25; static final int OFFER_PRICE = 26; @@ -303,12 +333,47 @@ public class WidgetID static class Shop { + static final int ITEMS_CONTAINER = 2; static final int INVENTORY_ITEM_CONTAINER = 0; } static class Smithing { static final int INVENTORY_ITEM_CONTAINER = 0; + + static final int QTY_1 = 3; + static final int QTY_5 = 4; + static final int QTY_10 = 5; + static final int QTY_X = 6; + static final int QTY_ALL = 7; + + static final int DAGGER = 9; + static final int SWORD = 10; + static final int SCIMITAR = 11; + static final int LONG_SWORD = 12; + static final int TWO_H_SWORD = 13; + static final int AXE = 14; + static final int MACE = 15; + static final int WARHAMMER = 16; + static final int BATTLE_AXE = 17; + static final int CLAWS = 18; + static final int CHAIN_BODY = 19; + static final int PLATE_LEGS = 20; + static final int PLATE_SKIRT = 21; + static final int PLATE_BODY = 22; + static final int NAILS = 23; + static final int MED_HELM = 24; + static final int FULL_HELM = 25; + static final int SQ_SHIELD = 26; + static final int KITE_SHIELD = 27; + static final int EXCLUSIVE1 = 28; + static final int DART_TIPS = 29; + static final int ARROW_HEADS = 30; + static final int KNIVES = 31; + static final int EXCLUSIVE2 = 32; + static final int JAVELIN_HEADS = 33; + static final int BOLTS = 34; + static final int LIMBS = 35; } static class GuidePrices @@ -319,6 +384,17 @@ public class WidgetID static class Equipment { + static final int HELMET = 14; + static final int CAPE = 15; + static final int AMULET = 16; + static final int WEAPON = 17; + static final int BODY = 18; + static final int SHIELD = 19; + static final int LEGS = 20; + static final int GLOVES = 21; + static final int BOOTS = 22; + static final int RING = 23; + static final int AMMO = 24; static final int INVENTORY_ITEM_CONTAINER = 0; } @@ -346,6 +422,7 @@ public class WidgetID static final int TOGGLE_RUN_ORB = 22; // Has the "Toggle run" name static final int RUN_ORB_TEXT = 23; static final int SPEC_ORB = 28; + static final int SPEC_CLICKBOX = 30; static final int WORLDMAP_ORB = 41; static final int WIKI_BANNER = 43; } @@ -582,6 +659,9 @@ public class WidgetID static final int SPELL_ICON = 28; static final int SPELL_TEXT = 29; static final int AUTO_RETALIATE = 30; + static final int SPECIAL_ATTACK_BAR = 34; + static final int SPECIAL_ATTACK_CLICKBOX = 36; + static final int TOOLTIP = 41; } static class VolcanicMine @@ -608,7 +688,6 @@ public class WidgetID static final int ROLE_SPRITE = 12; static final int ROLE = 13; } - static class HLR { static final int TEAMMATE1 = 19; @@ -616,7 +695,32 @@ public class WidgetID static final int TEAMMATE3 = 27; static final int TEAMMATE4 = 31; } - + static class HORN_GLORY + { + static final int ATTACKER = 5; + static final int DEFENDER = 6; + static final int COLLECTOR = 7; + static final int HEALER = 8; + } + static class REWARD_VALUES + { + static final int RUNNERS_PASSED = 14; + static final int HITPOINTS_REPLENISHED = 19; + static final int WRONG_POISON_PACKS_USED = 20; + static final int EGGS_COLLECTED = 21; + static final int FAILED_ATTACKER_ATTACKS = 22; + static final int RUNNERS_PASSED_POINTS = 24; + static final int RANGERS_KILLED = 25; + static final int FIGHTERS_KILLED = 26; + static final int HEALERS_KILLED = 27; + static final int RUNNERS_KILLED = 28; + static final int HITPOINTS_REPLENISHED_POINTS = 29; + static final int WRONG_POISON_PACKS_USED_POINTS = 30; + static final int EGGS_COLLECTED_POINTS = 31; + static final int FAILED_ATTACKER_ATTACKS_POINTS = 32; + static final int BASE_POINTS = 33; + static final int HONOUR_POINTS_REWARD = 49; + } static final int ROLE_SPRITE = 11; static final int ROLE = 12; @@ -632,6 +736,7 @@ public class WidgetID { static final int SKILL = 1; static final int LEVEL = 2; + static final int CONTINUE = 3; } static class QuestCompleted @@ -671,6 +776,7 @@ public class WidgetID static final int LIGHT_BOX = 1; static final int LIGHT_BOX_WINDOW = 2; static final int LIGHT_BULB_CONTAINER = 3; + static final int LIGHT_BOX_BUTTON_CONTAINER = 6; static final int BUTTON_A = 8; static final int BUTTON_B = 9; static final int BUTTON_C = 10; @@ -756,7 +862,9 @@ public class WidgetID static class WorldSwitcher { + static final int CONTAINER = 1; static final int WORLD_LIST = 16; + static final int LOGOUT_BUTTON = 23; } static class FossilOxygen @@ -792,6 +900,10 @@ public class WidgetID static class Pvp { + static final int FOG_OVERLAY = 1; + static final int PVP_WIDGET_CONTAINER = 54; // OUTDATED? + static final int SKULL = 56; // OUTDATED? + static final int ATTACK_RANGE = 59; // OUTDATED? static final int BOUNTY_HUNTER_INFO = 6; static final int KILLDEATH_RATIO = 28; static final int SKULL_CONTAINER = 48; @@ -929,9 +1041,28 @@ public class WidgetID static final int CONTAINER = 2; } + // Also used for many other interfaces! static class BankPin { static final int CONTAINER = 0; + static final int TOP_LEFT_TEXT = 2; + static final int FIRST_ENTERED = 3; + static final int SECOND_ENTERED = 4; + static final int THIRD_ENTERED = 5; + static final int FOURTH_ENTERED = 6; + static final int INSTRUCTION_TEXT = 10; + static final int EXIT_BUTTON = 13; + static final int FORGOT_BUTTON = 15; + static final int BUTTON_1 = 16; + static final int BUTTON_2 = 18; + static final int BUTTON_3 = 20; + static final int BUTTON_4 = 22; + static final int BUTTON_5 = 24; + static final int BUTTON_6 = 26; + static final int BUTTON_7 = 28; + static final int BUTTON_8 = 30; + static final int BUTTON_9 = 32; + static final int BUTTON_10 = 34; } static class EncounterHealthBar @@ -943,4 +1074,334 @@ public class WidgetID { static final int TELEPORT = 59; } + + + static class DialogPlayer + { + static final int HEAD_MODEL = 1; + static final int NAME = 2; + static final int CONTINUE = 3; + static final int TEXT = 4; + } + + static class DialogNotification + { + static final int TEXT = 0; + static final int CONTINUE = 1; + } + + static class DialogOption + { + static final int TEXT = 0; + static final int OPTION1 = 1; + static final int OPTION2 = 2; + static final int OPTION3 = 3; + static final int OPTION4 = 4; + static final int OPTION5 = 5; + } + + static class PestControlExchangeWindow + { + static final int ITEM_LIST = 2; + static final int BOTTOM = 5; + static final int POINTS = 8; + static final int CONFIRM_BUTTON = 6; + } + + static class MinigameDialog + { + static final int TEXT = 1; + static final int CONTINUE = 2; + } + + static class TheatreOfBlood + { + static final int RAIDING_PARTY = 9; + static final int ORB_BOX = 10; + static final int BOSS_HEALTH_BAR = 35; + } + + static class TheatreOfBloodParty + { + static final int CONTAINER = 10; + } + + static class EquipmentWidgetIdentifiers + { + static final int EQUIP_YOUR_CHARACTER = 3; + static final int STAB_ATTACK_BONUS = 24; + static final int SLASH_ATTACK_BONUS = 25; + static final int CRUSH_ATTACK_BONUS = 26; + static final int MAGIC_ATTACK_BONUS = 27; + static final int RANGED_ATTACK_BONUS = 28; + static final int STAB_DEFENCE_BONUS = 30; + static final int SLASH_DEFENCE_BONUS = 31; + static final int CRUSH_DEFENCE_BONUS = 32; + static final int MAGIC_DEFENCE_BONUS = 33; + static final int RANGED_DEFENCE_BONUS = 34; + static final int MELEE_STRENGTH = 36; + static final int RANGED_STRENGTH = 37; + static final int MAGIC_DAMAGE = 38; + static final int PRAYER_BONUS = 39; + static final int UNDEAD_DAMAGE_BONUS = 41; + static final int SLAYER_DAMAGE_BONUS = 42; + static final int WEIGHT = 49; + } + + static class FossilMushroomTeleport + { + static final int ROOT = 2; + static final int HOUSE_ON_HILL = 4; + static final int VERDANT_VALLEY = 8; + static final int SWAMP = 12; + static final int MUSHROOM_MEADOW = 16; + } + + static class SpellBook + { + static final int FILTERED_SPELLS_BOUNDS = 3; + static final int TOOLTIP = 189; + + // NORMAL SPELLS + static final int LUMBRIDGE_HOME_TELEPORT = 5; + static final int WIND_STRIKE = 6; + static final int CONFUSE = 7; + static final int ENCHANT_CROSSBOW_BOLT = 8; + static final int WATER_STRIKE = 9; + static final int LVL_1_ENCHANT = 10; + static final int EARTH_STRIKE = 11; + static final int WEAKEN = 12; + static final int FIRE_STRIKE = 13; + static final int BONES_TO_BANANAS = 14; + static final int WIND_BOLT = 15; + static final int CURSE = 16; + static final int BIND = 17; + static final int LOW_LEVEL_ALCHEMY = 18; + static final int WATER_BOLT = 19; + static final int VARROCK_TELEPORT = 20; + static final int LVL_2_ENCHANT = 21; + static final int EARTH_BOLT = 22; + static final int LUMBRIDGE_TELEPORT = 23; + static final int TELEKINETIC_GRAB = 24; + static final int FIRE_BOLT = 25; + static final int FALADOR_TELEPORT = 26; + static final int CRUMBLE_UNDEAD = 27; + static final int TELEPORT_TO_HOUSE = 28; + static final int WIND_BLAST = 29; + static final int SUPERHEAT_ITEM = 30; + static final int CAMELOT_TELEPORT = 31; + static final int WATER_BLAST = 32; + static final int LVL_3_ENCHANT = 33; + static final int IBAN_BLAST = 34; + static final int SNARE = 35; + static final int MAGIC_DART = 36; + static final int ARDOUGNE_TELEPORT = 37; + static final int EARTH_BLAST = 38; + static final int HIGH_LEVEL_ALCHEMY = 39; + static final int CHARGE_WATER_ORB = 40; + static final int LVL_4_ENCHANT = 41; + static final int WATCHTOWER_TELEPORT = 42; + static final int FIRE_BLAST = 43; + static final int CHARGE_EARTH_ORB = 44; + static final int BONES_TO_PEACHES = 45; + static final int SARADOMIN_STRIKE = 46; + static final int CLAWS_OF_GUTHIX = 47; + static final int FLAMES_OF_ZAMORAK = 48; + static final int TROLLHEIM_TELEPORT = 49; + static final int WIND_WAVE = 50; + static final int CHARGE_FIRE_ORB = 51; + static final int TELEPORT_TO_APE_ATOLL = 52; + static final int WATER_WAVE = 53; + static final int CHARGE_AIR_ORB = 54; + static final int VULNERABILITY = 55; + static final int LVL_5_ENCHANT = 56; + static final int TELEPORT_TO_KOUREND = 57; + static final int EARTH_WAVE = 58; + static final int ENFEEBLE = 59; + static final int TELEOTHER_LUMBRIDGE = 60; + static final int FIRE_WAVE = 61; + static final int ENTANGLE = 62; + static final int STUN = 63; + static final int CHARGE = 64; + static final int WIND_SURGE = 65; + static final int TELEOTHER_FALADOR = 66; + static final int WATER_SURGE = 67; + static final int TELE_BLOCK = 68; + static final int BOUNTY_TARGET_TELEPORT = 69; + static final int LVL_6_ENCHANT = 70; + static final int TELEOTHER_CAMELOT = 71; + static final int EARTH_SURGE = 72; + static final int LVL_7_ENCHANT = 73; + static final int FIRE_SURGE = 74; + + // ANCIENT SPELLS + static final int ICE_RUSH = 75; + static final int ICE_BLITZ = 76; + static final int ICE_BURST = 77; + static final int ICE_BARRAGE = 78; + static final int BLOOD_RUSH = 79; + static final int BLOOD_BLITZ = 80; + static final int BLOOD_BURST = 81; + static final int BLOOD_BARRAGE = 82; + static final int SMOKE_RUSH = 83; + static final int SMOKE_BLITZ = 84; + static final int SMOKE_BURST = 85; + static final int SMOKE_BARRAGE = 86; + static final int SHADOW_RUSH = 87; + static final int SHADOW_BLITZ = 88; + static final int SHADOW_BURST = 89; + static final int SHADOW_BARRAGE = 90; + static final int PADDEWWA_TELEPORT = 91; + static final int SENNTISTEN_TELEPORT = 92; + static final int KHARYRLL_TELEPORT = 93; + static final int LASSAR_TELEPORT = 94; + static final int DAREEYAK_TELEPORT = 95; + static final int CARRALLANGER_TELEPORT = 96; + static final int ANNAKARL_TELEPORT = 97; + static final int GHORROCK_TELEPORT = 98; + static final int EDGEVILLE_HOME_TELEPORT = 99; + + // LUNAR SPELLS + static final int LUNAR_HOME_TELEPORT = 100; + static final int BAKE_PIE = 101; + static final int CURE_PLANT = 102; + static final int MONSTER_EXAMINE = 103; + static final int NPC_CONTACT = 104; + static final int CURE_OTHER = 105; + static final int HUMIDIFY = 106; + static final int MOONCLAN_TELEPORT = 107; + static final int TELE_GROUP_MOONCLAN = 108; + static final int CURE_ME = 109; + static final int HUNTER_KIT = 110; + static final int WATERBIRTH_TELEPORT = 111; + static final int TELE_GROUP_WATERBIRTH = 112; + static final int CURE_GROUP = 113; + static final int STAT_SPY = 114; + static final int BARBARIAN_TELEPORT = 115; + static final int TELE_GROUP_BARBARIAN = 116; + static final int SUPERGLASS_MAKE = 117; + static final int TAN_LEATHER = 118; + static final int KHAZARD_TELEPORT = 119; + static final int TELE_GROUP_KHAZARD = 120; + static final int DREAM = 121; + static final int STRING_JEWELLERY = 122; + static final int STAT_RESTORE_POT_SHARE = 123; + static final int MAGIC_IMBUE = 124; + static final int FERTILE_SOIL = 125; + static final int BOOST_POTION_SHARE = 126; + static final int FISHING_GUILD_TELEPORT = 127; + static final int TELE_GROUP_FISHING_GUILD = 128; + static final int PLANK_MAKE = 129; + static final int CATHERBY_TELEPORT = 130; + static final int TELE_GROUP_CATHERBY = 131; + static final int RECHARGE_DRAGONSTONE = 132; + static final int ICE_PLATEAU_TELEPORT = 133; + static final int TELE_GROUP_ICE_PLATEAU = 134; + static final int ENERGY_TRANSFER = 135; + static final int HEAL_OTHER = 136; + static final int VENGEANCE_OTHER = 137; + static final int VENGEANCE = 138; + static final int HEAL_GROUP = 139; + static final int SPELLBOOK_SWAP = 140; + static final int GEOMANCY = 141; + static final int SPIN_FLAX = 142; + static final int OURANIA_TELEPORT = 143; + + // ARCEUUS SPELLS + static final int ARCEUUS_HOME_TELEPORT = 144; + static final int BATTLEFRONT_TELEPORT = 179; + // HEADS + static final int REANIMATE_GOBLIN = 145; + static final int REANIMATE_MONKEY = 147; + static final int REANIMATE_IMP = 148; + static final int REANIMATE_MINOTAUR = 149; + static final int REANIMATE_SCORPION = 151; + static final int REANIMATE_BEAR = 152; + static final int REANIMATE_UNICORN = 153; + static final int REANIMATE_DOG = 154; + static final int REANIMATE_CHAOS_DRUID = 156; + static final int REANIMATE_GIANT = 158; + static final int REANIMATE_OGRE = 160; + static final int REANIMATE_ELF = 161; + static final int REANIMATE_TROLL = 162; + static final int REANIMATE_HORROR = 164; + static final int REANIMATE_KALPHITE = 165; + static final int REANIMATE_DAGANNOTH = 167; + static final int REANIMATE_BLOODVELD = 168; + static final int REANIMATE_TZHAAR = 170; + static final int REANIMATE_DEMON = 172; + static final int REANIMATE_AVIANSIE = 173; + static final int REANIMATE_ABYSSAL = 176; + static final int REANIMATE_DRAGON = 178; + + } + + static class DialogSprite2 + { + static final int SPRITE1 = 1; + static final int TEXT = 2; + static final int SPRITE2 = 3; + static final int CONTINUE = 4; + } + + static class QuestTab + { + static final int QUEST_TAB = 3; + } + + public static class TradeScreen + { + public static final int FIRST_TRADING_WITH = 31; + public static final int SECOND_ACCEPT_FUNC = 13; + public static final int SECOND_DECLINE_FUNC = 14; + public static final int SECOND_MY_OFFER = 23; + public static final int SECOND_THEIR_OFFER = 24; + public static final int SECOND_ACCEPT_TEXT = 25; + public static final int SECOND_DECLINE_TEXT = 26; + public static final int SECOND_MY_ITEMS = 28; + public static final int SECOND_THEIR_ITEMS = 29; + public static final int SECOND_TRADING_WITH = 30; + } + + public static class DuelConfig + { + public static final int CONFIG_GROUP_IP = 482; + public static final int TITLE = 35; + public static final int OPPONENT_ATT = 9; + public static final int OPPONENT_STR = 13; + public static final int OPPONENT_DEF = 17; + public static final int OPPONENT_HP = 21; + } + + public static class DuelResult + { + public static final int RESULT_GROUP_ID = 372; + public static final int TITLE = 16; + public static final int TOTAL_STAKED = 32; + public static final int TOTAL_TAX = 39; + public static final int WINNINGS = 40; + } + + static class JewelBox + { + static final int DUEL_RING = 2; + static final int GAME_NECK = 3; + static final int COMB_BRAC = 4; + static final int SKIL_NECK = 5; + static final int RING_OFGP = 6; + static final int AMUL_GLOR = 7; // yes + } + + static class Options + { + static final int CAMERA_ZOOM_SLIDER_HANDLE = 15; + static final int MUSIC_SLIDER = 37; + static final int SOUND_EFFECT_SLIDER = 43; + static final int AREA_SOUND_SLIDER = 49; + } + + static class GauntletMap + { + static final int CONTAINER = 4; + } } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 123a118843..34ef03e1bb 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -538,6 +538,403 @@ public enum WidgetInfo MULTICOMBAT_FIXED(WidgetID.FIXED_VIEWPORT_GROUP_ID, WidgetID.FixedViewport.MULTICOMBAT_INDICATOR), MULTICOMBAT_RESIZEABLE_MODERN(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR), MULTICOMBAT_RESIZEABLE_CLASSIC(WidgetID.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR), + + //OpenOSRS + WORLD_MAP_BUTTON_BORDER(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), + + EQUIPMENT_HELMET(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.HELMET), + EQUIPMENT_CAPE(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.CAPE), + EQUIPMENT_AMULET(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.AMULET), + EQUIPMENT_WEAPON(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.WEAPON), + EQUIPMENT_BODY(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.BODY), + EQUIPMENT_SHIELD(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.SHIELD), + EQUIPMENT_LEGS(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.LEGS), + EQUIPMENT_GLOVES(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.GLOVES), + EQUIPMENT_BOOTS(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.BOOTS), + EQUIPMENT_RING(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.RING), + EQUIPMENT_AMMO(WidgetID.EQUIPMENT_GROUP_ID, WidgetID.Equipment.AMMO), + + MINIGAME_DIALOG(WidgetID.DIALOG_MINIGAME_GROUP_ID, 0), + MINIGAME_DIALOG_TEXT(WidgetID.DIALOG_MINIGAME_GROUP_ID, WidgetID.MinigameDialog.TEXT), + MINIGAME_DIALOG_CONTINUE(WidgetID.DIALOG_MINIGAME_GROUP_ID, WidgetID.MinigameDialog.CONTINUE), + PEST_CONTROL_EXCHANGE_WINDOW(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, 0), + PEST_CONTROL_EXCHANGE_WINDOW_POINTS(WidgetID.PEST_CONTROL_EXCHANGE_WINDOW_GROUP_ID, WidgetID.PestControlExchangeWindow.POINTS), + + PEST_CONTROL_BOAT_INFO_POINTS(WidgetID.PEST_CONTROL_BOAT_GROUP_ID, WidgetID.PestControlBoat.POINTS), + PEST_CONTROL_INFO_TIME(WidgetID.PEST_CONTROL_GROUP_ID, WidgetID.PestControl.TIME), + + BANK_UNNOTED_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.UNNOTED_BUTTON), + BANK_NOTED_BUTTON(WidgetID.BANK_GROUP_ID, WidgetID.Bank.NOTED_BUTTON), + + GRAND_EXCHANGE_HISTORY_BUTTON(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.HISTORY_BUTTON), + GRAND_EXCHANGE_BACK_BUTTON(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.BACK_BUTTON), + GRAND_EXCHANGE_OFFER1(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER1), + GRAND_EXCHANGE_OFFER2(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER2), + GRAND_EXCHANGE_OFFER3(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER3), + GRAND_EXCHANGE_OFFER4(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER4), + GRAND_EXCHANGE_OFFER5(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER5), + GRAND_EXCHANGE_OFFER6(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER6), + GRAND_EXCHANGE_OFFER7(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER7), + GRAND_EXCHANGE_OFFER8(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER8), + + GRAND_EXCHANGE_OFFER_CONFIRM_BUTTON(WidgetID.GRAND_EXCHANGE_GROUP_ID, WidgetID.GrandExchange.OFFER_CONFIRM_BUTTON), + + SMITHING_ANVIL_DAGGER(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.DAGGER), + SMITHING_ANVIL_SWORD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.SWORD), + SMITHING_ANVIL_SCIMITAR(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.SCIMITAR), + SMITHING_ANVIL_LONG_SWORD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.LONG_SWORD), + SMITHING_ANVIL_TWO_H_SWORD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.TWO_H_SWORD), + SMITHING_ANVIL_AXE(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.AXE), + SMITHING_ANVIL_MACE(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.MACE), + SMITHING_ANVIL_WARHAMMER(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.WARHAMMER), + SMITHING_ANVIL_BATTLE_AXE(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.BATTLE_AXE), + SMITHING_ANVIL_CLAWS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.CLAWS), + SMITHING_ANVIL_CHAIN_BODY(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.CHAIN_BODY), + SMITHING_ANVIL_PLATE_LEGS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.PLATE_LEGS), + SMITHING_ANVIL_PLATE_SKIRT(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.PLATE_SKIRT), + SMITHING_ANVIL_PLATE_BODY(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.PLATE_BODY), + SMITHING_ANVIL_NAILS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.NAILS), + SMITHING_ANVIL_MED_HELM(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.MED_HELM), + SMITHING_ANVIL_FULL_HELM(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.FULL_HELM), + SMITHING_ANVIL_SQ_SHIELD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.SQ_SHIELD), + SMITHING_ANVIL_KITE_SHIELD(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.KITE_SHIELD), + SMITHING_ANVIL_DART_TIPS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.DART_TIPS), + SMITHING_ANVIL_ARROW_HEADS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.ARROW_HEADS), + SMITHING_ANVIL_KNIVES(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.KNIVES), + SMITHING_ANVIL_JAVELIN_HEADS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.JAVELIN_HEADS), + SMITHING_ANVIL_BOLTS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.BOLTS), + SMITHING_ANVIL_LIMBS(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.LIMBS), + SMITHING_ANVIL_EXCLUSIVE1(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.EXCLUSIVE1), + SMITHING_ANVIL_EXCLUSIVE2(WidgetID.SMITHING_GROUP_ID, WidgetID.Smithing.EXCLUSIVE2), + + MINIMAP_SPEC_CLICKBOX(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.SPEC_CLICKBOX), + + MINIMAP_WORLD_ORB(WidgetID.MINIMAP_GROUP_ID, WidgetID.Minimap.WORLDMAP_ORB), + + RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_TAB(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.SPELL_TAB), + + COMBAT_WEAPON(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.WEAPON_NAME), + + COMBAT_SPECIAL_ATTACK(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPECIAL_ATTACK_BAR), + COMBAT_SPECIAL_ATTACK_CLICKBOX(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.SPECIAL_ATTACK_CLICKBOX), + COMBAT_TOOLTIP(WidgetID.COMBAT_GROUP_ID, WidgetID.Combat.TOOLTIP), + + MULTI_SKILL_MENU(WidgetID.MULTISKILL_MENU_GROUP_ID, 0), + + DIALOG2_SPRITE(WidgetID.DIALOG_SPRITE2_ID, 0), + DIALOG2_SPRITE_SPRITE1(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.SPRITE1), + DIALOG2_SPRITE_SPRITE2(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.SPRITE2), + DIALOG2_SPRITE_TEXT(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.TEXT), + DIALOG2_SPRITE_CONTINUE(WidgetID.DIALOG_SPRITE2_ID, WidgetID.DialogSprite2.CONTINUE), + + DIALOG_PLAYER_NAME(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.NAME), + DIALOG_PLAYER_TEXT(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.TEXT), + DIALOG_PLAYER_HEAD_MODEL(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.HEAD_MODEL), + DIALOG_PLAYER_CONTINUE(WidgetID.DIALOG_PLAYER_GROUP_ID, WidgetID.DialogPlayer.CONTINUE), + + DIALOG_NOTIFICATION_TEXT(WidgetID.DIALOG_NOTIFICATION_GROUP_ID, WidgetID.DialogNotification.TEXT), + DIALOG_NOTIFICATION_CONTINUE(WidgetID.DIALOG_NOTIFICATION_GROUP_ID, WidgetID.DialogNotification.CONTINUE), + + DIALOG_OPTION_TEXT(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.TEXT), + DIALOG_OPTION_OPTION1(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION1), + DIALOG_OPTION_OPTION2(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION2), + DIALOG_OPTION_OPTION3(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION3), + DIALOG_OPTION_OPTION4(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION4), + DIALOG_OPTION_OPTION5(WidgetID.DIALOG_OPTION_GROUP_ID, WidgetID.DialogOption.OPTION5), + + BA_RUNNERS_PASSED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RUNNERS_PASSED), + BA_HITPOINTS_REPLENISHED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HITPOINTS_REPLENISHED), + BA_WRONG_POISON_PACKS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.WRONG_POISON_PACKS_USED), + BA_EGGS_COLLECTED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.EGGS_COLLECTED), + BA_FAILED_ATTACKER_ATTACKS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.FAILED_ATTACKER_ATTACKS), + BA_RUNNERS_PASSED_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RUNNERS_PASSED_POINTS), + BA_RANGERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RANGERS_KILLED), + BA_FIGHTERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.FIGHTERS_KILLED), + BA_HEALERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HEALERS_KILLED), + BA_RUNNERS_KILLED(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.RUNNERS_KILLED), + BA_HITPOINTS_REPLENISHED_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HITPOINTS_REPLENISHED_POINTS), + BA_WRONG_POISON_PACKS_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.WRONG_POISON_PACKS_USED_POINTS), + BA_EGGS_COLLECTED_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.EGGS_COLLECTED_POINTS), + BA_FAILED_ATTACKER_ATTACKS_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.FAILED_ATTACKER_ATTACKS_POINTS), + BA_HONOUR_POINTS_REWARD(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.HONOUR_POINTS_REWARD), + BA_BASE_POINTS(WidgetID.BA_REWARD_GROUP_ID, WidgetID.BarbarianAssault.REWARD_VALUES.BASE_POINTS), + + LEVEL_UP_CONTINUE(WidgetID.LEVEL_UP_GROUP_ID, WidgetID.LevelUp.CONTINUE), + + THEATRE_OF_BLOOD_PARTY(WidgetID.THEATRE_OF_BLOOD_PARTY_GROUP_ID, WidgetID.TheatreOfBloodParty.CONTAINER), + + LIGHT_BOX_BUTTON_CONTAINER(WidgetID.LIGHT_BOX_GROUP_ID, WidgetID.LightBox.LIGHT_BOX_BUTTON_CONTAINER), + + THEATRE_OF_BLOOD_HEALTH_ORBS(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.ORB_BOX), + THEATRE_OF_BLOOD_BOSS_HEALTH(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.BOSS_HEALTH_BAR), + THEATRE_OF_BLOOD_RAIDING_PARTY(WidgetID.THEATRE_OF_BLOOD_GROUP_ID, WidgetID.TheatreOfBlood.RAIDING_PARTY), + + WORLD_SWITCHER_CONTAINER(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.CONTAINER), + + WORLD_SWITCHER_LOGOUT_BUTTON(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.LOGOUT_BUTTON), + + FOSSIL_MUSHROOM_TELEPORT(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.ROOT), + FOSSIL_MUSHROOM_HOUSE(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.HOUSE_ON_HILL), + FOSSIL_MUSHROOM_VALLEY(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.VERDANT_VALLEY), + FOSSIL_MUSHROOM_SWAMP(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.SWAMP), + FOSSIL_MUSHROOM_MEADOW(WidgetID.FOSSIL_ISLAND_MUSHROOM_TELE_GROUP_ID, WidgetID.FossilMushroomTeleport.MUSHROOM_MEADOW), + + PVP_SKULL(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.SKULL), + PVP_ATTACK_RANGE(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.ATTACK_RANGE), + + SPELLBOOK(WidgetID.SPELLBOOK_GROUP_ID, 0), + SPELLBOOK_FILTERED_BOUNDS(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FILTERED_SPELLS_BOUNDS), + + /* STANDARD SPELL BOOK WIDGETS*/ + SPELL_WIND_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_STRIKE), + SPELL_CONFUSE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CONFUSE), + SPELL_ENCHANT_CROSSBOW_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENCHANT_CROSSBOW_BOLT), + SPELL_WATER_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_STRIKE), + SPELL_LVL_1_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_1_ENCHANT), + SPELL_EARTH_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_STRIKE), + SPELL_WEAKEN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WEAKEN), + SPELL_FIRE_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_STRIKE), + SPELL_BONES_TO_BANANAS(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BONES_TO_BANANAS), + SPELL_WIND_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_BOLT), + SPELL_CURSE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURSE), + SPELL_BIND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BIND), + SPELL_LOW_LEVEL_ALCHEMY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LOW_LEVEL_ALCHEMY), + SPELL_WATER_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_BOLT), + SPELL_VARROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VARROCK_TELEPORT), + SPELL_LVL_2_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_2_ENCHANT), + SPELL_EARTH_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_BOLT), + SPELL_LUMBRIDGE_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LUMBRIDGE_TELEPORT), + SPELL_TELEKINETIC_GRAB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEKINETIC_GRAB), + SPELL_FIRE_BOLT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_BOLT), + SPELL_FALADOR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FALADOR_TELEPORT), + SPELL_CRUMBLE_UNDEAD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CRUMBLE_UNDEAD), + SPELL_TELEPORT_TO_HOUSE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEPORT_TO_HOUSE), + SPELL_WIND_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_BLAST), + SPELL_SUPERHEAT_ITEM(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SUPERHEAT_ITEM), + SPELL_CAMELOT_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CAMELOT_TELEPORT), + SPELL_WATER_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_BLAST), + SPELL_LVL_3_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_3_ENCHANT), + SPELL_IBAN_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.IBAN_BLAST), + SPELL_SNARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SNARE), + SPELL_MAGIC_DART(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MAGIC_DART), + SPELL_ARDOUGNE_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ARDOUGNE_TELEPORT), + SPELL_EARTH_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_BLAST), + SPELL_HIGH_LEVEL_ALCHEMY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HIGH_LEVEL_ALCHEMY), + SPELL_CHARGE_WATER_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_WATER_ORB), + SPELL_LVL_4_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_4_ENCHANT), + SPELL_WATCHTOWER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATCHTOWER_TELEPORT), + SPELL_FIRE_BLAST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_BLAST), + SPELL_CHARGE_EARTH_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_EARTH_ORB), + SPELL_BONES_TO_PEACHES(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BONES_TO_PEACHES), + SPELL_SARADOMIN_STRIKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SARADOMIN_STRIKE), + SPELL_CLAWS_OF_GUTHIX(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CLAWS_OF_GUTHIX), + SPELL_FLAMES_OF_ZAMORAK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FLAMES_OF_ZAMORAK), + SPELL_TROLLHEIM_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TROLLHEIM_TELEPORT), + SPELL_WIND_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_WAVE), + SPELL_CHARGE_FIRE_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_FIRE_ORB), + SPELL_TELEPORT_TO_APE_ATOLL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEPORT_TO_APE_ATOLL), + SPELL_WATER_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_WAVE), + SPELL_CHARGE_AIR_ORB(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE_AIR_ORB), + SPELL_VULNERABILITY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VULNERABILITY), + SPELL_LVL_5_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_5_ENCHANT), + SPELL_TELEPORT_TO_KOUREND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEPORT_TO_KOUREND), + SPELL_EARTH_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_WAVE), + SPELL_ENFEEBLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENFEEBLE), + SPELL_FIRE_WAVE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_WAVE), + SPELL_ENTANGLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENTANGLE), + SPELL_TELEOTHER_LUMBRIDGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEOTHER_LUMBRIDGE), + SPELL_STUN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STUN), + SPELL_CHARGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CHARGE), + SPELL_WIND_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WIND_SURGE), + SPELL_TELEOTHER_FALADOR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEOTHER_FALADOR), + SPELL_WATER_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATER_SURGE), + SPELL_TELE_BLOCK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_BLOCK), + SPELL_LVL_6_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_6_ENCHANT), + SPELL_TELEOTHER_CAMELOT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELEOTHER_CAMELOT), + SPELL_EARTH_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EARTH_SURGE), + SPELL_LVL_7_ENCHANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LVL_7_ENCHANT), + SPELL_FIRE_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_SURGE), + SPELL_BOUNTY_TARGET_TELEPORT2(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), + /* END OF STANDARD SPELL BOOK WIDGETS*/ + + /* ANCIENT SPELL BOOK WIDGETS*/ + SPELL_ICE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_RUSH), + SPELL_ICE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BLITZ), + SPELL_ICE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BURST), + SPELL_ICE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BARRAGE), + SPELL_BLOOD_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_RUSH), + SPELL_BLOOD_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BLITZ), + SPELL_BLOOD_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BURST), + SPELL_BLOOD_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BARRAGE), + SPELL_SMOKE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_RUSH), + SPELL_SMOKE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BLITZ), + SPELL_SMOKE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BURST), + SPELL_SMOKE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BARRAGE), + SPELL_SHADOW_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_RUSH), + SPELL_SHADOW_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BLITZ), + SPELL_SHADOW_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BURST), + SPELL_SHADOW_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BARRAGE), + SPELL_PADDEWWA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.PADDEWWA_TELEPORT), + SPELL_SENNTISTEN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SENNTISTEN_TELEPORT), + SPELL_KHARYRLL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.KHARYRLL_TELEPORT), + SPELL_LASSAR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LASSAR_TELEPORT), + SPELL_DAREEYAK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.DAREEYAK_TELEPORT), + SPELL_CARRALLANGER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CARRALLANGER_TELEPORT), + SPELL_ANNAKARL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ANNAKARL_TELEPORT), + SPELL_GHORROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.GHORROCK_TELEPORT), + SPELL_BOUNTY_TARGET_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), + /* END OF ANCIENT SPELL BOOK WIDGETS*/ + + /* LUNAR SPELL BOOK WIDGETS*/ + SPELL_VENGEANCE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VENGEANCE_OTHER), + SPELL_VENGEANCE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VENGEANCE), + SPELL_BOUNTY_TARGET_TELEPORT3(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), + SPELL_BAKE_PIE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BAKE_PIE), + SPELL_CURE_PLANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_PLANT), + SPELL_MONSTER_EXAMINE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MONSTER_EXAMINE), + SPELL_NPC_CONTACT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.NPC_CONTACT), + SPELL_CURE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_OTHER), + SPELL_HUMIDIFY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HUMIDIFY), + SPELL_MOONCLAN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MOONCLAN_TELEPORT), + SPELL_TELE_GROUP_MOONCLAN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_MOONCLAN), + SPELL_CURE_ME(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_ME), + SPELL_HUNTER_KIT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HUNTER_KIT), + SPELL_WATERBIRTH_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.WATERBIRTH_TELEPORT), + SPELL_TELE_GROUP_WATERBIRTH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_WATERBIRTH), + SPELL_CURE_GROUP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CURE_GROUP), + SPELL_STAT_SPY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STAT_SPY), + SPELL_BARBARIAN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BARBARIAN_TELEPORT), + SPELL_TELE_GROUP_BARBARIAN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_BARBARIAN), + SPELL_SUPERGLASS_MAKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SUPERGLASS_MAKE), + SPELL_TAN_LEATHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TAN_LEATHER), + SPELL_KHAZARD_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.KHAZARD_TELEPORT), + SPELL_TELE_GROUP_KHAZARD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_KHAZARD), + SPELL_DREAM(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.DREAM), + SPELL_STRING_JEWELLERY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STRING_JEWELLERY), + SPELL_STAT_RESTORE_POT_SHARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.STAT_RESTORE_POT_SHARE), + SPELL_MAGIC_IMBUE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.MAGIC_IMBUE), + SPELL_FERTILE_SOIL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FERTILE_SOIL), + SPELL_BOOST_POTION_SHARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOOST_POTION_SHARE), + SPELL_FISHING_GUILD_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FISHING_GUILD_TELEPORT), + SPELL_TELE_GROUP_FISHING_GUILD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_FISHING_GUILD), + SPELL_PLANK_MAKE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.PLANK_MAKE), + SPELL_CATHERBY_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CATHERBY_TELEPORT), + SPELL_TELE_GROUP_CATHERBY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_CATHERBY), + SPELL_RECHARGE_DRAGONSTONE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.RECHARGE_DRAGONSTONE), + SPELL_ICE_PLATEAU_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_PLATEAU_TELEPORT), + SPELL_TELE_GROUP_ICE_PLATEAU(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_GROUP_ICE_PLATEAU), + SPELL_ENERGY_TRANSFER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENERGY_TRANSFER), + SPELL_HEAL_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HEAL_OTHER), + SPELL_HEAL_GROUP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.HEAL_GROUP), + SPELL_SPELLBOOK_SWAP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SPELLBOOK_SWAP), + SPELL_GEOMANCY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.GEOMANCY), + SPELL_SPIN_FLAX(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SPIN_FLAX), + SPELL_OURANIA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.OURANIA_TELEPORT), + /* END OF LUNAR SPELL BOOK WIDGETS*/ + SPELL_TOOLTIP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TOOLTIP), + /* ARCEUUS SPELL BOOK WIDGETS*/ + SPELL_BATTLEFRONT_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BATTLEFRONT_TELEPORT), + SPELL_REANIMATE_GOBLIN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_GOBLIN), + SPELL_REANIMATE_MONKEY(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_MONKEY), + SPELL_REANIMATE_IMP(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_IMP), + SPELL_REANIMATE_MINOTAUR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_MINOTAUR), + SPELL_REANIMATE_SCORPION(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_SCORPION), + SPELL_REANIMATE_BEAR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_BEAR), + SPELL_REANIMATE_UNICORN(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_UNICORN), + SPELL_REANIMATE_DOG(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DOG), + SPELL_REANIMATE_CHAOS_DRUID(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_CHAOS_DRUID), + SPELL_REANIMATE_GIANT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_GIANT), + SPELL_REANIMATE_OGRE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_OGRE), + SPELL_REANIMATE_ELF(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_ELF), + SPELL_REANIMATE_TROLL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_TROLL), + SPELL_REANIMATE_HORROR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_HORROR), + SPELL_REANIMATE_KALPHITE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_KALPHITE), + SPELL_REANIMATE_DAGANNOTH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DAGANNOTH), + SPELL_REANIMATE_BLOODVELD(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_BLOODVELD), + SPELL_REANIMATE_TZHAAR(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_TZHAAR), + SPELL_REANIMATE_DEMON(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DEMON), + SPELL_REANIMATE_AVIANSIE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_AVIANSIE), + SPELL_REANIMATE_ABYSSAL(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_ABYSSAL), + SPELL_REANIMATE_DRAGON(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.REANIMATE_DRAGON), + /* END OF ARCEUUS SPELL BOOK WIDGETS*/ + + MULTICOMBAT_RESIZEABLE(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewport.MULTICOMBAT_INDICATOR), + + FULLSCREEN_MAP_ROOT(WidgetID.FULLSCREEN_CONTAINER_TLI, WidgetID.FullScreenMap.ROOT), + + MUSICTAB_INTERFACE(WidgetID.MUSICTAB_GROUP_ID, 1), + MUSICTAB_SONG_BOX(WidgetID.MUSICTAB_GROUP_ID, 2), + MUSICTAB_ALL_SONGS(WidgetID.MUSICTAB_GROUP_ID, 3), + MUSICTAB_SCROLLBAR(WidgetID.MUSICTAB_GROUP_ID, 4), + MUSICTAB_PLAYING(WidgetID.MUSICTAB_GROUP_ID, 5), + MUSICTAB_CURRENT_SONG_NAME(WidgetID.MUSICTAB_GROUP_ID, 6), + MUSICTAB_AUTO_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 7), + MUSICTAB_AUTO_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 8), + MUSICTAB_MANUAL_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 9), + MUSICTAB_MANUAL_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 10), + MUSICTAB_LOOP_BUTTON_LISTENER(WidgetID.MUSICTAB_GROUP_ID, 11), + MUSICTAB_LOOP_BUTTON(WidgetID.MUSICTAB_GROUP_ID, 12), + MUSICTAB_UNLOCKED_SONGS(WidgetID.MUSICTAB_GROUP_ID, 13), + + QUESTTAB_QUEST_TAB(WidgetID.QUESTTAB_GROUP_ID, WidgetID.QuestTab.QUEST_TAB), + + EQUIPMENT_MELEE_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MELEE_STRENGTH), + EQUIPMENT_RANGED_STRENGTH(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.RANGED_STRENGTH), + EQUIPMENT_MAGIC_DAMAGE(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.MAGIC_DAMAGE), + EQUIP_YOUR_CHARACTER(WidgetID.EQUIPMENT_PAGE_GROUP_ID, WidgetID.EquipmentWidgetIdentifiers.EQUIP_YOUR_CHARACTER), + + BANK_PIN_TOP_LEFT_TEXT(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.TOP_LEFT_TEXT), + BANK_PIN_EXIT_BUTTON(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.EXIT_BUTTON), + BANK_PIN_FORGOT_BUTTON(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.FORGOT_BUTTON), + BANK_PIN_FIRST_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.FIRST_ENTERED), + BANK_PIN_SECOND_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.SECOND_ENTERED), + BANK_PIN_THIRD_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.THIRD_ENTERED), + BANK_PIN_FOURTH_ENTERED(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.FOURTH_ENTERED), + BANK_PIN_INSTRUCTION_TEXT(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.INSTRUCTION_TEXT), + BANK_PIN_1(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_1), + BANK_PIN_2(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_2), + BANK_PIN_3(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_3), + BANK_PIN_4(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_4), + BANK_PIN_5(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_5), + BANK_PIN_6(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_6), + BANK_PIN_7(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_7), + BANK_PIN_8(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_8), + BANK_PIN_9(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_9), + BANK_PIN_10(WidgetID.BANK_PIN_GROUP_ID, WidgetID.BankPin.BUTTON_10), + + XP_DROP_1(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_1), + XP_DROP_2(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_2), + XP_DROP_3(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_3), + XP_DROP_4(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_4), + XP_DROP_5(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_5), + XP_DROP_6(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_6), + XP_DROP_7(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_7), + + JEWELLERY_BOX_DUEL_RING(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.DUEL_RING), + JEWELLERY_BOX_GAME_NECK(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.GAME_NECK), + JEWELLERY_BOX_COMB_BRAC(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.COMB_BRAC), + JEWELLERY_BOX_SKIL_NECK(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.SKIL_NECK), + JEWELLERY_BOX_RING_OFGP(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.RING_OFGP), + JEWELLERY_BOX_AMUL_GLOR(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.AMUL_GLOR), + OPTIONS_CAMERA_ZOOM_SLIDER_HANDLE(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.CAMERA_ZOOM_SLIDER_HANDLE), + OPTIONS_MUSIC_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.MUSIC_SLIDER), + OPTIONS_SOUND_EFFECT_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.SOUND_EFFECT_SLIDER), + OPTIONS_AREA_SOUND_SLIDER(WidgetID.OPTIONS_GROUP_ID, WidgetID.Options.AREA_SOUND_SLIDER), + + TRADING_WITH(WidgetID.PLAYER_TRADE_SCREEN_GROUP_ID, WidgetID.TradeScreen.FIRST_TRADING_WITH), + SECOND_TRADING_WITH(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_TRADING_WITH), + SECOND_TRADING_WITH_ACCEPT_BUTTON(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_ACCEPT_FUNC), + SECOND_TRADING_WITH_ACCEPT_TEXT(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_ACCEPT_TEXT), + SECOND_TRADING_WITH_DECLINE_BUTTON(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_DECLINE_FUNC), + SECOND_TRADING_WITH_DECLINE_TEXT(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_DECLINE_TEXT), + SECOND_TRADING_WITH_MY_OFFER(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_MY_OFFER), + SECOND_TRADING_WITH_THEIR_OFFER(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_THEIR_OFFER), + SECOND_TRADING_WITH_MY_ITEMS(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_MY_ITEMS), + SECOND_TRADING_WITH_THEIR_ITEMS(WidgetID.PLAYER_TRADE_CONFIRM_GROUP_ID, WidgetID.TradeScreen.SECOND_THEIR_ITEMS), + + GAUNTLET_MAP(WidgetID.GAUNTLET_MAP_GROUP_ID, WidgetID.GauntletMap.CONTAINER), + + SHOP_ITEMS_CONTAINER(WidgetID.SHOP_GROUP_ID, WidgetID.Shop.ITEMS_CONTAINER), ; private final int groupId; diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index d3444285ec..644a1346d3 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -609,16 +609,6 @@ public abstract class RSClientMixin implements RSClient return getWidget(groupId, childId); } - @Inject - @Override - public Widget getWidget(com.openosrs.api.widgets.WidgetInfo widget) - { - int groupId = widget.getGroupId(); - int childId = widget.getChildId(); - - return getWidget(groupId, childId); - } - @Inject @Override public Widget getWidget(int id) From 426265c765eaf678f1f67787efe3feace978583f Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 25 Jan 2021 18:09:26 -0500 Subject: [PATCH 13/53] ground markers: add option to export and import Co-authored-by: Paul Norton --- .../groundmarkers/GroundMarkerPlugin.java | 17 +- .../GroundMarkerSharingManager.java | 243 ++++++++++++++++++ 2 files changed, 257 insertions(+), 3 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java index 73e93f86ad..c1e1774931 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java @@ -51,6 +51,7 @@ import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.plugins.Plugin; @@ -98,7 +99,13 @@ public class GroundMarkerPlugin extends Plugin @Inject private ChatboxPanelManager chatboxPanelManager; - private void savePoints(int regionId, Collection points) + @Inject + private EventBus eventBus; + + @Inject + private GroundMarkerSharingManager sharingManager; + + void savePoints(int regionId, Collection points) { if (points == null || points.isEmpty()) { @@ -110,7 +117,7 @@ public class GroundMarkerPlugin extends Plugin configManager.setConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId, json); } - private Collection getPoints(int regionId) + Collection getPoints(int regionId) { String json = configManager.getConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId); if (Strings.isNullOrEmpty(json)) @@ -129,7 +136,7 @@ public class GroundMarkerPlugin extends Plugin return configManager.getConfig(GroundMarkerConfig.class); } - private void loadPoints() + void loadPoints() { points.clear(); @@ -181,14 +188,18 @@ public class GroundMarkerPlugin extends Plugin { overlayManager.add(overlay); overlayManager.add(minimapOverlay); + sharingManager.addMenuOptions(); loadPoints(); + eventBus.register(sharingManager); } @Override public void shutDown() { + eventBus.unregister(sharingManager); overlayManager.remove(overlay); overlayManager.remove(minimapOverlay); + sharingManager.removeMenuOptions(); points.clear(); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java new file mode 100644 index 0000000000..8899a81f0d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2021, 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.groundmarkers; + +import com.google.common.base.Strings; +import com.google.common.util.concurrent.Runnables; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import javax.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.events.WidgetMenuOptionClicked; +import static net.runelite.api.widgets.WidgetInfo.WORLD_MAP_OPTION; +import net.runelite.client.chat.ChatMessageManager; +import net.runelite.client.chat.QueuedMessage; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.game.chatbox.ChatboxPanelManager; +import net.runelite.client.menus.MenuManager; +import net.runelite.client.menus.WidgetMenuOption; +import net.runelite.http.api.RuneLiteAPI; + +@Slf4j +class GroundMarkerSharingManager +{ + private static final WidgetMenuOption EXPORT_MARKERS_OPTION = new WidgetMenuOption("Export", "Ground Markers", WORLD_MAP_OPTION); + private static final WidgetMenuOption IMPORT_MARKERS_OPTION = new WidgetMenuOption("Import", "Ground Markers", WORLD_MAP_OPTION); + + private static final Gson GSON = RuneLiteAPI.GSON; + + private final GroundMarkerPlugin plugin; + private final Client client; + private final MenuManager menuManager; + private final ChatMessageManager chatMessageManager; + private final ChatboxPanelManager chatboxPanelManager; + + @Inject + private GroundMarkerSharingManager(GroundMarkerPlugin plugin, Client client, MenuManager menuManager, ChatMessageManager chatMessageManager, ChatboxPanelManager chatboxPanelManager) + { + this.plugin = plugin; + this.client = client; + this.menuManager = menuManager; + this.chatMessageManager = chatMessageManager; + this.chatboxPanelManager = chatboxPanelManager; + } + + void addMenuOptions() + { + menuManager.addManagedCustomMenu(EXPORT_MARKERS_OPTION); + menuManager.addManagedCustomMenu(IMPORT_MARKERS_OPTION); + } + + void removeMenuOptions() + { + menuManager.removeManagedCustomMenu(EXPORT_MARKERS_OPTION); + menuManager.removeManagedCustomMenu(IMPORT_MARKERS_OPTION); + } + + private boolean widgetMenuClickedEquals(final WidgetMenuOptionClicked event, final WidgetMenuOption target) + { + return event.getMenuTarget().equals(target.getMenuTarget()) && + event.getMenuOption().equals(target.getMenuOption()); + } + + @Subscribe + public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + { + // ensure that the option clicked is the export markers option + if (event.getWidget() != WORLD_MAP_OPTION) + { + return; + } + + if (widgetMenuClickedEquals(event, EXPORT_MARKERS_OPTION)) + { + exportGroundMarkers(); + } + else if (widgetMenuClickedEquals(event, IMPORT_MARKERS_OPTION)) + { + promptForImport(); + } + } + + private void exportGroundMarkers() + { + int[] regions = client.getMapRegions(); + if (regions == null) + { + return; + } + + List activePoints = Arrays.stream(regions) + .mapToObj(regionId -> plugin.getPoints(regionId).stream()) + .flatMap(Function.identity()) + .collect(Collectors.toList()); + + if (activePoints.isEmpty()) + { + sendChatMessage("You have no ground markers to export."); + return; + } + + final String exportDump = GSON.toJson(activePoints); + + log.debug("Exported ground markers: {}", exportDump); + + Toolkit.getDefaultToolkit() + .getSystemClipboard() + .setContents(new StringSelection(exportDump), null); + sendChatMessage(activePoints.size() + " ground markers were copied to your clipboard."); + } + + private void promptForImport() + { + final String clipboardText; + try + { + clipboardText = Toolkit.getDefaultToolkit() + .getSystemClipboard() + .getData(DataFlavor.stringFlavor) + .toString(); + } + catch (IOException | UnsupportedFlavorException ex) + { + sendChatMessage("Unable to read system clipboard."); + log.warn("error reading clipboard", ex); + return; + } + + log.debug("Clipboard contents: {}", clipboardText); + if (Strings.isNullOrEmpty(clipboardText)) + { + sendChatMessage("You do not have any ground markers copied in your clipboard."); + return; + } + + List importPoints; + try + { + // CHECKSTYLE:OFF + importPoints = GSON.fromJson(clipboardText, new TypeToken>(){}.getType()); + // CHECKSTYLE:ON + } + catch (JsonSyntaxException e) + { + log.debug("Malformed JSON for clipboard import", e); + sendChatMessage("You do not have any ground markers copied in your clipboard."); + return; + } + + if (importPoints.isEmpty()) + { + sendChatMessage("You do not have any ground markers copied in your clipboard."); + return; + } + + chatboxPanelManager.openTextMenuInput("Are you sure you want to import " + importPoints.size() + " ground markers?") + .option("Yes", () -> importGroundMarkers(importPoints)) + .option("No", Runnables::doNothing) + .build(); + } + + private void importGroundMarkers(Collection importPoints) + { + // regions being imported may not be loaded on client, + // so need to import each bunch directly into the config + // first, collate the list of unique region ids in the import + Map> regionGroupedPoints = importPoints.stream() + .collect(Collectors.groupingBy(GroundMarkerPoint::getRegionId)); + + // now import each region into the config + regionGroupedPoints.forEach((regionId, groupedPoints) -> + { + // combine imported points with existing region points + log.debug("Importing {} points to region {}", groupedPoints.size(), regionId); + Collection regionPoints = plugin.getPoints(regionId); + + List mergedList = new ArrayList<>(regionPoints.size() + groupedPoints.size()); + // add existing points + mergedList.addAll(regionPoints); + + // add new points + for (GroundMarkerPoint point : groupedPoints) + { + // filter out duplicates + if (!mergedList.contains(point)) + { + mergedList.add(point); + } + } + + plugin.savePoints(regionId, mergedList); + }); + + // reload points from config + log.debug("Reloading points after import"); + plugin.loadPoints(); + sendChatMessage(importPoints.size() + " ground markers were imported from the clipboard."); + } + + private void sendChatMessage(final String message) + { + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.CONSOLE) + .runeLiteFormattedMessage(message) + .build()); + } +} From f6c68eefc8a3c5415451bdbd6190b1f745ed5489 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 25 Jan 2021 19:27:15 -0500 Subject: [PATCH 14/53] api: remove PlayerMenuOptionClicked There is only one legitimate use of this, which is in the hiscore plugin, but it is simple to replace it with a normal menu option clicked event. Additionally the world hopper was incorrectly using this event for the Hop option, so it has been changed to use the menu option clicked event. --- .../api/events/PlayerMenuOptionClicked.java | 44 --------- .../runelite/client/menus/MenuManager.java | 27 +----- .../client/plugins/hiscore/HiscorePlugin.java | 28 +++++- .../worldhopper/WorldHopperPlugin.java | 10 +- .../client/menus/MenuManagerTest.java | 95 ------------------- 5 files changed, 32 insertions(+), 172 deletions(-) delete mode 100644 runelite-api/src/main/java/net/runelite/api/events/PlayerMenuOptionClicked.java delete mode 100644 runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java diff --git a/runelite-api/src/main/java/net/runelite/api/events/PlayerMenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/PlayerMenuOptionClicked.java deleted file mode 100644 index dcfb0421ca..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/events/PlayerMenuOptionClicked.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016-2017, 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.api.events; - -import lombok.Data; - -/** - * An event where a player menu option that was added by RuneLite has - * been clicked (ie. HiScore Lookup). - */ -@Data -public class PlayerMenuOptionClicked -{ - /** - * The menu option clicked. - */ - private String menuOption; - /** - * The target player. - */ - private String menuTarget; -} diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index 67129b0ba5..a597038628 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -34,25 +34,21 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import net.runelite.api.IconID; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; import net.runelite.api.NPCComposition; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.NpcActionChanged; -import net.runelite.api.events.PlayerMenuOptionClicked; import net.runelite.api.events.PlayerMenuOptionsChanged; import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; -import net.runelite.client.util.Text; @Singleton @Slf4j @@ -64,8 +60,6 @@ public class MenuManager private static final int IDX_LOWER = 4; private static final int IDX_UPPER = 8; - private static final Pattern BOUNTY_EMBLEM_TAG_AND_TIER_REGEXP = Pattern.compile(String.format("%s[1-9]0?", IconID.BOUNTY_HUNTER_EMBLEM.toString())); - private final Client client; private final EventBus eventBus; @@ -235,10 +229,9 @@ public class MenuManager @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getMenuAction() != MenuAction.RUNELITE - && event.getMenuAction() != MenuAction.RUNELITE_PLAYER) + if (event.getMenuAction() != MenuAction.RUNELITE) { - return; // not a managed widget option or custom player option + return; } int widgetId = event.getWidgetId(); @@ -254,23 +247,9 @@ public class MenuManager customMenu.setMenuTarget(event.getMenuTarget()); customMenu.setWidget(curMenuOption.getWidget()); eventBus.post(customMenu); - return; // don't continue because it's not a player option + return; } } - - // removes bounty hunter emblem tag and tier from player name, e.g: - // "username5 (level-42)" -> "username (level-42)" - String target = BOUNTY_EMBLEM_TAG_AND_TIER_REGEXP.matcher(event.getMenuTarget()).replaceAll(""); - - // removes tags and level from player names for example: - // username (level-42) or username - String username = Text.removeTags(target).split("[(]")[0].trim(); - - PlayerMenuOptionClicked playerMenuOptionClicked = new PlayerMenuOptionClicked(); - playerMenuOptionClicked.setMenuOption(event.getMenuOption()); - playerMenuOptionClicked.setMenuTarget(username); - - eventBus.post(playerMenuOptionClicked); } private void addPlayerMenuItem(int playerOptionIndex, String menuText) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java index edb450d61b..caf3020149 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePlugin.java @@ -38,9 +38,10 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; +import net.runelite.api.Player; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.PlayerMenuOptionClicked; +import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; @@ -174,11 +175,30 @@ public class HiscorePlugin extends Plugin } @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + public void onMenuOptionClicked(MenuOptionClicked event) { - if (event.getMenuOption().equals(LOOKUP)) + if ((event.getMenuAction() == MenuAction.RUNELITE || event.getMenuAction() == MenuAction.RUNELITE_PLAYER) + && event.getMenuOption().equals(LOOKUP)) { - lookupPlayer(Text.removeTags(event.getMenuTarget())); + final String target; + if (event.getMenuAction() == MenuAction.RUNELITE_PLAYER) + { + // The player id is included in the event, so we can use that to get the player name, + // which avoids having to parse out the combat level and any icons preceding the name. + Player player = client.getCachedPlayers()[event.getId()]; + if (player == null) + { + return; + } + + target = player.getName(); + } + else + { + target = Text.removeTags(event.getMenuTarget()); + } + + lookupPlayer(target); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index b10e2a0667..a283fe9d7f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -47,10 +47,10 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; import net.runelite.api.ChatPlayer; -import net.runelite.api.FriendsChatMember; -import net.runelite.api.FriendsChatManager; import net.runelite.api.Client; import net.runelite.api.Friend; +import net.runelite.api.FriendsChatManager; +import net.runelite.api.FriendsChatMember; import net.runelite.api.GameState; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; @@ -60,7 +60,7 @@ import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuEntryAdded; -import net.runelite.api.events.PlayerMenuOptionClicked; +import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WorldListLoad; import net.runelite.api.widgets.WidgetInfo; @@ -408,9 +408,9 @@ public class WorldHopperPlugin extends Plugin } @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) + public void onMenuOptionClicked(MenuOptionClicked event) { - if (!event.getMenuOption().equals(HOP_TO)) + if (event.getMenuAction() != MenuAction.RUNELITE || !event.getMenuOption().equals(HOP_TO)) { return; } diff --git a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java b/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java deleted file mode 100644 index 4c378d48ce..0000000000 --- a/runelite-client/src/test/java/net/runelite/client/menus/MenuManagerTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2020, bfmoatbio - * Copyright (c) 2020, Jordan Atwood - * 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.menus; - -import com.google.inject.Guice; -import com.google.inject.Inject; -import com.google.inject.testing.fieldbinder.Bind; -import com.google.inject.testing.fieldbinder.BoundFieldModule; -import net.runelite.api.Client; -import net.runelite.api.MenuAction; -import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.PlayerMenuOptionClicked; -import net.runelite.client.eventbus.EventBus; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import static org.mockito.Mockito.verify; -import org.mockito.junit.MockitoJUnitRunner; -import static org.junit.Assert.assertEquals; - -@RunWith(MockitoJUnitRunner.class) -public class MenuManagerTest -{ - @Inject - private MenuManager menuManager; - - @Mock - @Bind - private Client client; - - @Mock - @Bind - private EventBus eventBus; - - @Before - public void before() - { - Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); - } - - @Test - public void testPlayerMenuOptionClicked() - { - MenuOptionClicked event = new MenuOptionClicked(); - event.setMenuAction(MenuAction.RUNELITE_PLAYER); - event.setMenuTarget("username (level-42)"); - - menuManager.onMenuOptionClicked(event); - - ArgumentCaptor captor = ArgumentCaptor.forClass(PlayerMenuOptionClicked.class); - verify(eventBus).post(captor.capture()); - PlayerMenuOptionClicked clicked = captor.getValue(); - assertEquals("username", clicked.getMenuTarget()); - } - - @Test - public void testPlayerMenuOptionWithBountyHunterEmblemClicked() - { - MenuOptionClicked event = new MenuOptionClicked(); - event.setMenuAction(MenuAction.RUNELITE_PLAYER); - event.setMenuTarget("username5 (level-42)"); - - menuManager.onMenuOptionClicked(event); - - ArgumentCaptor captor = ArgumentCaptor.forClass(PlayerMenuOptionClicked.class); - verify(eventBus).post(captor.capture()); - PlayerMenuOptionClicked clicked = captor.getValue(); - assertEquals("username", clicked.getMenuTarget()); - } -} From 48fdf79e65fc0bb6f7ca606e0ac09952c4eec3b9 Mon Sep 17 00:00:00 2001 From: zeruth Date: Mon, 25 Jan 2021 20:42:16 -0500 Subject: [PATCH 15/53] client: enable external updating --- runelite-client/src/main/java/net/runelite/client/RuneLite.java | 2 +- .../src/main/java/net/runelite/client/config/ConfigSection.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 6630da1ad3..9d728a6865 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -333,7 +333,7 @@ public class RuneLite oprsExternalPluginManager.startExternalPluginManager(); // Update external plugins - //oprsExternalPluginManager.update(); //TODO: Re-enable after fixing actions for new repo + oprsExternalPluginManager.update(); //TODO: Re-enable after fixing actions for new repo // Load the plugins, but does not start them yet. // This will initialize configuration diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java index 0765779b48..282855920a 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigSection.java @@ -24,8 +24,6 @@ */ package net.runelite.client.config; -import com.openosrs.client.OpenOSRS; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; From d68d66b01d6c29f16f8fd50b1a1f022a7066f496 Mon Sep 17 00:00:00 2001 From: loldudester Date: Mon, 25 Jan 2021 19:49:18 -0800 Subject: [PATCH 16/53] Fix javadoc cutting off descriptions Co-authored-by: Jordan Atwood --- .../java/net/runelite/api/ChatMessageType.java | 2 +- .../src/main/java/net/runelite/api/Client.java | 14 +++++++------- .../src/main/java/net/runelite/api/HeadIcon.java | 2 +- .../src/main/java/net/runelite/api/MenuEntry.java | 4 ++-- .../main/java/net/runelite/api/MessageNode.java | 2 +- .../src/main/java/net/runelite/api/Projectile.java | 2 +- .../net/runelite/api/events/MenuEntryAdded.java | 4 ++-- .../java/net/runelite/api/events/WorldChanged.java | 2 +- .../net/runelite/client/game/AgilityShortcut.java | 2 +- .../runelite/client/menus/WidgetMenuOption.java | 4 ++-- .../plugins/discord/DiscordGameEventType.java | 2 +- .../client/plugins/itemstats/stats/Stat.java | 2 +- .../runelite/client/plugins/xptracker/XpState.java | 4 ++-- .../runelite/client/util/QuantityFormatter.java | 2 +- 14 files changed, 24 insertions(+), 24 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java b/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java index f96d7fba63..d453bfbb35 100644 --- a/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java +++ b/runelite-api/src/main/java/net/runelite/api/ChatMessageType.java @@ -117,7 +117,7 @@ public enum ChatMessageType */ MODAUTOTYPER(91), /** - * A game message (ie. when a setting is changed). + * A game message. (ie. when a setting is changed) */ CONSOLE(99), /** diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 0dcad51c06..c08be0edbe 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -433,7 +433,7 @@ public interface Client extends GameEngine int getMouseCurrentButton(); /** - * Gets the currently selected tile (ie. last right clicked tile). + * Gets the currently selected tile. (ie. last right clicked tile) * * @return the selected tile */ @@ -1465,8 +1465,8 @@ public interface Client extends GameEngine void setPlayersHidden(boolean state); /** - * Sets whether 2D sprites (ie. overhead prayers, PK skull) related to - * the other players are hidden. + * Sets whether 2D sprites related to the other players are hidden. + * (ie. overhead prayers, PK skull) * * @param state the new player 2D hidden state */ @@ -1494,8 +1494,8 @@ public interface Client extends GameEngine void setLocalPlayerHidden(boolean state); /** - * Sets whether 2D sprites (ie. overhead prayers, PK skull) related to - * the local player are hidden. + * Sets whether 2D sprites related to the local player are hidden. + * (ie. overhead prayers, PK skull) * * @param state new local player 2D hidden state */ @@ -1509,8 +1509,8 @@ public interface Client extends GameEngine void setNPCsHidden(boolean state); /** - * Sets whether 2D sprites (ie. overhead prayers) related to - * the NPCs are hidden. + * Sets whether 2D sprites related to the NPCs are hidden. + * (ie. overhead prayers) * * @param state new NPC 2D hidden state */ diff --git a/runelite-api/src/main/java/net/runelite/api/HeadIcon.java b/runelite-api/src/main/java/net/runelite/api/HeadIcon.java index 6f70220ba9..ad8f00cc08 100644 --- a/runelite-api/src/main/java/net/runelite/api/HeadIcon.java +++ b/runelite-api/src/main/java/net/runelite/api/HeadIcon.java @@ -54,7 +54,7 @@ public enum HeadIcon */ REDEMPTION, /** - * Protect from range and mage (ie. used by Kalphite Queen). + * Protect from range and mage. (ie. used by Kalphite Queen) */ RANGE_MAGE } diff --git a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java index 6d9cc751f4..e28165e603 100644 --- a/runelite-api/src/main/java/net/runelite/api/MenuEntry.java +++ b/runelite-api/src/main/java/net/runelite/api/MenuEntry.java @@ -33,11 +33,11 @@ import lombok.Data; public class MenuEntry { /** - * The option text added to the menu (ie. "Walk here", "Use"). + * The option text added to the menu. (ie. "Walk here", "Use") */ private String option; /** - * The target of the action (ie. Item or Actor name). + * The target of the action. (ie. Item or Actor name) *

* If the option does not apply to any target, this field * will be set to empty string. diff --git a/runelite-api/src/main/java/net/runelite/api/MessageNode.java b/runelite-api/src/main/java/net/runelite/api/MessageNode.java index 9b7325a3e0..e1f96bf4aa 100644 --- a/runelite-api/src/main/java/net/runelite/api/MessageNode.java +++ b/runelite-api/src/main/java/net/runelite/api/MessageNode.java @@ -58,7 +58,7 @@ public interface MessageNode extends Node void setName(String name); /** - * Gets the sender of the message (ie. friends chat name). + * Gets the sender of the message. (ie. friends chat name) * * @return the message sender */ diff --git a/runelite-api/src/main/java/net/runelite/api/Projectile.java b/runelite-api/src/main/java/net/runelite/api/Projectile.java index 323a7a43ed..2f371611d3 100644 --- a/runelite-api/src/main/java/net/runelite/api/Projectile.java +++ b/runelite-api/src/main/java/net/runelite/api/Projectile.java @@ -25,7 +25,7 @@ package net.runelite.api; /** - * Represents a projectile entity (ie. cannonball, arrow). + * Represents a projectile entity. (ie. cannonball, arrow) */ public interface Projectile extends Renderable { diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java index e6aa08b600..0771e8189c 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuEntryAdded.java @@ -35,11 +35,11 @@ import lombok.Data; public class MenuEntryAdded { /** - * The option text added to the menu (ie. "Walk here", "Use"). + * The option text added to the menu. (ie. "Walk here", "Use") */ private final String option; /** - * The target of the action (ie. Item or Actor name). + * The target of the action. (ie. Item or Actor name) *

* If the option does not apply to any target, this field * will be set to empty string. diff --git a/runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java b/runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java index 57fcb00ee6..408114af1e 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java +++ b/runelite-api/src/main/java/net/runelite/api/events/WorldChanged.java @@ -27,7 +27,7 @@ package net.runelite.api.events; import net.runelite.api.Client; /** - * Posted when the game world the client wants to connect to has changed + * Posted when the game world the client wants to connect to has changed. * This is posted after the world ID and type have updated, but before a new * connection is established * diff --git a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java index 20b99655fb..5833b05a37 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java +++ b/runelite-client/src/main/java/net/runelite/client/game/AgilityShortcut.java @@ -237,7 +237,7 @@ public enum AgilityShortcut @Getter private final int level; /** - * Brief description of the shortcut (e.g. 'Rocks', 'Stepping Stones', 'Jump') + * Brief description of the shortcut. (e.g. 'Rocks', 'Stepping Stones', 'Jump') */ @Getter private final String description; diff --git a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java index 307551542c..d24ae1d18d 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/WidgetMenuOption.java @@ -33,11 +33,11 @@ import net.runelite.client.util.ColorUtil; public final class WidgetMenuOption { /** - * The left hand text to be displayed on the menu option. Ex. the menuOption of "Drop Bones" is "Drop" + * The left hand text to be displayed on the menu option. (ex. the menuOption of "Drop Bones" is "Drop") */ private String menuOption; /** - * The right hand text to be displayed on the menu option Ex. the menuTarget of "Drop Bones" is "Bones" + * The right hand text to be displayed on the menu option. (ex. the menuTarget of "Drop Bones" is "Bones") */ private String menuTarget; /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java index 17b72b5d6e..7e07a12ee4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordGameEventType.java @@ -470,7 +470,7 @@ enum DiscordGameEventType private int priority; /** - * Marks this event as root event, e.g event that should be used for total time tracking + * Marks this event as root event. (eg. event that should be used for total time tracking) */ private boolean root; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/stats/Stat.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/stats/Stat.java index be7b2ff4d8..2d65a7993c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/stats/Stat.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/stats/Stat.java @@ -52,7 +52,7 @@ public abstract class Stat public abstract int getValue(Client client); /** - * Get the base stat maximum, ie. the bottom half of the stat fraction. + * Get the base stat maximum. (ie. the bottom half of the stat fraction) */ public abstract int getMaximum(Client client); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java index fac3c16410..1fbbdb2c49 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpState.java @@ -159,8 +159,8 @@ class XpState } /** - * Update number of actions performed for skill (e.g amount of kills in this case) if last interacted - * NPC died + * Update number of actions performed for skill if last interacted NPC died. + * (eg. amount of kills in this case) * @param skill skill to update actions for * @param npc npc that just died * @param npcHealth max health of npc that just died diff --git a/runelite-client/src/main/java/net/runelite/client/util/QuantityFormatter.java b/runelite-client/src/main/java/net/runelite/client/util/QuantityFormatter.java index 49823b5cca..2b838e409c 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/QuantityFormatter.java +++ b/runelite-client/src/main/java/net/runelite/client/util/QuantityFormatter.java @@ -182,7 +182,7 @@ public class QuantityFormatter } /** - * Calculates, given a string with a value denominator (ex. 20K) + * Calculates, given a string with a value denominator (for example, 20K) * the multiplier that the denominator represents (in this case 1000). * * @param string The string to check. From 8aee2fb0c21f592054ba5266fd0cae7b1adcddbb Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Tue, 26 Jan 2021 16:53:31 -0700 Subject: [PATCH 17/53] Update Item IDs to 2021-1-27 --- .../main/java/net/runelite/api/ItemID.java | 57 ++++++++++++++++++- .../java/net/runelite/api/NullItemID.java | 56 ++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/ItemID.java b/runelite-api/src/main/java/net/runelite/api/ItemID.java index 66ef6c0323..df6d719ce9 100644 --- a/runelite-api/src/main/java/net/runelite/api/ItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/ItemID.java @@ -11656,8 +11656,6 @@ public final class ItemID public static final int GIANT_BOULDER = 25314; public static final int GOBLIN_DECORATIONS = 25316; public static final int GNOME_CHILD_ICON = 25319; - public static final int GNOME_CHILD = 25320; - public static final int GNOME_CHILD_25321 = 25321; public static final int _20TH_ANNIVERSARY_HAT = 25322; public static final int _20TH_ANNIVERSARY_TOP = 25324; public static final int _20TH_ANNIVERSARY_BOTTOM = 25326; @@ -11698,5 +11696,60 @@ public final class ItemID public static final int TRAILBLAZER_RELIC_HUNTER_T1_ARMOUR_SET = 25380; public static final int TRAILBLAZER_RELIC_HUNTER_T2_ARMOUR_SET = 25383; public static final int TRAILBLAZER_RELIC_HUNTER_T3_ARMOUR_SET = 25386; + public static final int SWAMPBARK_BODY = 25389; + public static final int SWAMPBARK_GAUNTLETS = 25392; + public static final int SWAMPBARK_BOOTS = 25395; + public static final int SWAMPBARK_HELM = 25398; + public static final int SWAMPBARK_LEGS = 25401; + public static final int BLOODBARK_BODY = 25404; + public static final int BLOODBARK_GAUNTLETS = 25407; + public static final int BLOODBARK_BOOTS = 25410; + public static final int BLOODBARK_HELM = 25413; + public static final int BLOODBARK_LEGS = 25416; + public static final int URIUM_REMAINS = 25419; + public static final int BLEACHED_BONES = 25422; + public static final int GOLD_KEY_RED = 25424; + public static final int GOLD_KEY_BROWN = 25426; + public static final int GOLD_KEY_CRIMSON = 25428; + public static final int GOLD_KEY_BLACK = 25430; + public static final int GOLD_KEY_PURPLE = 25432; + public static final int ZEALOTS_ROBE_TOP = 25434; + public static final int ZEALOTS_ROBE_BOTTOM = 25436; + public static final int ZEALOTS_HELM = 25438; + public static final int ZEALOTS_BOOTS = 25440; + public static final int BRONZE_LOCKS = 25442; + public static final int STEEL_LOCKS = 25445; + public static final int BLACK_LOCKS = 25448; + public static final int SILVER_LOCKS = 25451; + public static final int GOLD_LOCKS = 25454; + public static final int BROKEN_COFFIN = 25457; + public static final int BRONZE_COFFIN = 25459; + public static final int STEEL_COFFIN = 25461; + public static final int BLACK_COFFIN = 25463; + public static final int SILVER_COFFIN = 25465; + public static final int GOLD_COFFIN = 25467; + public static final int OPEN_BRONZE_COFFIN = 25469; + public static final int OPEN_STEEL_COFFIN = 25470; + public static final int OPEN_BLACK_COFFIN = 25471; + public static final int OPEN_SILVER_COFFIN = 25472; + public static final int OPEN_GOLD_COFFIN = 25473; + public static final int TREE_WIZARDS_JOURNAL = 25474; + public static final int BLOODY_NOTES = 25476; + public static final int RUNESCROLL_OF_SWAMPBARK = 25478; + public static final int RUNESCROLL_OF_BLOODBARK = 25481; + public static final int TOXIC_BLOWPIPE_BETA__BRONZE = 25484; + public static final int TOXIC_BLOWPIPE_BETA__IRON = 25485; + public static final int TOXIC_BLOWPIPE_BETA__STEEL = 25486; + public static final int TOXIC_BLOWPIPE_BETA__BLACK = 25487; + public static final int TOXIC_BLOWPIPE_BETA__MITHRIL = 25488; + public static final int TOXIC_BLOWPIPE_BETA__ADAMANT = 25489; + public static final int TOXIC_BLOWPIPE_BETA__RUNE = 25490; + public static final int TOXIC_BLOWPIPE_BETA__DRAGON = 25491; + public static final int BLACK_DHIDE_BODY_BETA = 25492; + public static final int BLACK_DHIDE_CHAPS_BETA = 25493; + public static final int BLACK_DHIDE_VAMBRACES_BETA = 25494; + public static final int CRYSTAL_HELM_BETA = 25495; + public static final int CRYSTAL_BODY_BETA = 25496; + public static final int CRYSTAL_LEGS_BETA = 25497; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullItemID.java b/runelite-api/src/main/java/net/runelite/api/NullItemID.java index c6fa2aadf0..a0bc89a2aa 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullItemID.java @@ -13453,6 +13453,8 @@ public final class NullItemID public static final int NULL_25315 = 25315; public static final int NULL_25317 = 25317; public static final int NULL_25318 = 25318; + public static final int NULL_25320 = 25320; + public static final int NULL_25321 = 25321; public static final int NULL_25323 = 25323; public static final int NULL_25325 = 25325; public static final int NULL_25327 = 25327; @@ -13480,5 +13482,59 @@ public final class NullItemID public static final int NULL_25385 = 25385; public static final int NULL_25387 = 25387; public static final int NULL_25388 = 25388; + public static final int NULL_25390 = 25390; + public static final int NULL_25391 = 25391; + public static final int NULL_25393 = 25393; + public static final int NULL_25394 = 25394; + public static final int NULL_25396 = 25396; + public static final int NULL_25397 = 25397; + public static final int NULL_25399 = 25399; + public static final int NULL_25400 = 25400; + public static final int NULL_25402 = 25402; + public static final int NULL_25403 = 25403; + public static final int NULL_25405 = 25405; + public static final int NULL_25406 = 25406; + public static final int NULL_25408 = 25408; + public static final int NULL_25409 = 25409; + public static final int NULL_25411 = 25411; + public static final int NULL_25412 = 25412; + public static final int NULL_25414 = 25414; + public static final int NULL_25415 = 25415; + public static final int NULL_25417 = 25417; + public static final int NULL_25418 = 25418; + public static final int NULL_25420 = 25420; + public static final int NULL_25421 = 25421; + public static final int NULL_25423 = 25423; + public static final int NULL_25425 = 25425; + public static final int NULL_25427 = 25427; + public static final int NULL_25429 = 25429; + public static final int NULL_25431 = 25431; + public static final int NULL_25433 = 25433; + public static final int NULL_25435 = 25435; + public static final int NULL_25437 = 25437; + public static final int NULL_25439 = 25439; + public static final int NULL_25441 = 25441; + public static final int NULL_25443 = 25443; + public static final int NULL_25444 = 25444; + public static final int NULL_25446 = 25446; + public static final int NULL_25447 = 25447; + public static final int NULL_25449 = 25449; + public static final int NULL_25450 = 25450; + public static final int NULL_25452 = 25452; + public static final int NULL_25453 = 25453; + public static final int NULL_25455 = 25455; + public static final int NULL_25456 = 25456; + public static final int NULL_25458 = 25458; + public static final int NULL_25460 = 25460; + public static final int NULL_25462 = 25462; + public static final int NULL_25464 = 25464; + public static final int NULL_25466 = 25466; + public static final int NULL_25468 = 25468; + public static final int NULL_25475 = 25475; + public static final int NULL_25477 = 25477; + public static final int NULL_25479 = 25479; + public static final int NULL_25480 = 25480; + public static final int NULL_25482 = 25482; + public static final int NULL_25483 = 25483; /* This file is automatically generated. Do not edit. */ } From 805158a6449bcd42a9300959d3c97cc78e65d9e3 Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Tue, 26 Jan 2021 16:53:31 -0700 Subject: [PATCH 18/53] Update Item variations to 2021-1-27 --- .../src/main/resources/item_variations.json | 53 +++++++++++++++---- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json index 62877d1869..9543697a90 100644 --- a/runelite-client/src/main/resources/item_variations.json +++ b/runelite-client/src/main/resources/item_variations.json @@ -2727,6 +2727,10 @@ 2464, 8936 ], + "black dhide vambraces": [ + 2491, + 25494 + ], "blue dhide chaps": [ 2493, 7382, @@ -2743,7 +2747,8 @@ 2497, 12383, 12387, - 20424 + 20424, + 25493 ], "blue dhide body": [ 2499, @@ -2761,7 +2766,8 @@ 2503, 12381, 12385, - 20423 + 20423, + 25492 ], "dragon chainbody": [ 2513, @@ -7760,7 +7766,15 @@ ], "toxic blowpipe": [ 12924, - 12926 + 12926, + 25484, + 25485, + 25486, + 25487, + 25488, + 25489, + 25490, + 25491 ], "serpentine helm": [ 12929, @@ -9240,21 +9254,24 @@ 23887, 23888, 23971, - 23973 + 23973, + 25495 ], "crystal body": [ 23889, 23890, 23891, 23975, - 23977 + 23977, + 25496 ], "crystal legs": [ 23892, 23893, 23894, 23979, - 23981 + 23981, + 25497 ], "crystal staff": [ 23898, @@ -9623,10 +9640,6 @@ 25319, 25338 ], - "gnome child": [ - 25320, - 25321 - ], "soul cape": [ 25344, 25346 @@ -9635,5 +9648,25 @@ 25380, 25383, 25386 + ], + "bronze coffin": [ + 25459, + 25469 + ], + "steel coffin": [ + 25461, + 25470 + ], + "black coffin": [ + 25463, + 25471 + ], + "silver coffin": [ + 25465, + 25472 + ], + "gold coffin": [ + 25467, + 25473 ] } \ No newline at end of file From 93a4a4c37998312970afaf022e8dec2f5487f4af Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Tue, 26 Jan 2021 16:53:31 -0700 Subject: [PATCH 19/53] Update Object IDs to 2021-1-27 --- .../java/net/runelite/api/NullObjectID.java | 91 +++---------------- .../main/java/net/runelite/api/ObjectID.java | 35 ++++--- 2 files changed, 27 insertions(+), 99 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java index 950d22e579..91bb2fdc18 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java @@ -879,7 +879,6 @@ public final class NullObjectID public static final int NULL_1793 = 1793; public static final int NULL_1794 = 1794; public static final int NULL_1795 = 1795; - public static final int NULL_1796 = 1796; public static final int NULL_1798 = 1798; public static final int NULL_1799 = 1799; public static final int NULL_1800 = 1800; @@ -890,7 +889,6 @@ public final class NullObjectID public static final int NULL_1807 = 1807; public static final int NULL_1808 = 1808; public static final int NULL_1809 = 1809; - public static final int NULL_1812 = 1812; public static final int NULL_1815 = 1815; public static final int NULL_1818 = 1818; public static final int NULL_1819 = 1819; @@ -19747,6 +19745,7 @@ public final class NullObjectID public static final int NULL_40427 = 40427; public static final int NULL_40428 = 40428; public static final int NULL_40429 = 40429; + public static final int NULL_40470 = 40470; public static final int NULL_40477 = 40477; public static final int NULL_40478 = 40478; public static final int NULL_40479 = 40479; @@ -20009,84 +20008,6 @@ public final class NullObjectID public static final int NULL_40934 = 40934; public static final int NULL_40935 = 40935; public static final int NULL_40936 = 40936; - public static final int NULL_40942 = 40942; - public static final int NULL_40943 = 40943; - public static final int NULL_40944 = 40944; - public static final int NULL_40945 = 40945; - public static final int NULL_40946 = 40946; - public static final int NULL_40947 = 40947; - public static final int NULL_40948 = 40948; - public static final int NULL_40949 = 40949; - public static final int NULL_40950 = 40950; - public static final int NULL_40951 = 40951; - public static final int NULL_40952 = 40952; - public static final int NULL_40953 = 40953; - public static final int NULL_40954 = 40954; - public static final int NULL_40955 = 40955; - public static final int NULL_40956 = 40956; - public static final int NULL_40957 = 40957; - public static final int NULL_40958 = 40958; - public static final int NULL_40959 = 40959; - public static final int NULL_40960 = 40960; - public static final int NULL_40961 = 40961; - public static final int NULL_40962 = 40962; - public static final int NULL_40963 = 40963; - public static final int NULL_40964 = 40964; - public static final int NULL_40965 = 40965; - public static final int NULL_40966 = 40966; - public static final int NULL_40967 = 40967; - public static final int NULL_40968 = 40968; - public static final int NULL_40969 = 40969; - public static final int NULL_40970 = 40970; - public static final int NULL_40971 = 40971; - public static final int NULL_40972 = 40972; - public static final int NULL_40973 = 40973; - public static final int NULL_40974 = 40974; - public static final int NULL_40975 = 40975; - public static final int NULL_40976 = 40976; - public static final int NULL_40977 = 40977; - public static final int NULL_40978 = 40978; - public static final int NULL_40979 = 40979; - public static final int NULL_40980 = 40980; - public static final int NULL_40981 = 40981; - public static final int NULL_40982 = 40982; - public static final int NULL_40983 = 40983; - public static final int NULL_40984 = 40984; - public static final int NULL_40985 = 40985; - public static final int NULL_40987 = 40987; - public static final int NULL_40988 = 40988; - public static final int NULL_40989 = 40989; - public static final int NULL_40990 = 40990; - public static final int NULL_40991 = 40991; - public static final int NULL_40992 = 40992; - public static final int NULL_40993 = 40993; - public static final int NULL_40994 = 40994; - public static final int NULL_40995 = 40995; - public static final int NULL_40996 = 40996; - public static final int NULL_40997 = 40997; - public static final int NULL_40998 = 40998; - public static final int NULL_40999 = 40999; - public static final int NULL_41000 = 41000; - public static final int NULL_41001 = 41001; - public static final int NULL_41002 = 41002; - public static final int NULL_41003 = 41003; - public static final int NULL_41004 = 41004; - public static final int NULL_41005 = 41005; - public static final int NULL_41006 = 41006; - public static final int NULL_41007 = 41007; - public static final int NULL_41008 = 41008; - public static final int NULL_41009 = 41009; - public static final int NULL_41010 = 41010; - public static final int NULL_41011 = 41011; - public static final int NULL_41012 = 41012; - public static final int NULL_41013 = 41013; - public static final int NULL_41014 = 41014; - public static final int NULL_41015 = 41015; - public static final int NULL_41016 = 41016; - public static final int NULL_41018 = 41018; - public static final int NULL_41019 = 41019; - public static final int NULL_41020 = 41020; - public static final int NULL_41021 = 41021; public static final int NULL_41022 = 41022; public static final int NULL_41191 = 41191; public static final int NULL_41192 = 41192; @@ -20096,5 +20017,15 @@ public final class NullObjectID public static final int NULL_41196 = 41196; public static final int NULL_41197 = 41197; public static final int NULL_41198 = 41198; + public static final int NULL_41201 = 41201; + public static final int NULL_41202 = 41202; + public static final int NULL_41203 = 41203; + public static final int NULL_41204 = 41204; + public static final int NULL_41205 = 41205; + public static final int NULL_41206 = 41206; + public static final int NULL_41207 = 41207; + public static final int NULL_41208 = 41208; + public static final int NULL_41209 = 41209; + public static final int NULL_41211 = 41211; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/ObjectID.java b/runelite-api/src/main/java/net/runelite/api/ObjectID.java index 153313b119..8bf9ca4de0 100644 --- a/runelite-api/src/main/java/net/runelite/api/ObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/ObjectID.java @@ -18582,7 +18582,7 @@ public final class ObjectID public static final int RUBBLE_34803 = 34803; public static final int RUBBLE_34804 = 34804; public static final int RUBBLE_34805 = 34805; - public static final int JADFEST_PORTAL = 34826; + public static final int HANDY_PORTAL = 34826; public static final int LARRANS_SMALL_CHEST_34828 = 34828; public static final int LARRANS_BIG_CHEST = 34829; public static final int LARRANS_BIG_CHEST_34830 = 34830; @@ -19619,7 +19619,7 @@ public final class ObjectID public static final int GATE_37954 = 37954; public static final int LADDER_37955 = 37955; public static final int LADDER_37956 = 37956; - public static final int HANDY_PORTAL = 37957; + public static final int HANDY_PORTAL_37957 = 37957; public static final int BANK_BOOTH_37959 = 37959; public static final int DOOR_37961 = 37961; public static final int DOOR_37963 = 37963; @@ -20709,6 +20709,8 @@ public final class ObjectID public static final int EXPLOSIVE_POTION_TABLE_40467 = 40467; public static final int POTION_OF_POWER_TABLE_40468 = 40468; public static final int POTION_OF_POWER_TABLE_40469 = 40469; + public static final int GRAVESTONE_40471 = 40471; + public static final int COFFIN_40472 = 40472; public static final int BANK_CHEST_40473 = 40473; public static final int SOUL_WARS_PORTAL = 40474; public static final int SOUL_WARS_PORTAL_40475 = 40475; @@ -20899,25 +20901,8 @@ public final class ObjectID public static final int STATUE_40915 = 40915; public static final int STATUE_40916 = 40916; public static final int STATUE_40917 = 40917; - public static final int INERT_PORTAL = 40918; - public static final int PORTAL_40919 = 40919; - public static final int ODD_FEATHERS = 40920; - public static final int PORTAL_40921 = 40921; - public static final int BARRIER_40922 = 40922; - public static final int SLEEPING_BAG_40923 = 40923; - public static final int STATUE_40924 = 40924; - public static final int ARCHWAY_40929 = 40929; - public static final int LIGHT_40930 = 40930; - public static final int LIGHT_40931 = 40931; public static final int EVERGREEN_40932 = 40932; public static final int EVERGREEN_40933 = 40933; - public static final int LIGHT_40937 = 40937; - public static final int LIGHT_40938 = 40938; - public static final int LIGHT_40939 = 40939; - public static final int LIGHT_40940 = 40940; - public static final int FIREWORKS = 40941; - public static final int POST_40986 = 40986; - public static final int PARTY_TABLE = 41017; public static final int POTION_OF_POWER_TABLE_41023 = 41023; public static final int PEDESTAL_SPACE = 41024; public static final int PEDESTAL_SPACE_41025 = 41025; @@ -21088,5 +21073,17 @@ public final class ObjectID public static final int ANCIENT_BRAZIER_41190 = 41190; public static final int BARRIER_41199 = 41199; public static final int BARRIER_41200 = 41200; + public static final int SOLID_GOLD_DOOR = 41210; + public static final int GOLD_CHEST = 41212; + public static final int GOLD_CHEST_41213 = 41213; + public static final int GOLD_CHEST_41214 = 41214; + public static final int GOLD_CHEST_41215 = 41215; + public static final int GOLD_CHEST_41216 = 41216; + public static final int GOLD_CHEST_41217 = 41217; + public static final int GOLD_CHEST_41218 = 41218; + public static final int GOLD_CHEST_41219 = 41219; + public static final int GOLD_CHEST_41220 = 41220; + public static final int GOLD_CHEST_41221 = 41221; + public static final int ALTAR_41222 = 41222; /* This file is automatically generated. Do not edit. */ } From 3c9674f63ee493465554a43622e4d5717c4f49d2 Mon Sep 17 00:00:00 2001 From: RuneLite Cache-Code Autoupdater Date: Tue, 26 Jan 2021 16:53:31 -0700 Subject: [PATCH 20/53] Update NPC IDs to 2021-1-27 --- .../src/main/java/net/runelite/api/NpcID.java | 33 ++++--------------- .../main/java/net/runelite/api/NullNpcID.java | 1 - 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/NpcID.java b/runelite-api/src/main/java/net/runelite/api/NpcID.java index 15460768d9..f6bef67796 100644 --- a/runelite-api/src/main/java/net/runelite/api/NpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NpcID.java @@ -2657,6 +2657,7 @@ public final class NpcID public static final int DRYAD = 2828; public static final int FAIRY_2829 = 2829; public static final int MYSTERIOUS_OLD_MAN = 2830; + public static final int CHAIR = 2832; public static final int LIL_CREATOR = 2833; public static final int GIANT_BAT = 2834; public static final int CAMEL = 2835; @@ -5716,6 +5717,7 @@ public final class NpcID public static final int THE_INADEQUACY_HARD = 6119; public static final int THE_EVERLASTING_HARD = 6120; public static final int THE_UNTOUCHABLE_HARD = 6121; + public static final int URIUM_SHADOW = 6143; public static final int SCION_6177 = 6177; public static final int JUNGLE_SPIDER_6267 = 6267; public static final int JUNGLE_SPIDER_6271 = 6271; @@ -8920,37 +8922,14 @@ public final class NpcID public static final int DUCK_10546 = 10546; public static final int DUCK_10547 = 10547; public static final int CHICKEN_10556 = 10556; - public static final int GNOME_CHILD_10557 = 10557; - public static final int GNOME_CHILD_10558 = 10558; public static final int SCRUBFOOT = 10559; - public static final int GNOME_CHILD_10560 = 10560; public static final int RED_FIREFLIES = 10561; - public static final int GNOME_CHILD_10562 = 10562; - public static final int THRANDER = 10563; public static final int GREEN_FIREFLIES = 10564; - public static final int CHUCK_10565 = 10565; public static final int GOBLIN_10566 = 10566; public static final int GOBLIN_10567 = 10567; - public static final int PIOUS_PETE = 10568; - public static final int MYSTERIOUS_WATCHER = 10569; - public static final int MYSTERIOUS_WATCHER_10570 = 10570; - public static final int MYSTERIOUS_WATCHER_10571 = 10571; - public static final int BIG_MO = 10572; - public static final int CHEERLEADER_10573 = 10573; - public static final int CHEERLEADER_10574 = 10574; - public static final int CHEERLEADER_10575 = 10575; - public static final int BLACK_DRAGON_10576 = 10576; - public static final int RED_DRAGON_10577 = 10577; - public static final int BLUE_DRAGON_10578 = 10578; - public static final int KING_BLACK_DRAGON_10579 = 10579; - public static final int BABY_BLUE_DRAGON_10580 = 10580; - public static final int LESSER_DEMON_10581 = 10581; - public static final int GREATER_DEMON_10582 = 10582; - public static final int BLACK_DEMON_10583 = 10583; - public static final int SCORPION_10584 = 10584; - public static final int KING_SCORPION_10585 = 10585; - public static final int ORC = 10586; - public static final int LIZARD_MAN = 10587; - public static final int TROLL_10588 = 10588; + public static final int URIUM_SHADE = 10589; + public static final int DAMPE = 10590; + public static final int UNDEAD_ZEALOT = 10591; + public static final int UNDEAD_ZEALOT_10592 = 10592; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java index 622f0fc904..c0acd7f40c 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java @@ -174,7 +174,6 @@ public final class NullNpcID public static final int NULL_2780 = 2780; public static final int NULL_2781 = 2781; public static final int NULL_2831 = 2831; - public static final int NULL_2832 = 2832; public static final int NULL_2934 = 2934; public static final int NULL_2935 = 2935; public static final int NULL_2936 = 2936; From 2be9fe9df3357b3d27863b0efeb7224d564b1c93 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 25 Jan 2021 13:03:09 -0500 Subject: [PATCH 21/53] slayer plugin: update task completion message parsing --- .../client/plugins/slayer/SlayerPlugin.java | 47 +++++++---------- .../plugins/slayer/SlayerPluginTest.java | 51 ++++++++++++++++--- 2 files changed, 64 insertions(+), 34 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java index 72ad3524ee..db9b247fe3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java @@ -99,7 +99,7 @@ public class SlayerPlugin extends Plugin //Chat messages private static final Pattern CHAT_GEM_PROGRESS_MESSAGE = Pattern.compile("^(?:You're assigned to kill|You have received a new Slayer assignment from .*:) (?:[Tt]he )?(?.+?)(?: (?:in|on|south of) (?:the )?(?[^;]+))?(?:; only | \\()(?\\d+)(?: more to go\\.|\\))$"); private static final String CHAT_GEM_COMPLETE_MESSAGE = "You need something new to hunt."; - private static final Pattern CHAT_COMPLETE_MESSAGE = Pattern.compile("(?:\\d+,)*\\d+"); + private static final Pattern CHAT_COMPLETE_MESSAGE = Pattern.compile("You've completed (?:at least )?(?[\\d,]+) (?:Wilderness )?tasks?(?: and received \\d+ points, giving you a total of (?[\\d,]+)| and reached the maximum amount of Slayer points \\((?[\\d,]+)\\))?"); private static final String CHAT_CANCEL_MESSAGE = "Your task has been cancelled."; private static final String CHAT_CANCEL_MESSAGE_JAD = "You no longer have a slayer task as you left the fight cave."; private static final String CHAT_CANCEL_MESSAGE_ZUK = "You no longer have a slayer task as you left the Inferno."; @@ -450,6 +450,7 @@ public class SlayerPlugin extends Plugin expeditiousChargeCount = Integer.parseInt(mExpeditious.group(1)); config.expeditious(expeditiousChargeCount); } + if (chatMsg.startsWith(CHAT_BRACELET_SLAUGHTER_CHARGE)) { Matcher mSlaughter = CHAT_BRACELET_SLAUGHTER_CHARGE_REGEX.matcher(chatMsg); @@ -466,35 +467,25 @@ public class SlayerPlugin extends Plugin { Matcher mComplete = CHAT_COMPLETE_MESSAGE.matcher(chatMsg); - List matches = new ArrayList<>(); - while (mComplete.find()) + if (mComplete.find()) { - matches.add(mComplete.group(0).replaceAll(",", "")); - } + String mTasks = mComplete.group("tasks"); + String mPoints = mComplete.group("points"); + if (mPoints == null) + { + mPoints = mComplete.group("points2"); + } - int streak = -1, points = -1; - switch (matches.size()) - { - case 0: - streak = 1; - break; - case 1: - streak = Integer.parseInt(matches.get(0)); - break; - case 3: - streak = Integer.parseInt(matches.get(0)); - points = Integer.parseInt(matches.get(2)); - break; - default: - log.warn("Unreachable default case for message ending in '; return to Slayer master'"); - } - if (streak != -1) - { - config.streak(streak); - } - if (points != -1) - { - config.points(points); + if (mTasks != null) + { + int streak = Integer.parseInt(mTasks.replace(",", "")); + config.streak(streak); + } + if (mPoints != null) + { + int points = Integer.parseInt(mPoints.replace(",", "")); + config.points(points); + } } setTask("", 0, 0); diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java index d2b4b13f5a..967802b2cf 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/slayer/SlayerPluginTest.java @@ -101,11 +101,14 @@ public class SlayerPluginTest private static final String REWARD_POINTS = "Reward points: 17,566"; - private static final String TASK_ONE = "You've completed one task; return to a Slayer master."; - private static final String TASK_COMPLETE_NO_POINTS = "You've completed 3 tasks; return to a Slayer master."; - private static final String TASK_POINTS = "You've completed 9 tasks and received 0 points, giving you a total of 18,000; return to a Slayer master."; - private static final String TASK_LARGE_STREAK = "You've completed 2,465 tasks and received 15 points, giving you a total of 17,566,000; return to a Slayer master."; - private static final String TASK_COMPETE_TURAEL = "You've completed 104 tasks. You'll be eligible to earn reward points if you complete tasks from a more advanced Slayer Master."; + private static final String TASK_ONE = "You've completed 1 task and will need 4 more before you start receiving Slayer points; return to a Slayer master."; + private static final String TASK_COMPLETE_NO_POINTS = "You've completed 3 tasks and will need 2 more before you start receiving Slayer points; return to a Slayer master."; + private static final String TASK_POINTS = "You've completed 9 tasks and received 10 points, giving you a total of 18,000; return to a Slayer master."; + private static final String TASK_LARGE_STREAK = "You've completed 2,465 tasks and received 15 points, giving you a total of 131,071; return to a Slayer master."; + private static final String TASK_COMPETE_TURAEL = "You've completed 104 tasks . You'll be eligible to earn reward points if you complete tasks from a more advanced Slayer Master."; + private static final String TASK_MAX_STREAK = "You've completed at least 16,000 tasks and received 15 points, giving you a total of 131,071; return to a Slayer master."; + private static final String TASK_MAX_POINTS = "You've completed 9 tasks and reached the maximum amount of Slayer points (131,071); return to a Slayer master."; + private static final String TASK_WILDERNESS = "You've completed 9 Wilderness tasks and received 10 points, giving you a total of 18,000; return to a Slayer master."; private static final String TASK_COMPLETE = "You need something new to hunt."; private static final String TASK_CANCELED = "Your task has been cancelled."; @@ -483,7 +486,7 @@ public class SlayerPluginTest verify(slayerConfig).streak(2465); assertEquals("", slayerPlugin.getTaskName()); assertEquals(0, slayerPlugin.getAmount()); - verify(slayerConfig).points(17_566_000); + verify(slayerConfig).points(131_071); } @Test @@ -497,6 +500,42 @@ public class SlayerPluginTest assertEquals(0, slayerPlugin.getAmount()); } + @Test + public void testTaskMaxStreak() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_MAX_STREAK, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(16_000); + verify(slayerConfig).points(131_071); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testTaskMaxPoints() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_MAX_POINTS, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(9); + verify(slayerConfig).points(131_071); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + + @Test + public void testTaskWilderness() + { + ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", TASK_WILDERNESS, null, 0); + slayerPlugin.onChatMessage(chatMessageEvent); + + verify(slayerConfig).streak(9); + verify(slayerConfig).points(18_000); + assertEquals("", slayerPlugin.getTaskName()); + assertEquals(0, slayerPlugin.getAmount()); + } + @Test public void testComplete() { From 5eab226b3795307c1d0e08a55d68c5a4c9992852 Mon Sep 17 00:00:00 2001 From: Runelite auto updater Date: Wed, 27 Jan 2021 11:49:30 +0000 Subject: [PATCH 22/53] Release 1.6.38 --- cache-client/pom.xml | 2 +- cache-updater/pom.xml | 2 +- cache/pom.xml | 2 +- http-api/pom.xml | 2 +- http-service/pom.xml | 2 +- pom.xml | 4 ++-- runelite-api/pom.xml | 2 +- runelite-client/pom.xml | 2 +- runelite-script-assembler-plugin/pom.xml | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cache-client/pom.xml b/cache-client/pom.xml index 64e289637a..57ec51fdaf 100644 --- a/cache-client/pom.xml +++ b/cache-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38-SNAPSHOT + 1.6.38 cache-client diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml index 84680ae2ef..6e7643a80c 100644 --- a/cache-updater/pom.xml +++ b/cache-updater/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.6.38-SNAPSHOT + 1.6.38 Cache Updater diff --git a/cache/pom.xml b/cache/pom.xml index 2493a298c3..ea4003b324 100644 --- a/cache/pom.xml +++ b/cache/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38-SNAPSHOT + 1.6.38 cache diff --git a/http-api/pom.xml b/http-api/pom.xml index 44a54972f9..433473fae3 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.6.38-SNAPSHOT + 1.6.38 Web API diff --git a/http-service/pom.xml b/http-service/pom.xml index 0a5a66948a..2542170650 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.6.38-SNAPSHOT + 1.6.38 Web Service diff --git a/pom.xml b/pom.xml index 39f5f6f422..da133f32ca 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.6.38-SNAPSHOT + 1.6.38 pom RuneLite @@ -61,7 +61,7 @@ https://github.com/runelite/runelite scm:git:git://github.com/runelite/runelite scm:git:git@github.com:runelite/runelite - HEAD + runelite-parent-1.6.38 diff --git a/runelite-api/pom.xml b/runelite-api/pom.xml index 5a035ea6c7..fb5a88b052 100644 --- a/runelite-api/pom.xml +++ b/runelite-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38-SNAPSHOT + 1.6.38 runelite-api diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 682c6625f8..6ec2a05b30 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38-SNAPSHOT + 1.6.38 client diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml index ff8e50ba3c..6d4306d736 100644 --- a/runelite-script-assembler-plugin/pom.xml +++ b/runelite-script-assembler-plugin/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38-SNAPSHOT + 1.6.38 script-assembler-plugin From 585bdc65d4b1960bcee2fbeded6b2656907a7ea0 Mon Sep 17 00:00:00 2001 From: Runelite auto updater Date: Wed, 27 Jan 2021 11:49:39 +0000 Subject: [PATCH 23/53] Bump for 1.6.39-SNAPSHOT --- cache-client/pom.xml | 2 +- cache-updater/pom.xml | 2 +- cache/pom.xml | 2 +- http-api/pom.xml | 2 +- http-service/pom.xml | 2 +- pom.xml | 4 ++-- runelite-api/pom.xml | 2 +- runelite-client/pom.xml | 2 +- runelite-script-assembler-plugin/pom.xml | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cache-client/pom.xml b/cache-client/pom.xml index 57ec51fdaf..eaa5cc4bc1 100644 --- a/cache-client/pom.xml +++ b/cache-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38 + 1.6.39-SNAPSHOT cache-client diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml index 6e7643a80c..e8ed1260ad 100644 --- a/cache-updater/pom.xml +++ b/cache-updater/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.6.38 + 1.6.39-SNAPSHOT Cache Updater diff --git a/cache/pom.xml b/cache/pom.xml index ea4003b324..88f64d466f 100644 --- a/cache/pom.xml +++ b/cache/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38 + 1.6.39-SNAPSHOT cache diff --git a/http-api/pom.xml b/http-api/pom.xml index 433473fae3..8ebea1f210 100644 --- a/http-api/pom.xml +++ b/http-api/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.6.38 + 1.6.39-SNAPSHOT Web API diff --git a/http-service/pom.xml b/http-service/pom.xml index 2542170650..44f7340e3f 100644 --- a/http-service/pom.xml +++ b/http-service/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.6.38 + 1.6.39-SNAPSHOT Web Service diff --git a/pom.xml b/pom.xml index da133f32ca..e9c9fb5744 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ net.runelite runelite-parent - 1.6.38 + 1.6.39-SNAPSHOT pom RuneLite @@ -61,7 +61,7 @@ https://github.com/runelite/runelite scm:git:git://github.com/runelite/runelite scm:git:git@github.com:runelite/runelite - runelite-parent-1.6.38 + HEAD diff --git a/runelite-api/pom.xml b/runelite-api/pom.xml index fb5a88b052..9fff909084 100644 --- a/runelite-api/pom.xml +++ b/runelite-api/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38 + 1.6.39-SNAPSHOT runelite-api diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 6ec2a05b30..518749315a 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38 + 1.6.39-SNAPSHOT client diff --git a/runelite-script-assembler-plugin/pom.xml b/runelite-script-assembler-plugin/pom.xml index 6d4306d736..47677f9a03 100644 --- a/runelite-script-assembler-plugin/pom.xml +++ b/runelite-script-assembler-plugin/pom.xml @@ -29,7 +29,7 @@ net.runelite runelite-parent - 1.6.38 + 1.6.39-SNAPSHOT script-assembler-plugin From 42e745881f81e369e4316b7e723fad1057386951 Mon Sep 17 00:00:00 2001 From: Broooklyn <54762282+Broooklyn@users.noreply.github.com> Date: Wed, 27 Jan 2021 10:20:01 -0500 Subject: [PATCH 24/53] itemstats: Update Soul Wars Bandages healing --- .../net/runelite/client/plugins/itemstats/ItemStatChanges.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java index 1a6d4677e7..ac7be8d848 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemstats/ItemStatChanges.java @@ -215,7 +215,7 @@ public class ItemStatChanges add(new GauntletPotion(), EGNIOL_POTION_1, EGNIOL_POTION_2, EGNIOL_POTION_3, EGNIOL_POTION_4); // Soul Wars - add(combo(2, heal(HITPOINTS, perc(.20, 2)), heal(RUN_ENERGY, 100)), BANDAGES_25202); + add(combo(2, heal(HITPOINTS, perc(.15, 1)), heal(RUN_ENERGY, 100)), BANDAGES_25202); add(combo(6, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5)), boost(RANGED, perc(.15, 5)), boost(MAGIC, perc(.15, 5)), heal(PRAYER, perc(.25, 8))), POTION_OF_POWER1, POTION_OF_POWER2, POTION_OF_POWER3, POTION_OF_POWER4); log.debug("{} items; {} behaviours loaded", effects.size(), new HashSet<>(effects.values()).size()); From 267dbb3231d25515702728dc838050f6fc24b659 Mon Sep 17 00:00:00 2001 From: Broooklyn <54762282+Broooklyn@users.noreply.github.com> Date: Wed, 27 Jan 2021 20:25:44 -0500 Subject: [PATCH 25/53] npc indicators: remove tags from minimap npc name --- .../client/plugins/npchighlight/NpcMinimapOverlay.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java index 9582288ea1..e1fd961216 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcMinimapOverlay.java @@ -36,6 +36,7 @@ import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayLayer; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayUtil; +import net.runelite.client.util.Text; public class NpcMinimapOverlay extends Overlay { @@ -56,7 +57,7 @@ public class NpcMinimapOverlay extends Overlay { for (NPC npc : plugin.getHighlightedNpcs()) { - renderNpcOverlay(graphics, npc, npc.getName(), config.getHighlightColor()); + renderNpcOverlay(graphics, npc, Text.removeTags(npc.getName()), config.getHighlightColor()); } return null; From f5df6a02981ce00a1525e4e19183727a2d9f222f Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 27 Jan 2021 18:42:34 -0500 Subject: [PATCH 26/53] menu manager: preserve managed menu option ordering Also add a check that the menu being added is of type CC_OP so that we know getWidgetId() is valid --- .../main/java/net/runelite/client/menus/MenuManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index a597038628..179b757001 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -26,7 +26,7 @@ package net.runelite.client.menus; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; +import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import java.util.Arrays; import java.util.Collection; @@ -66,7 +66,7 @@ public class MenuManager //Maps the indexes that are being used to the menu option. private final Map playerMenuIndexMap = new HashMap<>(); //Used to manage custom non-player menu options - private final Multimap managedMenuOptions = HashMultimap.create(); + private final Multimap managedMenuOptions = LinkedHashMultimap.create(); private final Set npcMenuOptions = new HashSet<>(); @Inject @@ -117,7 +117,7 @@ public class MenuManager @Subscribe public void onMenuEntryAdded(MenuEntryAdded event) { - if (client.getSpellSelected()) + if (client.getSpellSelected() || event.getType() != MenuAction.CC_OP.getId()) { return; } From 84661dfe5202c2f91f83385ea474b7a5955857ec Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 27 Jan 2021 18:43:49 -0500 Subject: [PATCH 27/53] api: remove npc action changed event Despite menu manager using this, the methods to register npc menu options was removed awhile ago, and so it is unused --- .../runelite/api/events/NpcActionChanged.java | 44 ------------------- .../runelite/client/menus/MenuManager.java | 37 ---------------- 2 files changed, 81 deletions(-) delete mode 100644 runelite-api/src/main/java/net/runelite/api/events/NpcActionChanged.java diff --git a/runelite-api/src/main/java/net/runelite/api/events/NpcActionChanged.java b/runelite-api/src/main/java/net/runelite/api/events/NpcActionChanged.java deleted file mode 100644 index 7539821167..0000000000 --- a/runelite-api/src/main/java/net/runelite/api/events/NpcActionChanged.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2018, 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.api.events; - -import lombok.Data; -import net.runelite.api.NPCComposition; - -/** - * An event where an action of an {@link NPCComposition} has changed. - */ -@Data -public class NpcActionChanged -{ - /** - * The NPC composition that has been changed. - */ - private NPCComposition npcComposition; - /** - * The raw index of the modified action. - */ - private int idx; -} diff --git a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java index 179b757001..c2231233db 100644 --- a/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java +++ b/runelite-client/src/main/java/net/runelite/client/menus/MenuManager.java @@ -31,19 +31,15 @@ import com.google.common.collect.Multimap; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.MenuAction; import net.runelite.api.MenuEntry; -import net.runelite.api.NPCComposition; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.NpcActionChanged; import net.runelite.api.events.PlayerMenuOptionsChanged; import net.runelite.api.events.WidgetMenuOptionClicked; import net.runelite.api.widgets.WidgetInfo; @@ -67,7 +63,6 @@ public class MenuManager private final Map playerMenuIndexMap = new HashMap<>(); //Used to manage custom non-player menu options private final Multimap managedMenuOptions = LinkedHashMultimap.create(); - private final Set npcMenuOptions = new HashSet<>(); @Inject @VisibleForTesting @@ -194,38 +189,6 @@ public class MenuManager addPlayerMenuItem(newIdx, menuText); } - @Subscribe - public void onNpcActionChanged(NpcActionChanged event) - { - NPCComposition composition = event.getNpcComposition(); - for (String npcOption : npcMenuOptions) - { - addNpcOption(composition, npcOption); - } - } - - private void addNpcOption(NPCComposition composition, String npcOption) - { - String[] actions = composition.getActions(); - int unused = -1; - for (int i = 0; i < actions.length; ++i) - { - if (actions[i] == null && unused == -1) - { - unused = i; - } - else if (actions[i] != null && actions[i].equals(npcOption)) - { - return; - } - } - if (unused == -1) - { - return; - } - actions[unused] = npcOption; - } - @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { From e3b0755385c3594d6d76d0130c4bc9c2e1aebdcf Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 28 Jan 2021 23:28:14 -0500 Subject: [PATCH 28/53] world hopper: move hop() to client thread --- .../plugins/worldhopper/WorldHopperPlugin.java | 12 +++++++++--- .../plugins/worldhopper/WorldSwitcherPanel.java | 5 +---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java index a283fe9d7f..f0d4f88185 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldHopperPlugin.java @@ -64,6 +64,7 @@ import net.runelite.api.events.MenuOptionClicked; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WorldListLoad; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatMessageBuilder; import net.runelite.client.chat.ChatMessageManager; @@ -111,6 +112,9 @@ public class WorldHopperPlugin extends Plugin @Inject private Client client; + @Inject + private ClientThread clientThread; + @Inject private ConfigManager configManager; @@ -162,7 +166,7 @@ public class WorldHopperPlugin extends Plugin @Override public void hotkeyPressed() { - hop(true); + clientThread.invoke(() -> hop(true)); } }; private final HotkeyListener nextKeyListener = new HotkeyListener(() -> config.nextKey()) @@ -170,7 +174,7 @@ public class WorldHopperPlugin extends Plugin @Override public void hotkeyPressed() { - hop(false); + clientThread.invoke(() -> hop(false)); } }; @@ -304,7 +308,7 @@ public class WorldHopperPlugin extends Plugin void hopTo(World world) { - hop(world.getId()); + clientThread.invoke(() -> hop(world.getId())); } void addToFavorites(World world) @@ -613,6 +617,8 @@ public class WorldHopperPlugin extends Plugin private void hop(int worldId) { + assert client.isClientThread(); + WorldResult worldResult = worldService.getWorlds(); // Don't try to hop if the world doesn't exist World world = worldResult.findWorld(worldId); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java index 486d88f373..2f0d428712 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldhopper/WorldSwitcherPanel.java @@ -370,10 +370,7 @@ class WorldSwitcherPanel extends PluginPanel private WorldTableRow buildRow(World world, boolean stripe, boolean current, boolean favorite) { WorldTableRow row = new WorldTableRow(world, current, favorite, plugin.getStoredPing(world), - world1 -> - { - plugin.hopTo(world1); - }, + plugin::hopTo, (world12, add) -> { if (add) From 61f732d3301a80d8aea8a56522726398d87b2a9d Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 30 Jan 2021 11:10:05 -0500 Subject: [PATCH 29/53] tile: add setter for ground object --- runelite-api/src/main/java/net/runelite/api/Tile.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/Tile.java b/runelite-api/src/main/java/net/runelite/api/Tile.java index be35c8c3d2..9c0565ea31 100644 --- a/runelite-api/src/main/java/net/runelite/api/Tile.java +++ b/runelite-api/src/main/java/net/runelite/api/Tile.java @@ -61,6 +61,13 @@ public interface Tile */ GroundObject getGroundObject(); + /** + * Sets the object on the ground layer of the tile. + * + * @param groundObject the ground object + */ + void setGroundObject(GroundObject groundObject); + /** * Gets the wall of the tile. * From 2b3ce15516c65703885c0ea5c74ae53971cd1bce Mon Sep 17 00:00:00 2001 From: Max Weber Date: Tue, 22 Dec 2020 12:00:31 -0700 Subject: [PATCH 30/53] don't use gson's reflection serialization on non RuneLite classes java >=16 disallows access to most private fields which makes these fail with the reflection type adapter --- .../net/runelite/http/api/RuneLiteAPI.java | 25 +++++- .../http/api/gson/ColorTypeAdapter.java | 80 ++++++++++++++++++ .../api/gson/IllegalReflectionExclusion.java | 58 +++++++++++++ .../http/api/gson/InstantTypeAdapter.java | 82 +++++++++++++++++++ .../http/api/ws/WebsocketGsonFactory.java | 4 +- .../http/api/gson/ColorTypeAdapterTest.java | 51 ++++++++++++ .../http/api/gson/InstantTypeAdapterTest.java | 49 +++++++++++ .../net/runelite/client/RuneLiteModule.java | 4 + .../client/account/SessionManager.java | 9 +- .../externalplugins/ExternalPluginClient.java | 11 ++- .../crowdsourcing/CrowdsourcingManager.java | 7 +- .../grandexchange/GrandExchangePlugin.java | 8 +- .../groundmarkers/GroundMarkerPlugin.java | 9 +- .../GroundMarkerSharingManager.java | 12 +-- .../ObjectIndicatorsPlugin.java | 8 +- .../screenmarkers/ScreenMarkerPlugin.java | 5 +- .../timetracking/clocks/ClockManager.java | 7 +- .../wiki/WikiSearchChatboxTextInput.java | 3 +- .../runelite/client/util/ImageCapture.java | 11 ++- 19 files changed, 402 insertions(+), 41 deletions(-) create mode 100644 http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java create mode 100644 http-api/src/main/java/net/runelite/http/api/gson/IllegalReflectionExclusion.java create mode 100644 http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java create mode 100644 http-api/src/test/java/net/runelite/http/api/gson/ColorTypeAdapterTest.java create mode 100644 http-api/src/test/java/net/runelite/http/api/gson/InstantTypeAdapterTest.java diff --git a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java index 0b017518c8..dc483f35db 100644 --- a/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java +++ b/http-api/src/main/java/net/runelite/http/api/RuneLiteAPI.java @@ -25,10 +25,16 @@ package net.runelite.http.api; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.awt.Color; import java.io.IOException; import java.io.InputStream; +import java.time.Instant; import java.util.Properties; import java.util.concurrent.TimeUnit; +import net.runelite.http.api.gson.ColorTypeAdapter; +import net.runelite.http.api.gson.InstantTypeAdapter; +import net.runelite.http.api.gson.IllegalReflectionExclusion; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.MediaType; @@ -46,7 +52,7 @@ public class RuneLiteAPI public static final String RUNELITE_MACHINEID = "RUNELITE-MACHINEID"; public static final OkHttpClient CLIENT; - public static final Gson GSON = new Gson(); + public static final Gson GSON; public static final MediaType JSON = MediaType.parse("application/json"); public static String userAgent; @@ -96,6 +102,23 @@ public class RuneLiteAPI } }) .build(); + + GsonBuilder gsonBuilder = new GsonBuilder(); + + gsonBuilder + .registerTypeAdapter(Instant.class, new InstantTypeAdapter()) + .registerTypeAdapter(Color.class, new ColorTypeAdapter()); + + boolean assertionsEnabled = false; + assert assertionsEnabled = true; + if (assertionsEnabled) + { + IllegalReflectionExclusion jbe = new IllegalReflectionExclusion(); + gsonBuilder.addSerializationExclusionStrategy(jbe); + gsonBuilder.addDeserializationExclusionStrategy(jbe); + } + + GSON = gsonBuilder.create(); } public static HttpUrl getSessionBase() diff --git a/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java b/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java new file mode 100644 index 0000000000..6f4b003df0 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/gson/ColorTypeAdapter.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020 Abex + * 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.http.api.gson; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.awt.Color; +import java.io.IOException; + +public class ColorTypeAdapter extends TypeAdapter +{ + @Override + public void write(JsonWriter out, Color value) throws IOException + { + if (value == null) + { + out.nullValue(); + return; + } + + int rgba = value.getRGB(); + out.beginObject() + .name("value") + .value(rgba) + .endObject(); + } + + @Override + public Color read(JsonReader in) throws IOException + { + switch (in.peek()) + { + case NULL: + in.nextNull(); + return null; + case BEGIN_OBJECT: + in.beginObject(); + double value = 0; + while (in.peek() != JsonToken.END_OBJECT) + { + switch (in.nextName()) + { + case "value": + value = in.nextDouble(); + break; + default: + in.skipValue(); + break; + } + } + in.endObject(); + return new Color((int) value, true); + } + return null; // throws + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/gson/IllegalReflectionExclusion.java b/http-api/src/main/java/net/runelite/http/api/gson/IllegalReflectionExclusion.java new file mode 100644 index 0000000000..d7611cf83f --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/gson/IllegalReflectionExclusion.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 Abex + * 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.http.api.gson; + +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; +import java.lang.reflect.Modifier; + +public class IllegalReflectionExclusion implements ExclusionStrategy +{ + @Override + public boolean shouldSkipField(FieldAttributes f) + { + if (f.getDeclaringClass().getName().startsWith("net.runelite")) + { + return false; + } + + assert !Modifier.isPrivate(f.getDeclaringClass().getModifiers()) : "gsoning private class " + f.getDeclaringClass().getName(); + try + { + f.getDeclaringClass().getField(f.getName()); + } + catch (NoSuchFieldException e) + { + throw new AssertionError("gsoning private field " + f.getDeclaringClass() + "." + f.getName()); + } + return false; + } + + @Override + public boolean shouldSkipClass(Class clazz) + { + return false; + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java b/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java new file mode 100644 index 0000000000..bf92af94b8 --- /dev/null +++ b/http-api/src/main/java/net/runelite/http/api/gson/InstantTypeAdapter.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020 Abex + * 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.http.api.gson; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.time.Instant; + +// Just add water! +public class InstantTypeAdapter extends TypeAdapter +{ + @Override + public void write(JsonWriter out, Instant value) throws IOException + { + if (value == null) + { + out.nullValue(); + return; + } + + out.beginObject() + .name("seconds") + .value(value.getEpochSecond()) + .name("nanos") + .value(value.getNano()) + .endObject(); + } + + @Override + public Instant read(JsonReader in) throws IOException + { + if (in.peek() == JsonToken.NULL) + { + in.nextNull(); + return null; + } + + long seconds = 0; + int nanos = 0; + in.beginObject(); + while (in.peek() != JsonToken.END_OBJECT) + { + switch (in.nextName()) + { + case "nanos": + nanos = in.nextInt(); + break; + case "seconds": + seconds = in.nextLong(); + break; + } + } + in.endObject(); + + return Instant.ofEpochSecond(seconds, nanos); + } +} diff --git a/http-api/src/main/java/net/runelite/http/api/ws/WebsocketGsonFactory.java b/http-api/src/main/java/net/runelite/http/api/ws/WebsocketGsonFactory.java index 9d4e46e6ea..328d0aa1a7 100644 --- a/http-api/src/main/java/net/runelite/http/api/ws/WebsocketGsonFactory.java +++ b/http-api/src/main/java/net/runelite/http/api/ws/WebsocketGsonFactory.java @@ -25,11 +25,11 @@ package net.runelite.http.api.ws; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.ws.messages.Handshake; import net.runelite.http.api.ws.messages.LoginResponse; import net.runelite.http.api.ws.messages.party.Join; @@ -76,7 +76,7 @@ public class WebsocketGsonFactory public static Gson build(final RuntimeTypeAdapterFactory factory) { - return new GsonBuilder() + return RuneLiteAPI.GSON.newBuilder() .registerTypeAdapterFactory(factory) .create(); } diff --git a/http-api/src/test/java/net/runelite/http/api/gson/ColorTypeAdapterTest.java b/http-api/src/test/java/net/runelite/http/api/gson/ColorTypeAdapterTest.java new file mode 100644 index 0000000000..d7f5e6fd4c --- /dev/null +++ b/http-api/src/test/java/net/runelite/http/api/gson/ColorTypeAdapterTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Abex + * 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.http.api.gson; + +import java.awt.Color; +import net.runelite.http.api.RuneLiteAPI; +import org.junit.Assert; +import org.junit.Test; + +public class ColorTypeAdapterTest +{ + @Test + public void test() + { + test("null", null); + test("{\"value\":-13347208,\"falpha\":0.0}", new Color(0x12345678, false)); + test("{\"value\":305419896,\"falpha\":0.0}", new Color(0x12345678, true)); + test("{\"value\":-1.4221317E7,\"falpha\":0.0}", new Color(0xFF26FFFB, true)); + } + + private void test(String json, Color object) + { + Color parsed = RuneLiteAPI.GSON.fromJson(json, Color.class); + Assert.assertEquals(object, parsed); + String serialized = RuneLiteAPI.GSON.toJson(object); + Color roundTripped = RuneLiteAPI.GSON.fromJson(serialized, Color.class); + Assert.assertEquals(object, roundTripped); + } +} \ No newline at end of file diff --git a/http-api/src/test/java/net/runelite/http/api/gson/InstantTypeAdapterTest.java b/http-api/src/test/java/net/runelite/http/api/gson/InstantTypeAdapterTest.java new file mode 100644 index 0000000000..dab70a4f96 --- /dev/null +++ b/http-api/src/test/java/net/runelite/http/api/gson/InstantTypeAdapterTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Abex + * 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.http.api.gson; + +import java.time.Instant; +import net.runelite.http.api.RuneLiteAPI; +import org.junit.Assert; +import org.junit.Test; + +public class InstantTypeAdapterTest +{ + @Test + public void test() + { + test("null", null); + test("{\"seconds\":1609538310,\"nanos\":291698903}", Instant.ofEpochSecond(1609538310, 291698903)); + } + + private void test(String json, Instant object) + { + Instant parsed = RuneLiteAPI.GSON.fromJson(json, Instant.class); + Assert.assertEquals(object, parsed); + String serialized = RuneLiteAPI.GSON.toJson(object); + Instant roundTripped = RuneLiteAPI.GSON.fromJson(serialized, Instant.class); + Assert.assertEquals(object, roundTripped); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java b/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java index 3376c62f77..8c80c67a37 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLiteModule.java @@ -24,6 +24,7 @@ */ package net.runelite.client; +import com.google.gson.Gson; import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.name.Names; @@ -51,6 +52,7 @@ import net.runelite.client.plugins.PluginManager; import net.runelite.client.task.Scheduler; import net.runelite.client.util.DeferredEventBus; import net.runelite.client.util.ExecutorServiceExceptionLogger; +import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.chat.ChatClient; import okhttp3.OkHttpClient; @@ -86,6 +88,8 @@ public class RuneLiteModule extends AbstractModule bind(PluginManager.class); bind(SessionManager.class); + bind(Gson.class).toInstance(RuneLiteAPI.GSON); + bind(Callbacks.class).to(Hooks.class); bind(EventBus.class) diff --git a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java index cadf0b4562..4b6bf1674e 100644 --- a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java +++ b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java @@ -64,6 +64,7 @@ public class SessionManager private final WSClient wsClient; private final File sessionFile; private final AccountClient accountClient; + private final Gson gson; @Inject private SessionManager( @@ -71,13 +72,15 @@ public class SessionManager ConfigManager configManager, EventBus eventBus, WSClient wsClient, - OkHttpClient okHttpClient) + OkHttpClient okHttpClient, + Gson gson) { this.configManager = configManager; this.eventBus = eventBus; this.wsClient = wsClient; this.sessionFile = sessionfile; this.accountClient = new AccountClient(okHttpClient); + this.gson = gson; eventBus.register(this); } @@ -94,7 +97,7 @@ public class SessionManager try (FileInputStream in = new FileInputStream(sessionFile)) { - session = new Gson().fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), AccountSession.class); + session = gson.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), AccountSession.class); log.debug("Loaded session for {}", session.getUsername()); } @@ -124,7 +127,7 @@ public class SessionManager try (Writer fw = new OutputStreamWriter(new FileOutputStream(sessionFile), StandardCharsets.UTF_8)) { - new Gson().toJson(accountSession, fw); + gson.toJson(accountSession, fw); log.debug("Saved session to {}", sessionFile); } diff --git a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClient.java b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClient.java index e6bda75032..ccf4b9fad3 100644 --- a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClient.java +++ b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClient.java @@ -25,6 +25,7 @@ package net.runelite.client.externalplugins; import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; @@ -59,11 +60,13 @@ import okio.BufferedSource; public class ExternalPluginClient { private final OkHttpClient okHttpClient; + private final Gson gson; @Inject - private ExternalPluginClient(OkHttpClient okHttpClient) + private ExternalPluginClient(OkHttpClient okHttpClient, Gson gson) { this.okHttpClient = okHttpClient; + this.gson = gson; } public List downloadManifest() throws IOException, VerificationException @@ -94,7 +97,7 @@ public class ExternalPluginClient throw new VerificationException("Unable to verify external plugin manifest"); } - return RuneLiteAPI.GSON.fromJson(new String(data, StandardCharsets.UTF_8), + return gson.fromJson(new String(data, StandardCharsets.UTF_8), new TypeToken>() { }.getType()); @@ -156,7 +159,7 @@ public class ExternalPluginClient Request request = new Request.Builder() .url(url) - .post(RequestBody.create(RuneLiteAPI.JSON, RuneLiteAPI.GSON.toJson(plugins))) + .post(RequestBody.create(RuneLiteAPI.JSON, gson.toJson(plugins))) .build(); okHttpClient.newCall(request).enqueue(new Callback() @@ -190,7 +193,7 @@ public class ExternalPluginClient } // CHECKSTYLE:OFF - return RuneLiteAPI.GSON.fromJson(new InputStreamReader(res.body().byteStream()), new TypeToken>(){}.getType()); + return gson.fromJson(new InputStreamReader(res.body().byteStream()), new TypeToken>(){}.getType()); // CHECKSTYLE:ON } catch (JsonSyntaxException ex) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/CrowdsourcingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/CrowdsourcingManager.java index 661071a786..09d737c10f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/CrowdsourcingManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/crowdsourcing/CrowdsourcingManager.java @@ -32,7 +32,6 @@ import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; -import net.runelite.http.api.RuneLiteAPI; import okhttp3.Call; import okhttp3.Callback; import okhttp3.MediaType; @@ -47,11 +46,13 @@ public class CrowdsourcingManager { private static final String CROWDSOURCING_BASE = "https://crowdsource.runescape.wiki/runelite"; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private static final Gson GSON = RuneLiteAPI.GSON; @Inject private OkHttpClient okHttpClient; + @Inject + private Gson gson; + private List data = new ArrayList<>(); public void storeEvent(Object event) @@ -77,7 +78,7 @@ public class CrowdsourcingManager Request r = new Request.Builder() .url(CROWDSOURCING_BASE) - .post(RequestBody.create(JSON, GSON.toJson(temp))) + .post(RequestBody.create(JSON, gson.toJson(temp))) .build(); okHttpClient.newCall(r).enqueue(new Callback() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java index d28f4b0323..f3d9b513b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grandexchange/GrandExchangePlugin.java @@ -128,7 +128,6 @@ public class GrandExchangePlugin extends Plugin private static final String BUY_LIMIT_GE_TEXT = "
Buy limit: "; private static final String BUY_LIMIT_KEY = "buylimit"; - private static final Gson GSON = new Gson(); private static final Duration BUY_LIMIT_RESET = Duration.ofHours(4); static final String SEARCH_GRAND_EXCHANGE = "Search Grand Exchange"; @@ -183,6 +182,9 @@ public class GrandExchangePlugin extends Plugin @Inject private ConfigManager configManager; + @Inject + private Gson gson; + private Widget grandExchangeText; private Widget grandExchangeItem; private String grandExchangeExamine; @@ -253,12 +255,12 @@ public class GrandExchangePlugin extends Plugin { return null; } - return GSON.fromJson(offer, SavedOffer.class); + return gson.fromJson(offer, SavedOffer.class); } private void setOffer(int slot, SavedOffer offer) { - configManager.setRSProfileConfiguration("geoffer", Integer.toString(slot), GSON.toJson(offer)); + configManager.setRSProfileConfiguration("geoffer", Integer.toString(slot), gson.toJson(offer)); } private void deleteOffer(int slot) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java index c1e1774931..cfb6171941 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerPlugin.java @@ -73,8 +73,6 @@ public class GroundMarkerPlugin extends Plugin private static final String WALK_HERE = "Walk here"; private static final String REGION_PREFIX = "region_"; - private static final Gson GSON = new Gson(); - @Getter(AccessLevel.PACKAGE) private final List points = new ArrayList<>(); @@ -105,6 +103,9 @@ public class GroundMarkerPlugin extends Plugin @Inject private GroundMarkerSharingManager sharingManager; + @Inject + private Gson gson; + void savePoints(int regionId, Collection points) { if (points == null || points.isEmpty()) @@ -113,7 +114,7 @@ public class GroundMarkerPlugin extends Plugin return; } - String json = GSON.toJson(points); + String json = gson.toJson(points); configManager.setConfiguration(CONFIG_GROUP, REGION_PREFIX + regionId, json); } @@ -126,7 +127,7 @@ public class GroundMarkerPlugin extends Plugin } // CHECKSTYLE:OFF - return GSON.fromJson(json, new TypeToken>(){}.getType()); + return gson.fromJson(json, new TypeToken>(){}.getType()); // CHECKSTYLE:ON } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java index 8899a81f0d..91c0e800ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/groundmarkers/GroundMarkerSharingManager.java @@ -53,7 +53,6 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.chatbox.ChatboxPanelManager; import net.runelite.client.menus.MenuManager; import net.runelite.client.menus.WidgetMenuOption; -import net.runelite.http.api.RuneLiteAPI; @Slf4j class GroundMarkerSharingManager @@ -61,22 +60,23 @@ class GroundMarkerSharingManager private static final WidgetMenuOption EXPORT_MARKERS_OPTION = new WidgetMenuOption("Export", "Ground Markers", WORLD_MAP_OPTION); private static final WidgetMenuOption IMPORT_MARKERS_OPTION = new WidgetMenuOption("Import", "Ground Markers", WORLD_MAP_OPTION); - private static final Gson GSON = RuneLiteAPI.GSON; - private final GroundMarkerPlugin plugin; private final Client client; private final MenuManager menuManager; private final ChatMessageManager chatMessageManager; private final ChatboxPanelManager chatboxPanelManager; + private final Gson gson; @Inject - private GroundMarkerSharingManager(GroundMarkerPlugin plugin, Client client, MenuManager menuManager, ChatMessageManager chatMessageManager, ChatboxPanelManager chatboxPanelManager) + private GroundMarkerSharingManager(GroundMarkerPlugin plugin, Client client, MenuManager menuManager, + ChatMessageManager chatMessageManager, ChatboxPanelManager chatboxPanelManager, Gson gson) { this.plugin = plugin; this.client = client; this.menuManager = menuManager; this.chatMessageManager = chatMessageManager; this.chatboxPanelManager = chatboxPanelManager; + this.gson = gson; } void addMenuOptions() @@ -135,7 +135,7 @@ class GroundMarkerSharingManager return; } - final String exportDump = GSON.toJson(activePoints); + final String exportDump = gson.toJson(activePoints); log.debug("Exported ground markers: {}", exportDump); @@ -173,7 +173,7 @@ class GroundMarkerSharingManager try { // CHECKSTYLE:OFF - importPoints = GSON.fromJson(clipboardText, new TypeToken>(){}.getType()); + importPoints = gson.fromJson(clipboardText, new TypeToken>(){}.getType()); // CHECKSTYLE:ON } catch (JsonSyntaxException e) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java index 46a4a0924d..cfa99092a8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/objectindicators/ObjectIndicatorsPlugin.java @@ -88,7 +88,6 @@ public class ObjectIndicatorsPlugin extends Plugin private static final String MARK = "Mark object"; private static final String UNMARK = "Unmark object"; - private final Gson GSON = new Gson(); @Getter(AccessLevel.PACKAGE) private final List objects = new ArrayList<>(); private final Map> points = new HashMap<>(); @@ -108,6 +107,9 @@ public class ObjectIndicatorsPlugin extends Plugin @Inject private ObjectIndicatorsConfig config; + @Inject + private Gson gson; + @Provides ObjectIndicatorsConfig provideConfig(ConfigManager configManager) { @@ -428,7 +430,7 @@ public class ObjectIndicatorsPlugin extends Plugin } else { - final String json = GSON.toJson(points); + final String json = gson.toJson(points); configManager.setConfiguration(CONFIG_GROUP, "region_" + id, json); } } @@ -442,7 +444,7 @@ public class ObjectIndicatorsPlugin extends Plugin return null; } - Set points = GSON.fromJson(json, new TypeToken>() + Set points = gson.fromJson(json, new TypeToken>() { }.getType()); // Prior to multiloc support the plugin would mark objects named "null", which breaks diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java index 88dca9d214..5ec747e3f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenmarkers/ScreenMarkerPlugin.java @@ -88,6 +88,9 @@ public class ScreenMarkerPlugin extends Plugin @Inject private ScreenMarkerCreationOverlay overlay; + @Inject + private Gson gson; + @Getter @Inject private ColorPickerManager colorPickerManager; @@ -266,7 +269,6 @@ public class ScreenMarkerPlugin extends Plugin return; } - final Gson gson = new Gson(); final String json = gson .toJson(screenMarkers.stream().map(ScreenMarkerOverlay::getMarker).collect(Collectors.toList())); configManager.setConfiguration(CONFIG_GROUP, CONFIG_KEY, json); @@ -279,7 +281,6 @@ public class ScreenMarkerPlugin extends Plugin return Stream.empty(); } - final Gson gson = new Gson(); final List screenMarkerData = gson.fromJson(json, new TypeToken>() { }.getType()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java index 720c5633e9..30d16ff573 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timetracking/clocks/ClockManager.java @@ -53,6 +53,9 @@ public class ClockManager @Inject private Notifier notifier; + @Inject + private Gson gson; + @Getter private final List timers = new CopyOnWriteArrayList<>(); @@ -183,7 +186,6 @@ public class ClockManager if (!Strings.isNullOrEmpty(timersJson)) { - final Gson gson = new Gson(); final List timers = gson.fromJson(timersJson, new TypeToken>() { }.getType()); @@ -200,7 +202,6 @@ public class ClockManager if (!Strings.isNullOrEmpty(stopwatchesJson)) { - final Gson gson = new Gson(); final List stopwatches = gson.fromJson(stopwatchesJson, new TypeToken>() { }.getType()); @@ -227,14 +228,12 @@ public class ClockManager void saveTimers() { - final Gson gson = new Gson(); final String json = gson.toJson(timers); configManager.setConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.TIMERS, json); } void saveStopwatches() { - final Gson gson = new Gson(); final String json = gson.toJson(stopwatches); configManager.setConfiguration(TimeTrackingConfig.CONFIG_GROUP, TimeTrackingConfig.STOPWATCHES, json); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java index 8552d90eef..622e4db98b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wiki/WikiSearchChatboxTextInput.java @@ -67,7 +67,6 @@ public class WikiSearchChatboxTextInput extends ChatboxTextInput private static final int PREDICTION_DEBOUNCE_DELAY_MS = 200; private final ChatboxPanelManager chatboxPanelManager; - private final Gson gson = new Gson(); private Future runningRequest = null; private List predictions = ImmutableList.of(); @@ -78,7 +77,7 @@ public class WikiSearchChatboxTextInput extends ChatboxTextInput @Inject public WikiSearchChatboxTextInput(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread, ScheduledExecutorService scheduledExecutorService, @Named("developerMode") final boolean developerMode, - OkHttpClient okHttpClient) + OkHttpClient okHttpClient, Gson gson) { super(chatboxPanelManager, clientThread); this.chatboxPanelManager = chatboxPanelManager; diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java index dfee412c03..e842005dba 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java @@ -26,6 +26,7 @@ package net.runelite.client.util; import com.google.common.base.Strings; +import com.google.gson.Gson; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.datatransfer.Clipboard; @@ -54,7 +55,6 @@ import net.runelite.api.GameState; import net.runelite.api.WorldType; import net.runelite.client.Notifier; import static net.runelite.client.RuneLite.SCREENSHOT_DIR; -import net.runelite.http.api.RuneLiteAPI; import okhttp3.Call; import okhttp3.Callback; import okhttp3.HttpUrl; @@ -75,6 +75,7 @@ public class ImageCapture private final Client client; private final Notifier notifier; private final OkHttpClient okHttpClient; + private final Gson gson; private final String imgurClientId; @Inject @@ -82,12 +83,14 @@ public class ImageCapture final Client client, final Notifier notifier, final OkHttpClient okHttpClient, + final Gson gson, @Named("runelite.imgur.client.id") final String imgurClientId ) { this.client = client; this.notifier = notifier; this.okHttpClient = okHttpClient; + this.gson = gson; this.imgurClientId = imgurClientId; } @@ -204,7 +207,7 @@ public class ImageCapture */ private void uploadScreenshot(File screenshotFile, boolean notify) throws IOException { - String json = RuneLiteAPI.GSON.toJson(new ImageUploadRequest(screenshotFile)); + String json = gson.toJson(new ImageUploadRequest(screenshotFile)); Request request = new Request.Builder() .url(IMGUR_IMAGE_UPLOAD_URL) @@ -225,8 +228,8 @@ public class ImageCapture { try (InputStream in = response.body().byteStream()) { - ImageUploadResponse imageUploadResponse = RuneLiteAPI.GSON - .fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), ImageUploadResponse.class); + ImageUploadResponse imageUploadResponse = + gson.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), ImageUploadResponse.class); if (imageUploadResponse.isSuccess()) { From 243929826b99f3dad1605c48f85f000268bdc41e Mon Sep 17 00:00:00 2001 From: Max Weber Date: Thu, 24 Dec 2020 08:42:30 -0700 Subject: [PATCH 31/53] ReflectUtil: allow privateLookupIn cross-classloader with JDK-8173978 --- .../ExternalPluginClassLoader.java | 16 ++++- .../net/runelite/client/util/ReflectUtil.java | 62 ++++++++++++++++++- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClassLoader.java b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClassLoader.java index 054a7779b5..5690c3d61e 100644 --- a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClassLoader.java +++ b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginClassLoader.java @@ -24,18 +24,32 @@ */ package net.runelite.client.externalplugins; +import java.lang.invoke.MethodHandles; import java.net.URL; import java.net.URLClassLoader; import lombok.Getter; +import lombok.Setter; +import net.runelite.client.util.ReflectUtil; -class ExternalPluginClassLoader extends URLClassLoader +class ExternalPluginClassLoader extends URLClassLoader implements ReflectUtil.PrivateLookupableClassLoader { @Getter private final ExternalPluginManifest manifest; + @Getter + @Setter + private MethodHandles.Lookup lookup; + ExternalPluginClassLoader(ExternalPluginManifest manifest, URL[] urls) { super(urls, ExternalPluginClassLoader.class.getClassLoader()); this.manifest = manifest; + ReflectUtil.installLookupHelper(this); + } + + @Override + public Class defineClass0(String name, byte[] b, int off, int len) throws ClassFormatError + { + return super.defineClass(name, b, off, len); } } diff --git a/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java b/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java index 60b3b305f1..fbcc28d28d 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ReflectUtil.java @@ -25,6 +25,8 @@ */ package net.runelite.client.util; +import com.google.common.io.ByteStreams; +import java.io.IOException; import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -36,7 +38,7 @@ public class ReflectUtil { } - public static MethodHandles.Lookup privateLookupIn(Class clazz) + public static MethodHandles.Lookup privateLookupIn(Class clazz) { try { @@ -44,7 +46,16 @@ public class ReflectUtil // we need to access it via reflection. This is preferred way because it's Java 9+ public api and is // likely to not change final Method privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class); - return (MethodHandles.Lookup) privateLookupIn.invoke(null, clazz, MethodHandles.lookup()); + MethodHandles.Lookup caller; + if (clazz.getClassLoader() instanceof PrivateLookupableClassLoader) + { + caller = ((PrivateLookupableClassLoader) clazz.getClassLoader()).getLookup(); + } + else + { + caller = MethodHandles.lookup(); + } + return (MethodHandles.Lookup) privateLookupIn.invoke(null, clazz, caller); } catch (InvocationTargetException | IllegalAccessException e) { @@ -69,4 +80,51 @@ public class ReflectUtil } } } + + public interface PrivateLookupableClassLoader + { + // define class is protected final so this needs a different name to become public + Class defineClass0(String name, byte[] b, int off, int len) throws ClassFormatError; + + MethodHandles.Lookup getLookup(); + void setLookup(MethodHandles.Lookup lookup); + } + + /** + * Allows private Lookups to be created for classes in this ClassLoader + *

+ * Due to JDK-8173978 it is impossible to create get a lookup with module scoped permissions when teleporting + * between modules. Since external plugins are loaded in a separate classloader to us they are contained in unique + * unnamed modules. Since we (via LambdaMetafactory) are creating a hidden class in that module, we require module + * scoped access to it, and since the methods can be private, we also require private access. The only way to get + * MODULE|PRIVATE is to either 1) invokedynamic in that class, 2) call MethodHandles.lookup() from that class, or + * 3) call privateLookupIn with an existing lookup with PRIVATE|MODULE created from a class in the same module. + * Our solution is to make classloaders call this method which will define a class in the classloader's unnamed + * module that calls MethodHandles.lookup() and stores it in the classloader for later use. + */ + public static void installLookupHelper(PrivateLookupableClassLoader cl) + { + try + { + String name = PrivateLookupHelper.class.getName(); + byte[] classData = ByteStreams.toByteArray(ReflectUtil.class.getResourceAsStream("/" + name.replace('.', '/') + ".class")); + Class clazz = cl.defineClass0(name, classData, 0, classData.length); + + // force to run + clazz.getConstructor().newInstance(); + } + catch (IOException | ReflectiveOperationException e) + { + throw new RuntimeException("unable to install lookup helper", e); + } + } + + public static class PrivateLookupHelper + { + static + { + PrivateLookupableClassLoader pcl = (PrivateLookupableClassLoader) PrivateLookupHelper.class.getClassLoader(); + pcl.setLookup(MethodHandles.lookup()); + } + } } From e678c83ff987c589ec56e070d7a2cb221de90573 Mon Sep 17 00:00:00 2001 From: Noodleeater Date: Sat, 30 Jan 2021 20:37:02 +0000 Subject: [PATCH 32/53] added licence headers --- .../net/runelite/api/AbstractArchive.java | 48 +++++++++++++++++++ .../runelite/rs/api/RSAbstractArchive.java | 19 +++++++- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 runelite-api/src/main/java/net/runelite/api/AbstractArchive.java diff --git a/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java b/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java new file mode 100644 index 0000000000..f1aa2fd1b6 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, Noodleeater + * 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.api; + +/** + * Represents an archive of data, which is split split into "groups" of "files". + */ +public interface AbstractArchive extends IndexDataBase +{ + /** + * the methods bellow are usefull for reading byte data from the cache + */ + int getGroupCount(); + + byte[] getConfigData(int archiveId, int fileId); + + int[] getFileIds(int groupId); + + int[][] getFileIds(); + + byte[] getFile(int groupId, int fileId); + + int getGroupFileCount(int groupId); + + int[] getFileCounts(); +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java index fe3f6c7003..a9aaed036e 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java @@ -1,9 +1,10 @@ package net.runelite.rs.api; +import net.runelite.api.AbstractArchive; import net.runelite.api.IndexDataBase; import net.runelite.mapping.Import; -public interface RSAbstractArchive extends IndexDataBase +public interface RSAbstractArchive extends IndexDataBase, AbstractArchive { @Import("takeFile") byte[] getConfigData(int archiveId, int fileId); @@ -11,4 +12,20 @@ public interface RSAbstractArchive extends IndexDataBase @Import("getGroupFileIds") @Override int[] getFileIds(int group); + + @Import("groupCount") + int getGroupCount(); + + @Import("fileIds") + int[][] getFileIds(); + + @Import("getFile") + byte[] getFile(int var1, int var2); + + @Import("getGroupFileCount") + + int getGroupFileCount(int var1); + + @Import("fileCounts") + int[] getFileCounts(); } From 9f1ed6d6de98083f85735fb2ca1bd027e8703824 Mon Sep 17 00:00:00 2001 From: Noodleeater Date: Sat, 30 Jan 2021 20:37:45 +0000 Subject: [PATCH 33/53] added licence headers --- .../src/main/java/net/runelite/api/AbstractArchive.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java b/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java index f1aa2fd1b6..0be27dfa46 100644 --- a/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java +++ b/runelite-api/src/main/java/net/runelite/api/AbstractArchive.java @@ -25,7 +25,7 @@ package net.runelite.api; /** - * Represents an archive of data, which is split split into "groups" of "files". + * Represents an archive of data, which is ordered into "groups" of "files". */ public interface AbstractArchive extends IndexDataBase { From 9d09bb722ef019a8ce7c7128bf7910e9d4837d3e Mon Sep 17 00:00:00 2001 From: Noodleeater Date: Sat, 30 Jan 2021 20:51:13 +0000 Subject: [PATCH 34/53] added @overide annotations --- .../main/java/net/runelite/rs/api/RSAbstractArchive.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java index a9aaed036e..d15f48a266 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java @@ -14,18 +14,22 @@ public interface RSAbstractArchive extends IndexDataBase, AbstractArchive int[] getFileIds(int group); @Import("groupCount") + @Override int getGroupCount(); @Import("fileIds") + @Override int[][] getFileIds(); @Import("getFile") + @Override byte[] getFile(int var1, int var2); @Import("getGroupFileCount") - + @Override int getGroupFileCount(int var1); @Import("fileCounts") + @Override int[] getFileCounts(); } From e827167e30afc6feb1f26ec40803e660bdd76127 Mon Sep 17 00:00:00 2001 From: Noodleeater Date: Sat, 30 Jan 2021 20:56:01 +0000 Subject: [PATCH 35/53] renamed method parameters --- .../main/java/net/runelite/rs/api/RSAbstractArchive.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java index d15f48a266..bddfbe6f71 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java @@ -7,11 +7,12 @@ import net.runelite.mapping.Import; public interface RSAbstractArchive extends IndexDataBase, AbstractArchive { @Import("takeFile") + @Override byte[] getConfigData(int archiveId, int fileId); @Import("getGroupFileIds") @Override - int[] getFileIds(int group); + int[] getFileIds(int groupId); @Import("groupCount") @Override @@ -23,11 +24,11 @@ public interface RSAbstractArchive extends IndexDataBase, AbstractArchive @Import("getFile") @Override - byte[] getFile(int var1, int var2); + byte[] getFile(int groupId, int fileId); @Import("getGroupFileCount") @Override - int getGroupFileCount(int var1); + int getGroupFileCount(int groupId); @Import("fileCounts") @Override From 79b01e36fbbe26d57767102dc100f3152934b848 Mon Sep 17 00:00:00 2001 From: Noodleeater Date: Sat, 30 Jan 2021 22:14:41 +0000 Subject: [PATCH 36/53] added api to get cache archives --- .../main/java/net/runelite/api/Client.java | 25 +++++++++++ .../java/net/runelite/rs/api/RSClient.java | 45 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index a9709e9307..1d354616c2 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -2137,4 +2137,29 @@ public interface Client extends GameEngine void setOutdatedScript(String outdatedScript); List getOutdatedScripts(); + + /** + * various archives you might want to use for reading data from cache + */ + AbstractArchive getSequenceDefinition_skeletonsArchive(); + + AbstractArchive getSequenceDefinition_archive(); + + AbstractArchive getSequenceDefinition_animationsArchive(); + + AbstractArchive getNpcDefinition_archive(); + + AbstractArchive getObjectDefinition_modelsArchive(); + + AbstractArchive getObjectDefinition_archive(); + + AbstractArchive getItemDefinition_archive(); + + AbstractArchive getKitDefinition_archive(); + + AbstractArchive getKitDefinition_modelsArchive(); + + AbstractArchive getSpotAnimationDefinition_archive(); + + AbstractArchive getSpotAnimationDefinition_modelArchive(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 0b89c019da..dc923d6bd5 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -26,6 +26,7 @@ package net.runelite.rs.api; import java.math.BigInteger; import java.util.Map; +import net.runelite.api.AbstractArchive; import net.runelite.api.Client; import net.runelite.api.SpritePixels; import net.runelite.api.World; @@ -1350,4 +1351,48 @@ public interface RSClient extends RSGameEngine, Client RSIterableNodeHashTable newIterableNodeHashTable(int size); RSVarbitComposition getVarbitComposition(int id); + + @Override + @Import("SequenceDefinition_skeletonsArchive") + RSAbstractArchive getSequenceDefinition_skeletonsArchive(); + + @Override + @Import("SequenceDefinition_archive") + RSAbstractArchive getSequenceDefinition_archive(); + + @Override + @Import("SequenceDefinition_animationsArchive") + RSAbstractArchive getSequenceDefinition_animationsArchive(); + + @Override + @Import("NpcDefinition_archive") + AbstractArchive getNpcDefinition_archive(); + + @Override + @Import("ObjectDefinition_modelsArchive") + AbstractArchive getObjectDefinition_modelsArchive(); + + @Override + @Import("ObjectDefinition_archive") + RSAbstractArchive getObjectDefinition_archive(); + + @Override + @Import("ItemDefinition_archive") + RSAbstractArchive getItemDefinition_archive(); + + @Override + @Import("KitDefinition_archive") + AbstractArchive getKitDefinition_archive(); + + @Override + @Import("KitDefinition_modelsArchive") + AbstractArchive getKitDefinition_modelsArchive(); + + @Override + @Import("SpotAnimationDefinition_archive") + AbstractArchive getSpotAnimationDefinition_archive(); + + @Override + @Import("SpotAnimationDefinition_modelArchive") + AbstractArchive getSpotAnimationDefinition_modelArchive(); } From 8acd6ff097f98af811903da7aa61d8d918a2941a Mon Sep 17 00:00:00 2001 From: Noodleeater Date: Sat, 30 Jan 2021 23:15:37 +0000 Subject: [PATCH 37/53] added api to create and write to byte buffers --- .../main/java/net/runelite/api/Buffer.java | 50 +++++++++++++++++++ .../main/java/net/runelite/api/Client.java | 5 ++ .../java/net/runelite/rs/api/RSBuffer.java | 27 +++++++++- .../java/net/runelite/rs/api/RSClient.java | 3 ++ 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 runelite-api/src/main/java/net/runelite/api/Buffer.java diff --git a/runelite-api/src/main/java/net/runelite/api/Buffer.java b/runelite-api/src/main/java/net/runelite/api/Buffer.java new file mode 100644 index 0000000000..1aa2acaf76 --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/Buffer.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020, Noodleeater + * 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.api; + +/** + * Represents a byte buffer + */ +public interface Buffer extends Node +{ + /** + * Use this api to write to byte buffers + */ + byte[] getPayload(); + + int getOffset(); + + void writeByte(int var1); + + void writeShort(int var1); + + void writeMedium(int var1); + + void writeInt(int var1); + + void writeLong(long var1); + + void writeStringCp1252NullTerminated(String string); +} diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 1d354616c2..5d548fb2ae 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -2162,4 +2162,9 @@ public interface Client extends GameEngine AbstractArchive getSpotAnimationDefinition_archive(); AbstractArchive getSpotAnimationDefinition_modelArchive(); + + /** + * use createBuffer to create a new byte buffer + */ + Buffer createBuffer(byte[] initialBytes); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSBuffer.java b/runescape-api/src/main/java/net/runelite/rs/api/RSBuffer.java index b43e772f62..3772548707 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSBuffer.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSBuffer.java @@ -1,12 +1,37 @@ package net.runelite.rs.api; +import net.runelite.api.Buffer; import net.runelite.mapping.Import; -public interface RSBuffer extends RSNode +public interface RSBuffer extends Buffer, RSNode { @Import("array") byte[] getPayload(); @Import("offset") int getOffset(); + + @Import("writeByte") + @Override + void writeByte(int var1); + + @Import("writeShort") + @Override + void writeShort(int var1); + + @Import("writeMedium") + @Override + void writeMedium(int var1); + + @Import("writeInt") + @Override + void writeInt(int var1); + + @Import("writeLong") + @Override + void writeLong(long var1); + + @Import("writeStringCp1252NullTerminated") + @Override + void writeStringCp1252NullTerminated(String string); } \ No newline at end of file diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index dc923d6bd5..66318eef50 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -1395,4 +1395,7 @@ public interface RSClient extends RSGameEngine, Client @Override @Import("SpotAnimationDefinition_modelArchive") AbstractArchive getSpotAnimationDefinition_modelArchive(); + + @Construct + RSBuffer createBuffer(byte[] bytes); } From 941189c82d91ef0e1d8cdae24c2f5840ea8120ef Mon Sep 17 00:00:00 2001 From: Noodleeater Date: Sat, 30 Jan 2021 23:31:36 +0000 Subject: [PATCH 38/53] added api to create and write to byte buffers --- runelite-api/src/main/java/net/runelite/api/Buffer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/Buffer.java b/runelite-api/src/main/java/net/runelite/api/Buffer.java index 1aa2acaf76..384b3cacc8 100644 --- a/runelite-api/src/main/java/net/runelite/api/Buffer.java +++ b/runelite-api/src/main/java/net/runelite/api/Buffer.java @@ -29,13 +29,13 @@ package net.runelite.api; */ public interface Buffer extends Node { - /** - * Use this api to write to byte buffers - */ byte[] getPayload(); int getOffset(); + /** + * Use this api to write to byte buffers + */ void writeByte(int var1); void writeShort(int var1); From ca56ef10823aea1ecd275c0d3c3f9a3b17838ff9 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 30 Jan 2021 13:14:33 -0500 Subject: [PATCH 39/53] Apply default font to text with unicode characters MacOS does not support fallback fonts, and any character not in our RS fonts do not render correctly. We only render unicode characters a handful of places, mostly for the check mark/cross in overlays, and on the icon text field suggestion button. So this sets the font of those places to the default system font which can render them correctly. --- .../barrows/BarrowsBrotherSlainOverlay.java | 2 ++ .../plugins/cluescrolls/clues/EmoteClue.java | 5 ++- .../cluescrolls/clues/FaloTheBardClue.java | 2 ++ .../cluescrolls/clues/SkillChallengeClue.java | 18 +++++----- .../net/runelite/client/ui/FontManager.java | 36 +++++++++---------- .../client/ui/components/IconTextField.java | 9 ++--- .../ui/overlay/components/LineComponent.java | 30 +++++++++++----- .../ui/overlay/components/TextComponent.java | 24 ++++++++++++- 8 files changed, 83 insertions(+), 43 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java index c7cdef0058..4e4eba0175 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsBrotherSlainOverlay.java @@ -34,6 +34,7 @@ import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; import net.runelite.api.Varbits; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.ui.FontManager; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPanel; @@ -82,6 +83,7 @@ public class BarrowsBrotherSlainOverlay extends OverlayPanel panelComponent.getChildren().add(LineComponent.builder() .left(brother.getName()) .right(slain) + .rightFont(FontManager.getDefaultFont()) .rightColor(brotherSlain ? Color.GREEN : Color.RED) .build()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java index b59be0da14..ab3ac38982 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java @@ -45,6 +45,7 @@ import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldPoint; import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; +import static net.runelite.client.plugins.cluescrolls.clues.Enemy.*; import net.runelite.client.plugins.cluescrolls.clues.emote.Emote; import static net.runelite.client.plugins.cluescrolls.clues.emote.Emote.*; import static net.runelite.client.plugins.cluescrolls.clues.emote.Emote.BULL_ROARER; @@ -53,7 +54,7 @@ import static net.runelite.client.plugins.cluescrolls.clues.emote.STASHUnit.*; import static net.runelite.client.plugins.cluescrolls.clues.emote.STASHUnit.SHANTAY_PASS; import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement; import static net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirements.*; -import static net.runelite.client.plugins.cluescrolls.clues.Enemy.*; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -258,6 +259,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu panelComponent.getChildren().add(LineComponent.builder() .left("STASH Unit:") .right(stashUnitBuilt ? UNICODE_CHECK_MARK : UNICODE_BALLOT_X) + .rightFont(FontManager.getDefaultFont()) .rightColor(stashUnitBuilt ? Color.GREEN : Color.RED) .build()); } @@ -292,6 +294,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu .left(requirement.getCollectiveName(client)) .leftColor(TITLED_CONTENT_COLOR) .right(combinedFulfilled ? UNICODE_CHECK_MARK : UNICODE_BALLOT_X) + .rightFont(FontManager.getDefaultFont()) .rightColor(equipmentFulfilled ? Color.GREEN : (combinedFulfilled ? Color.ORANGE : Color.RED)) .build()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java index 16974ffd16..c208d5238f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/FaloTheBardClue.java @@ -41,6 +41,7 @@ import net.runelite.client.plugins.cluescrolls.clues.item.AnyRequirementCollecti import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement; import net.runelite.client.plugins.cluescrolls.clues.item.RangeItemRequirement; import net.runelite.client.plugins.cluescrolls.clues.item.SingleItemRequirement; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -134,6 +135,7 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl .left(requirement.getCollectiveName(plugin.getClient())) .leftColor(TITLED_CONTENT_COLOR) .right(inventoryFulfilled ? "\u2713" : "\u2717") + .rightFont(FontManager.getDefaultFont()) .rightColor(inventoryFulfilled ? Color.GREEN : Color.RED) .build()); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java index 67de8ad26a..41f6f283cb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java @@ -25,6 +25,11 @@ package net.runelite.client.plugins.cluescrolls.clues; import com.google.common.collect.ImmutableSet; +import java.awt.Color; +import java.awt.Graphics2D; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @@ -34,25 +39,21 @@ import net.runelite.api.ItemID; import net.runelite.api.NPC; import net.runelite.api.Point; import net.runelite.api.TileObject; +import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_BORDER_COLOR; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_FILL_COLOR; import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_HOVER_BORDER_COLOR; +import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; import net.runelite.client.plugins.cluescrolls.clues.item.AnyRequirementCollection; -import static net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirements.*; import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement; +import static net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirements.*; import net.runelite.client.plugins.cluescrolls.clues.item.SingleItemRequirement; +import net.runelite.client.ui.FontManager; import net.runelite.client.ui.overlay.OverlayUtil; import net.runelite.client.ui.overlay.components.LineComponent; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.TitleComponent; -import java.awt.Color; -import java.awt.Graphics2D; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR; -import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET; @Getter public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, NamedObjectClueScroll @@ -379,6 +380,7 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam .left(requirement.getCollectiveName(plugin.getClient())) .leftColor(TITLED_CONTENT_COLOR) .right(combinedFulfilled ? "\u2713" : "\u2717") + .rightFont(FontManager.getDefaultFont()) .rightColor(equipmentFulfilled || (combinedFulfilled && !requireEquipped) ? Color.GREEN : (combinedFulfilled ? Color.ORANGE : Color.RED)) .build()); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java index 564ebcba62..5305506a41 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/FontManager.java @@ -24,17 +24,25 @@ */ package net.runelite.client.ui; -import javax.swing.text.StyleContext; import java.awt.Font; import java.awt.FontFormatException; import java.awt.GraphicsEnvironment; import java.io.IOException; +import javax.swing.text.StyleContext; +import lombok.Getter; public class FontManager { + @Getter private static final Font runescapeFont; + @Getter private static final Font runescapeSmallFont; + @Getter private static final Font runescapeBoldFont; + @Getter + private static final Font defaultFont; + @Getter + private static final Font defaultBoldFont; static { @@ -48,7 +56,7 @@ public class FontManager ge.registerFont(font); runescapeFont = StyleContext.getDefaultStyleContext() - .getFont(font.getName(), Font.PLAIN, 16); + .getFont(font.getName(), Font.PLAIN, 16); ge.registerFont(runescapeFont); Font smallFont = Font.createFont(Font.TRUETYPE_FONT, @@ -57,16 +65,16 @@ public class FontManager ge.registerFont(smallFont); runescapeSmallFont = StyleContext.getDefaultStyleContext() - .getFont(smallFont.getName(), Font.PLAIN, 16); + .getFont(smallFont.getName(), Font.PLAIN, 16); ge.registerFont(runescapeSmallFont); Font boldFont = Font.createFont(Font.TRUETYPE_FONT, - FontManager.class.getResourceAsStream("runescape_bold.ttf")) - .deriveFont(Font.BOLD, 16); + FontManager.class.getResourceAsStream("runescape_bold.ttf")) + .deriveFont(Font.BOLD, 16); ge.registerFont(boldFont); runescapeBoldFont = StyleContext.getDefaultStyleContext() - .getFont(boldFont.getName(), Font.BOLD, 16); + .getFont(boldFont.getName(), Font.BOLD, 16); ge.registerFont(runescapeBoldFont); } catch (FontFormatException ex) @@ -77,20 +85,8 @@ public class FontManager { throw new RuntimeException("Font file not found.", ex); } - } - public static Font getRunescapeFont() - { - return runescapeFont; - } - - public static Font getRunescapeSmallFont() - { - return runescapeSmallFont; - } - - public static Font getRunescapeBoldFont() - { - return runescapeBoldFont; + defaultFont = new Font(Font.DIALOG, Font.PLAIN, 16); + defaultBoldFont = new Font(Font.DIALOG, Font.BOLD, 16); } } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java b/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java index cb317b8afd..b4c2ff1127 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/components/IconTextField.java @@ -29,6 +29,7 @@ package net.runelite.client.ui.components; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; @@ -125,7 +126,7 @@ public class IconTextField extends JPanel textField.addMouseListener(hoverEffect); innerTxt.addMouseListener(hoverEffect); - clearButton = createRHSButton(ColorScheme.PROGRESS_ERROR_COLOR, Color.PINK); + clearButton = createRHSButton(ColorScheme.PROGRESS_ERROR_COLOR, Color.PINK, FontManager.getRunescapeBoldFont()); clearButton.setText("×"); clearButton.addActionListener(evt -> { @@ -192,7 +193,7 @@ public class IconTextField extends JPanel } }); - suggestionButton = createRHSButton(ColorScheme.LIGHT_GRAY_COLOR, ColorScheme.MEDIUM_GRAY_COLOR); + suggestionButton = createRHSButton(ColorScheme.LIGHT_GRAY_COLOR, ColorScheme.MEDIUM_GRAY_COLOR, FontManager.getDefaultBoldFont()); suggestionButton.setText("▾"); suggestionButton.addActionListener(e -> { @@ -237,11 +238,11 @@ public class IconTextField extends JPanel add(rhsButtons, BorderLayout.EAST); } - private JButton createRHSButton(Color fg, Color rollover) + private JButton createRHSButton(Color fg, Color rollover, Font font) { JButton b = new JButton(); b.setPreferredSize(new Dimension(30, 0)); - b.setFont(FontManager.getRunescapeBoldFont()); + b.setFont(font); b.setBorder(null); b.setRolloverEnabled(true); SwingUtil.removeButtonDecorations(b); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java index 20638e7874..83c67c09e0 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/LineComponent.java @@ -28,6 +28,7 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Strings; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; @@ -50,6 +51,10 @@ public class LineComponent implements LayoutableRenderableEntity @Builder.Default private Color rightColor = Color.WHITE; + private Font leftFont; + + private Font rightFont; + @Builder.Default private Point preferredLocation = new Point(); @@ -67,13 +72,16 @@ public class LineComponent implements LayoutableRenderableEntity final String left = MoreObjects.firstNonNull(this.left, ""); final String right = MoreObjects.firstNonNull(this.right, ""); - final FontMetrics metrics = graphics.getFontMetrics(); + final Font leftFont = MoreObjects.firstNonNull(this.leftFont, graphics.getFont()); + final Font rightFont = MoreObjects.firstNonNull(this.rightFont, graphics.getFont()); + final FontMetrics lfm = graphics.getFontMetrics(leftFont), rfm = graphics.getFontMetrics(rightFont); + final int fmHeight = Math.max(lfm.getHeight(), rfm.getHeight()); final int baseX = preferredLocation.x; - final int baseY = preferredLocation.y + metrics.getHeight(); + final int baseY = preferredLocation.y + fmHeight; int x = baseX; int y = baseY; - final int leftFullWidth = getLineWidth(left, metrics); - final int rightFullWidth = getLineWidth(right, metrics); + final int leftFullWidth = getLineWidth(left, lfm); + final int rightFullWidth = getLineWidth(right, rfm); final TextComponent textComponent = new TextComponent(); if (preferredSize.width < leftFullWidth + rightFullWidth) @@ -87,8 +95,8 @@ public class LineComponent implements LayoutableRenderableEntity leftSmallWidth -= rightSmallWidth; } - final String[] leftSplitLines = lineBreakText(left, leftSmallWidth, metrics); - final String[] rightSplitLines = lineBreakText(right, rightSmallWidth, metrics); + final String[] leftSplitLines = lineBreakText(left, leftSmallWidth, lfm); + final String[] rightSplitLines = lineBreakText(right, rightSmallWidth, rfm); int lineCount = Math.max(leftSplitLines.length, rightSplitLines.length); @@ -100,19 +108,21 @@ public class LineComponent implements LayoutableRenderableEntity textComponent.setPosition(new Point(x, y)); textComponent.setText(leftText); textComponent.setColor(leftColor); + textComponent.setFont(leftFont); textComponent.render(graphics); } if (i < rightSplitLines.length) { final String rightText = rightSplitLines[i]; - textComponent.setPosition(new Point(x + preferredSize.width - getLineWidth(rightText, metrics), y)); + textComponent.setPosition(new Point(x + preferredSize.width - getLineWidth(rightText, rfm), y)); textComponent.setText(rightText); textComponent.setColor(rightColor); + textComponent.setFont(rightFont); textComponent.render(graphics); } - y += metrics.getHeight(); + y += fmHeight; } final Dimension dimension = new Dimension(preferredSize.width, y - baseY); @@ -126,6 +136,7 @@ public class LineComponent implements LayoutableRenderableEntity textComponent.setPosition(new Point(x, y)); textComponent.setText(left); textComponent.setColor(leftColor); + textComponent.setFont(leftFont); textComponent.render(graphics); } @@ -134,10 +145,11 @@ public class LineComponent implements LayoutableRenderableEntity textComponent.setPosition(new Point(x + preferredSize.width - rightFullWidth, y)); textComponent.setText(right); textComponent.setColor(rightColor); + textComponent.setFont(rightFont); textComponent.render(graphics); } - y += metrics.getHeight(); + y += fmHeight; final Dimension dimension = new Dimension(preferredSize.width, y - baseY); bounds.setLocation(preferredLocation); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java index 45326fea28..0b6054a466 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/TextComponent.java @@ -26,10 +26,12 @@ package net.runelite.client.ui.overlay.components; import java.awt.Color; import java.awt.Dimension; +import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; import java.util.regex.Pattern; +import javax.annotation.Nullable; import lombok.Setter; import net.runelite.client.ui.overlay.RenderableEntity; import net.runelite.client.util.ColorUtil; @@ -45,10 +47,22 @@ public class TextComponent implements RenderableEntity private Point position = new Point(); private Color color = Color.WHITE; private boolean outline; + /** + * The text font. + */ + @Nullable + private Font font; @Override public Dimension render(Graphics2D graphics) { + Font originalFont = null; + if (font != null) + { + originalFont = graphics.getFont(); + graphics.setFont(font); + } + final FontMetrics fontMetrics = graphics.getFontMetrics(); if (COL_TAG_PATTERN_W_LOOKAHEAD.matcher(text).find()) @@ -105,6 +119,14 @@ public class TextComponent implements RenderableEntity graphics.drawString(text, position.x, position.y); } - return new Dimension(fontMetrics.stringWidth(text), fontMetrics.getHeight()); + int width = fontMetrics.stringWidth(text); + int height = fontMetrics.getHeight(); + + if (originalFont != null) + { + graphics.setFont(originalFont); + } + + return new Dimension(width, height); } } From cdba2ef2977e3b477de3c079f7e7a34edb398248 Mon Sep 17 00:00:00 2001 From: Broooklyn <54762282+Broooklyn@users.noreply.github.com> Date: Sun, 31 Jan 2021 11:57:00 -0500 Subject: [PATCH 40/53] hotkey button: use default font --- .../java/net/runelite/client/plugins/config/HotkeyButton.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/HotkeyButton.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/HotkeyButton.java index 55b9160c5b..131aef04bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/HotkeyButton.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/HotkeyButton.java @@ -32,6 +32,7 @@ import javax.swing.JButton; import lombok.Getter; import net.runelite.client.config.Keybind; import net.runelite.client.config.ModifierlessKeybind; +import net.runelite.client.ui.FontManager; class HotkeyButton extends JButton { @@ -40,6 +41,7 @@ class HotkeyButton extends JButton public HotkeyButton(Keybind value, boolean modifierless) { + setFont(FontManager.getDefaultFont().deriveFont(12.f)); setValue(value); addMouseListener(new MouseAdapter() { From ab4bb3bc977820fcdefc058c0cacd7277e3c9324 Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 31 Jan 2021 12:34:00 -0500 Subject: [PATCH 41/53] Revert "runelite-client: Don't use system specific modifier key names" This reverts commit 962bc58178503ee8ffcd0890b3b2882370ffd5eb. --- .../net/runelite/client/config/Keybind.java | 29 +------------------ 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/Keybind.java b/runelite-client/src/main/java/net/runelite/client/config/Keybind.java index e7e338a6b3..eba500b859 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/Keybind.java +++ b/runelite-client/src/main/java/net/runelite/client/config/Keybind.java @@ -159,7 +159,7 @@ public class Keybind String mod = ""; if (modifiers != 0) { - mod = getModifiersExText(modifiers); + mod = InputEvent.getModifiersExText(modifiers); } if (mod.isEmpty() && key.isEmpty()) @@ -177,33 +177,6 @@ public class Keybind return mod; } - public static String getModifiersExText(int modifiers) - { - StringBuilder buf = new StringBuilder(); - if ((modifiers & InputEvent.META_DOWN_MASK) != 0) - { - buf.append("Meta+"); - } - if ((modifiers & InputEvent.CTRL_DOWN_MASK) != 0) - { - buf.append("Ctrl+"); - } - if ((modifiers & InputEvent.ALT_DOWN_MASK) != 0) - { - buf.append("Alt+"); - } - if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) - { - buf.append("Shift+"); - } - - if (buf.length() > 0) - { - buf.setLength(buf.length() - 1); // remove trailing '+' - } - return buf.toString(); - } - @Nullable public static Integer getModifierForKeyCode(int keyCode) { From fe01c7dbf4a421c885787cec95c06fed5e168320 Mon Sep 17 00:00:00 2001 From: Psikoi Date: Sun, 31 Jan 2021 19:15:54 +0000 Subject: [PATCH 42/53] Resize and tweak hiscores boss icons --- .../plugins/hiscore/bosses/abyssal_sire.png | Bin 876 -> 687 bytes .../plugins/hiscore/bosses/alchemical_hydra.png | Bin 435 -> 366 bytes .../plugins/hiscore/bosses/barrows_chests.png | Bin 272 -> 251 bytes .../client/plugins/hiscore/bosses/bryophyta.png | Bin 594 -> 493 bytes .../client/plugins/hiscore/bosses/callisto.png | Bin 364 -> 315 bytes .../client/plugins/hiscore/bosses/cerberus.png | Bin 291 -> 276 bytes .../hiscore/bosses/chambers_of_xeric.png | Bin 518 -> 398 bytes .../bosses/chambers_of_xeric_challenge_mode.png | Bin 510 -> 358 bytes .../plugins/hiscore/bosses/chaos_elemental.png | Bin 471 -> 341 bytes .../plugins/hiscore/bosses/chaos_fanatic.png | Bin 515 -> 371 bytes .../hiscore/bosses/commander_zilyana.png | Bin 616 -> 497 bytes .../plugins/hiscore/bosses/corporeal_beast.png | Bin 861 -> 600 bytes .../hiscore/bosses/crazy_archaeologist.png | Bin 863 -> 568 bytes .../plugins/hiscore/bosses/dagannoth_prime.png | Bin 384 -> 336 bytes .../plugins/hiscore/bosses/dagannoth_rex.png | Bin 382 -> 338 bytes .../hiscore/bosses/dagannoth_supreme.png | Bin 352 -> 317 bytes .../hiscore/bosses/deranged_archaeologist.png | Bin 368 -> 323 bytes .../plugins/hiscore/bosses/general_graardor.png | Bin 531 -> 430 bytes .../plugins/hiscore/bosses/giant_mole.png | Bin 422 -> 357 bytes .../hiscore/bosses/grotesque_guardians.png | Bin 332 -> 288 bytes .../client/plugins/hiscore/bosses/hespori.png | Bin 478 -> 399 bytes .../plugins/hiscore/bosses/kalphite_queen.png | Bin 422 -> 364 bytes .../hiscore/bosses/king_black_dragon.png | Bin 331 -> 304 bytes .../client/plugins/hiscore/bosses/kraken.png | Bin 351 -> 294 bytes .../client/plugins/hiscore/bosses/kreearra.png | Bin 407 -> 343 bytes .../plugins/hiscore/bosses/kril_tsutsaroth.png | Bin 549 -> 449 bytes .../client/plugins/hiscore/bosses/mimic.png | Bin 403 -> 363 bytes .../client/plugins/hiscore/bosses/nightmare.png | Bin 609 -> 492 bytes .../client/plugins/hiscore/bosses/obor.png | Bin 627 -> 389 bytes .../client/plugins/hiscore/bosses/sarachnis.png | Bin 488 -> 409 bytes .../client/plugins/hiscore/bosses/scorpia.png | Bin 333 -> 282 bytes .../client/plugins/hiscore/bosses/skotizo.png | Bin 473 -> 382 bytes .../hiscore/bosses/the_corrupted_gauntlet.png | Bin 546 -> 419 bytes .../plugins/hiscore/bosses/the_gauntlet.png | Bin 618 -> 510 bytes .../plugins/hiscore/bosses/theatre_of_blood.png | Bin 613 -> 487 bytes .../bosses/thermonuclear_smoke_devil.png | Bin 543 -> 462 bytes .../client/plugins/hiscore/bosses/tzkal_zuk.png | Bin 583 -> 370 bytes .../client/plugins/hiscore/bosses/tztok_jad.png | Bin 315 -> 292 bytes .../client/plugins/hiscore/bosses/venenatis.png | Bin 378 -> 341 bytes .../client/plugins/hiscore/bosses/vetion.png | Bin 391 -> 347 bytes .../client/plugins/hiscore/bosses/vorkath.png | Bin 597 -> 478 bytes .../plugins/hiscore/bosses/wintertodt.png | Bin 873 -> 759 bytes .../client/plugins/hiscore/bosses/zalcano.png | Bin 485 -> 407 bytes .../client/plugins/hiscore/bosses/zulrah.png | Bin 374 -> 346 bytes 44 files changed, 0 insertions(+), 0 deletions(-) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/abyssal_sire.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/abyssal_sire.png index 0209db1f974818c6d8638e7ba7f39c3f860ca2b8..c5b238a9d09d126105b1e6ee9bea13ffd60eb814 100644 GIT binary patch literal 687 zcmeAS@N?(olHy`uVBq!ia0vp^5Xfq~I0z$e5N$R!mR=;%1w*jO4F zadNPm8XAfU3lwGe6r_1uo0*yF=%{OI8mOr$$V$sfNbvD+vokaMdAMi9ySg|yT3A|| znwt3==&30yYpKaZ$xHi7OEgas6cXUEbK=et;Yt#flaB~WD^Y(Ui zceAl~@V2#0PquNevNAKU3iL9|Ha75M(08`gP14g2*3oj)(zGyBk5N)swdI=CqK76-(xaS&*%d8UuPb< z_NTkq3|btHP50?AKJu2)tl{9#n!npu7RUy$Fr1$^RW)@X%i4~R17&{m=G91hFWt`@ zIm@!O%>C_=jca%Ie^2^*V&i#RLnqY-~l?XJ9fWy=#Wc|FN8`_3xMsy)kBJnL6) zQCgNVVRMDW{(Td@mwMhfxKlzgWJSn(?n&#^J*Irx&to=GF?I8f70Q;42^Yj|ug;w+ zv}vE(hN}weOt${I@tk`{rDn5y+=IloFQu3YzkN8>%02(P{tAheKj%zKwfn&=yS#fF g+a>i>M^8)Z|7XP%cJeCEZ3QJePgg&ebxsLQ0P8Q(s{jB1 literal 876 zcmeAS@N?(olHy`uVBq!ia0vp^qChOd!3-orr?xRNFfjfI@Ck7Ra>)QpOpI|CzyZoxWQ8k(9+jEu6fT%ioow#LR5y1LrxvVq)8E-Vbn3=9%t0vxO?3bLYs zUS`I|#*VhOB0|E>wz@(BJib11YN{$`hK6<)7T&hDlLZ;vyuDqWoGmRaqd6H&w6)C) z3>P&6%*l8)7DOBXW(FB6c!RPHZe8O(NPc=PtwyaQEak7aXC5R0Jp?UmYI|8l>XX{eYBQk#3 z($Ut{?C$F6;^F4y{QezLYXN`oE%*2 z=$$=VL_T23{=JJguim|UyZ-+ALq|MIColIAWw0#2^+nQ{^D|vjdB)S# K&t;ucLK6Vl^XKCL diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/alchemical_hydra.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/alchemical_hydra.png index 3b708b7522d2f340a64f4887fdbf6355aa2880a7..b34ed9c93e42e60fb4816b7b895caba0284349dc 100644 GIT binary patch literal 366 zcmeAS@N?(olHy`uVBq!ia0vp^5NYw@Sgt!7}2vBiwNGg_%YHAHE zEB7rdvI-3gs;t(uvyZH6NzZK#tF8CU&JBska!E;Z^$0g`^U!efP_nW~?3&;hnBeIf zW9sB*n6W%M28EiZtDnm{r-UW| D))0vD literal 435 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+3?vf;>QaH!>Hwb**Z=?j1DO!uTUe}OZy%i_ z<&~3X>g%WB=8;q^8(3E1lV4yJ8WvPp9ah(%=H%>=mF=9IYUJe;(b(*kmTnszW8mfy zP*NJ*)E-)0YZD%kS}vQ@z96Z4LR5WgKys-=K%9+NgqFQSR?F;!j{b<+W}mnMr=TPa zBO47Hn}V|5wA`kUh%8Uv7*i)dB`cfChM7@ug>GI^t{!0y&VjZLzQvUjGV@wY7Orvz zI+VF2$S;_IVcKJnic(YU~go~+5qpNFoj+Wm4|EbfM zl#QQg7F(J7iY$$1j$~n&80*cVCA-L*<(7wez;+j*8GgKyDiY2sldWXAgqcl)g?1d3 z+}hZgyel+dPo!MBmciVa`vL`@*?bW5DV@gDV<6(V=9;5O?l$Y|{ef%MGwM0|mVZ|5 zTYq(Vl73V4q_oO7li%EjY%6U}U*Emc{gS#a_wKzLmgR^2S-5Nq_t_tM9@ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/barrows_chests.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/barrows_chests.png index 89ebe418dcc6662dc8ef41f6008ba24812aad3f2..1560f1aaaa10a428c0c440741e96c10241d9c98b 100644 GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^5|JxJDtM+tp43W5; ztiT{4I?=+Xe}aY6be0EQQ?}@7AFOcFOW!v0P=%JBp88~GQH50vbEZySD6@=DeEQYN zz6zopr05k$hxBvhE literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+3?vf;>QaG}Wq?nJ>;M1%flLVKZ%&-un_*(2 zJbz-2oSdkwt)`WQy1u@Gs;Y#91fQd$wzjski;KRer=hR6v0Hg}Ay6B0NswPK1H-h( zQlHiXxy_y~jv*44Q!hN^JFLLLl5jjXY^~__@AWqr)2FX}+<$U9H;3lZ=qV15eB)H^ z6e=EU-ssAtkk8tu;<$G0+r2VvDm__Oue@=Xkic_z%`e3>FQ=93K3($MWRHMB``I4G zCE_pbRbRxX7bP0l+XkKGNoSE diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/bryophyta.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/bryophyta.png index e64276d9caac5de32aaf29f7895afedc036da05a..68c4e2c90442d97822113cbfb9d64caffa734f90 100644 GIT binary patch literal 493 zcmeAS@N?(olHy`uVBq!ia0vp^5NbL>q32_C|n4r2fDn8!4IMS@B zCOE6aFDJw(BHSR(Rk5KvKE1#vGtMJE-8DPQHquEk#7;K1JTN)iBQ4S;DaoQD)*?3A zG|gMp)I?56L9BIRQbl7#bxue@l237iXHJ4=bc#zxiBm$TQ+S+1L7shbhIMU%Rb`}3 zafqh2zO1T-q>K!|hzPF`KSybOSbbqwX}W)Im0MS~LsP0vPJo7kgQ~8Mq>+wFQ4jTxt1mvHZAmX~peD#j+ z@4o!{KVOt_=Y&sZ(x1#}8wEb* SpRtPu`O?$X&t;ucLK6VZvb2T( literal 594 zcmeAS@N?(olHy`uVBq!ia0vp@KrF(+3?viZxXUsyFxmz9gt!8^qylLPfy8JFL4Gb) z7Usfeoyr7l4Gqb}D9hF?qoQcd{4`sAZRxxmmxff`%xJ@sVz0t{cR2-7b#=+KAdQrC zm-Kw^q%03zLq%aBp4=#-Xm2fd5AC2ZD>olw7G@?kHkO=J+n5kzFCV?U4DX0|2TM~m z8EL`79G{eUmmoj0q70wZSStxJ0X9|^QDK27f9t|zpNtsym_WPCcsBuR84+<&eqT4^5MK*EUQPooDMKCkq$sCQKMP550ajLK78Yh}Qzan*E{}qK zdtmShlmz(&Gdx&euu&i&;qt74319ma9O5>2*8t@qkczK@Y*x*#Tspu0|msgH}T=%A~RkL=n3AY?yvvTR$#jBT}=XNO=VKgt!7}2#}GIQdU&d*3>l8 z(^FSfb+WS)5fn5xGP1L@^zm@BGBfjXb#--eEX>PDh>VB{3rk6gi3|=73h+s`G>_EQ zY@U5F5@--pNswPK!?gVWzdeDx1)eUBAsXkmUN~9AtSG>ILE)K>woLKPc zyC+VwB+ps7>RnL5OcR$E$CN(yayQspt~yy#R_ypYzUK7DuZ6EJOGa+6`)69)KyhY^!260#eF^8>?|#n6%~`BBV)qC9BpjeoSfujWJCl7<0B#> zgM%ZrHN8AslP%4io$P}Gd{UBP@^jKl3bPm(7~fs(>jj$5ToU9L%)l`1vDByaK<-vg z7sn8Z%f1s{Pdlu@(K2~~%fu7gB)8wq{`}8Ba?8!)Y4#7E8z@~aIp*Zj{k-y@wP5QB z*?j_Q6;n0OtTCC8y=|*nx2k*TT;;0WF_-tHx2?=t+;=ZOTSL+C!mOp*TLdV$JYD@<);T3K F0Ra36hnfHY diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/cerberus.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/cerberus.png index 8d0802478387885cd93eaf406d7a88cec114df56..f7dc1f8047d9fe636209a75eee663d964dd8a376 100644 GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^5NI3=ggt!7}2#{xB@ZsYW6BJAl z=CtEvFyLg!7vs}lU{I5k?2;9T65EaloaenPYZ@$9{Jgkp5^5*^fd-wk;-B2^uu)ui&LQ=fb z-adTA@yS-!q3w$DjN8>qKL?@zf0MO+-}Pf3^|CEz@_#(cbgMV7 Q#v0@|Pgg&ebxsLQ0PMb93jhEB delta 280 zcmbQjw3w;BGr-TCmrII^fq{Y7)59eQNb>`+AO|y$G`+$$8At^N_=LFr|NkGz1Ohuw zh9n_QKR!+|A)zu!zF;BFG%-#WJ_dOPhI}zT15O4F1_nt!J{@@(HA%_xk{~ZW&Ic=H z_DztC5aMi;;p>$bGUsH772=#1dp?h0Vu5JA#AV+Jw}lQXaJZxf&T5%twsrfL|Mpv6 zEl_@Znz1aFx6$EgOJIV6AFqn%bXHl;*PB-I9J_kMrLAE?PWWEmrr(7&BFW69>ny+X zU3=cWRcuc3Ibq>@^I6i0`EFbiUq0^^Z{1O@4U_IDFN}SBUg5dyMqP)fUyB6h@Am)O ZW-oJ0uH+)DkaMp?2dn*B#LLXg($Xp^DOpof@A2{I>+6=HqtVva&eYYmzrWMi+2iKs$Ii~y+uP;o>Br5^ z!pX{{udjWDhpxD}thTqez`?n~!l<*fyTZiK)z*E6hir6p)!ErpPMzhs+w$SPJ z`l_r9hNH1Ff(ljp6Mm}ciXk&XFqNR(80roj9SkbIp|26%+Cn_t(wutlPb~eBMzxkS?ps#7b7AGC zIsKbwm9Cr7w4^t-yD~J*rR~_-q7{?#y2@n>iZfdZ!x{>tvT~BDvjR%fM5AJ23w-X^ z=g9zVWhx2s3uc&>|NplqkT=iM#W6(V{MHG_`C1HkTu$Eb=5bu zk#zELdbZlFr7TB|{pnrM;N5C4K~-QK<3G=gY+a=*Gv7R9oP3qfap}rv0mhKY*EaoR zth}8dC*Py>cuL!owyVN>-qkz1OU(bm__)YZ1Xzth;+b%719VbOQvjCKT+{!L0002JNklVHy~SNiad-Lu&tXfGmdPcXeQTLx%n%1Sv&6ySbp8>zKyupz zZjTr6`C)-TPzuT62<#nEDJJ3x*h`YBbVdm45=SP#V`W4?fn=yJ7QZ?-!yO6ctm=pIk!3w2Pc<9Z`MMeRNX zGr@x@NEHS6gt!7}2uKLe$xNt-3Q7z2 zPYLpl_jC?%vGY%kF3L}>KU9(*8)Yt}36oZr=78 z%1j^kdcF``qttnbc~;pB0kg#cWm}#s_^I>Nr&s9P_jvtl1u{jB2l7~=UwHg>@?5-X z(wPN82Sv7R+vnG~z{qb^fOz6e&0BrJLF~2HI0Y+SKYf^T_jK&0?+JfGv&6S6?Y5oU fUz;WP`~Op3brx3n<%={ML4o7x>gTe~DWM4f)3|>L literal 471 zcmeAS@N?(olHy`uVBq!ia0vp^{6H+g!3-q-bzC(AQqKc?LR|m<{|{sWfrV<|=InHJ zX{&3!ok12ALY&e!r%X6hlJBaQ8fad6y}x^7W}1(2o{pTu+Vms`otQIKr7KbsuCz9I z=x5}m)}_al$A{;H`=@3mRK|v6#)M=gM-_$pr{t&B2YJWE1ZM_##<|-0#{_4@g=UBQ zC40MsC5Go_Csidy7v`rmq{fyQ>)S*HrUm=NCxqpM2c%@gmnVehMhB%QMHNK`rTV!? zMFpq1+WQB4C&Y#4g!m--xS>vJ zI)^yh`kENnDDW>i2J|FTNswPK!?gVWzdeDxxt=bLAsp9z{jZ8O1qh_DGjFusAj%q@ z^XA5>CmPg?QMrVx{;8U2$&)`et$bqh|Lb0JGRYq|FKU(DJDGQC?*mYBus zgfDZraQ#=>?%VQxr%uk|$avmewfF8^VUGUiumAq6%}BekPyhXLUa8PGDq5h(@pScb JS?83{1OS#huo(aV diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_fanatic.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/chaos_fanatic.png index b27a0109358c901c0963a4727efc72884c74772e..b712e9b70a9cd1db051d4960ffc242668fee5aba 100644 GIT binary patch literal 371 zcmeAS@N?(olHy`uVBq!ia0vp^5NVNp`gt!7}QUN0)qraD@36rrZ zqY674n+v;(4TF`nxw#&bo&ckOFSD;Uqqdf+8Xpf2I|F+Zb5v|-XqdmBx0{=*gM$-; zgN2ESvA({ZjEaloaenCpbFsq)JkF{+kNY+5dNM8Uef|D3({@TeKCbLIAvajBqVq6U@r)lA zxok`q%(=|LtT4^Z_O;{JQ??~rP5g>qtlcW;5hmKea^Xp)oAt^3XoE*9c0Y7!=ULzR z=uX8?e&@ALTJY0zQgJb>WQ^T$+k@6U`>cX^4_R`#aWrV$DErHJ*^@(8 T&v?%%P|$h0`njxgN@xNAhtnz>VB*c@ZOUR|$6({c;Gn{! z!p6X+&#dRq;P1le?8@%q%I?a~$j{8c%)-pX#KPq7fpe^&JGkd*4O9b;jyu_^z-llDzY*&jSUTDW@ggU(e`$8FE=zSI1v!N z?(=D&{8CRB#}J9jy%&y(H3bN;J@Bq@b#Rg0y_@^!5wYF(|0kAk9(MZwwEUTm;3sXK z(;pvfl5P#K5b8a;(pPb!&r-$7tO>fW&OPNm8niQLEvMMmE7E7fc3*zmxV3r3SN2~5 zD#xyc%k`>n>bSP(@=V8xg70fKmMEBpWwS2M-+VVy%kJtO`4W4*seS5~8^6>r9#`qx ve~(EbbccP5LfF%vRhuO^YvR=>)qi6AWXQk2qEB)*C@MW&{an^LB{Ts5)KZ1- diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/commander_zilyana.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/commander_zilyana.png index bec91f5bc183edc8886564f7fc6642cedb2320e5..9f1d6d20cca73317ea4192b347d000e118b05b8d 100644 GIT binary patch literal 497 zcmV3{mCLY^!>EO{ntRc~c&U(cql<5zhig<+X@6{1 zwOduER8ON(OqEJSfImBIHZsG*%cG>kxw*rEg1wfOyxhyVkdd@|d$gjWt!-|iY;B*A zkei5zl7@zm*U5`^c7D^ueQ|MnY;1LEYH_uvXohlIn2c7MO-OrjMvO*6T1`EKLOp0R zFJUh(MIjz;6%LrId&&R+00MMUPE!DuZ~yyA0002MNkljx z3`&x2HnVZjp5=1sR3#2-%ZzKZYf*C{5m?x@MVBfr#3e@`8X*TA^}rC nufkg}xP81YBI|oZ^rv|OOlA(r7G5-900000NkvXXu0mjf+z{ik literal 616 zcmV-u0+;=XP)ox;X5r!G<>MDXh_DC>ac~HWh=R32M8w2dB_yS!Wmpip*kt8I`oRaAitW=4=h)YO4MLsLXcTSu3Lk%2`|-@wq&(8$=t)Xdz}0wiK-WvyYuX=H0> zug34-2oiB}c5!uebNBG@^z!!c1^R`>&(S|1Feo@AG%UnBJR*{X!PhE^g(W&BHZI;P zAu%c0nuUQSg@qYpe=19wS31agpzX|%&|n6085jZ3n;R(+>-l#80000Xfq_vlz$e5N$R!?3Xe}*2 zTRpF%x3QqMBqc7?i=U5&nVEUp%85&7G|!z-GqbmvBZJ&R z{G1ZJoKoHG{XA^_U2Gg}Ohc_q-R(^5tqjeLv@MKP)l?Le6{OXbrQ}3K&K=o!WaqL& zTj%dxKW)+UrsnFbwyLbk{Djiv_>!!c{Djby*nsRr_sl?de=j#5dvkve6Mu6fHwQfz zBW*VWZ97X%Qws*jTzM(KavIi9QZ#)K=cK-QSg*&*B4)E=|3X%EkcLWFgrQ( zhuY%if&*I=c1@mIrMS-KdW6gx#d)93eX6->a;EW|Uz4)hlm}Zhrm(&)%jhuL8eX*S zZaB*|$A?m1Za%;DWmVSKpKJcH7wvhx;oF`mS2H{wUH#3OcKYIXcHR^Hx6aE{Zj6rQ z>J#01Yv1Dz-4&{@q9u2h-z=RkC$;t7+1+zE6?-!-oeBHN+H4|ge6ZFw4U|4SUHx3v IIVCg!068k=k^lez literal 861 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9S!3-p~d(N$3U|{?g;1l8sw+r z#LvTyiIFir+-uFENwfQFG82PEg#|Pu5fvSJ*qO=omh)s&bdRvH_e$lv1ZrW zscYtUx;a^TyI4ufbKIf^!IYhPIQk64y?{dPIk2^O^$al(&p#m+r_hTB{2H= zOM?7@87@3f=wG(r>x4ZH2Lu8NY97{rQp|r(7sn8Z%gG4`SS5ZoHgLLj#5)9dM6^hH zwz#^4_{2C(67_6}_lj~0^NVX_J(T|Vd3Z?Bv+%&s;Oh_CJ3eM-Wxjs#>ZP=Vl;muU zPsU8GH++AdJ#$u9XYHEYoVP#T{%mxT;p_7|r?)Qeo!q>*dv^QgI4Gut+5c}iu;9Uj z3mZOkoY2slka#BWqT$BEjUPEXJx^)|SnmwJe972o^QNE0ML!e$&Y#xT(9zP<)YWe1 z4h;zly?*7|RdbU=Ejwn&z`{tB0$0?W(T&edf2i&m0!fM>B0wUu}6=`^-4) z+$>x6B<1&aDnEz7#Nc{=$32_C|lmmH5E^ZFy^a#Ch zS2WRF0zIFYw z^x%*4rmz83T=jHu4AD5hb%J}*AqN3hT?4k{$%$!GHn#{_KA&U!eLuHWnD0TMs_Xx+ zu77nsUS2|LmX}KN`Jd}=7+o#Wmf>WT`@~Sc#QTfebJ=NsoCP+$c(iFpwn^yQIgJWu zroDK3v^0B`>Vae1JESYOM`~s-`@sHrTe6gB>B2M1tlUHtPHZlzjCjF!OsBCy=;PH1 zR;~9k4n6-PVc_l5DKZEX+*u(p*6<;@-9r{*L^f_M%=6@?MULAs!koRRj} z(w=s55nfsu;TEYO#uJMDW>tm-+AGUTa4<0f0fV>@ru&^*Q8mY-9`j~jz zh)1}}2RTTq$nu7{$obhxsmSv9*h+~Daj>y69pMPc06IvuB*+h#95`dPzIk4k*48rH z$k=wyvThH57LH&>)9406y>ubB^-a?P#ZvYduK;Rz=jq}YB5^r6fq_XaO)Si;OrX0_ z(4}C-s+HLpS%pP~pBq>!ww9KB{ld%B+vDr=(}C$v+B30fVb{#Im3`x5Qebp+S5FrY zH!tV+*Uz88r6?b7|G(kDf(H{W7$h!`bb2T_G4P_{#=?)Bot`IsdU%vHS7vs;l$;rP z({g9!$wfUpK0jGoU5~0RO?@glHEEH9?xWDFrdvzD^7i_k)mLZep7HYopf=o+qeUUUy_w?*$4n1*Zp7Ly?@_T<+xy3yl|0pRRSI}D@u(jf3 tkn4=+4h}1`ZWg7cFfKU3B|3qD!CArjP0R(I6rj%;JYD@<);T3K0RTiJ;~fA1 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_prime.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_prime.png index 18e004e18b9f6a4137eeffa9471463f45ad60f9b..bc6612dbf421d80be5bfa7699506a382ed90040a 100644 GIT binary patch literal 336 zcmeAS@N?(olHy`uVBq!ia0vp^5NTmh%gt!7}2*@;6jZTgZiwP^U z)XvDyNXSSCj0ns(Q%}xLj*O4=3-Jqy3i0ssSXrqvJzLe))799*xZX~$+D2zliPnNb ztz-igFBK^#Hzx~Qi@Evgy{XD^dWxk%a?Xm9aZaM8C#pc!GnEAS1v5;`|Nq+)$eZrz z;uxZFervxw-(dqDma|hmM7`gc+W!BaGUtxYYmo!oA55$jwppmM1c*6k25kGUdUM|< z!38}BW<@^K2#I2goXFMZERem5Lwy=89kj@L>5Q$=HeZ{3ut2NxGQ)G{1zopr01&lz00000 literal 384 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3-oh+|s`Ssonse5ZC|z{{xvokZG)%n3?Dw z>K_&p7M&Cw5)~4Y8dGkiQ){c|p)45~5f~XC8J`}Xk)M%On3brn?BVN?oSp2WDxG7h z?it{jmYY^>qf=n6o@S_OXl__yp|!e7XGMk1f&vA-vI07VsU*lRm|}q&W`{)02Ne%7JGnd1{-(RV?r_YmcPv=1m+g8&NY|AcZzT12J!;06>xq0$$hj;K#<&rC!p6c~tuR{8Lk!AfW Z-*Mk@VZR%vdWanqik_~1F6*2Ung9p_kLUmZ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_rex.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_rex.png index 1b73c2d416676b4884d009716817ac74dabc8ca1..a18662f7024b2f3fc78163a5b72eeea9faa8d50a 100644 GIT binary patch literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^5NTmh%gt!7}2(Yy>%t;GNj`J_f zj;gLo%1jDLO$dmK^h${KP0LcPt4*yeOeimlj}G++^mX+2vM(&t&M8pO&yS1+q!l3d(?KZctGwg^ncv&&o!B0^hP}xa z+I=i`;a?3!i@eE988_LLPBVX5mwVSC@~PE1A?fGST8%Xs++V%B9Aob`^})PlZ|t2V zLYp$yy%tZ=6=u6qI$fH_EHu^DQ#dfOVlj)$#pOIM>MySR&T;zExJC7w@`2s)wW&UN aze43b1X!!~YwY_43K>sVKbLh*2~7Z3rg|*^ literal 382 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3-oh+|s`SsrCS$5ZC|z{{xvoP>>ZF9qN%B z=bxDr5)tH<5bc|t8d_DASXZ0s;b9dQ>6Mlcn42C^Q4n8Ml$f04Z);^3T3Q+x z7w6^bYVKrfEGjBgQ<@ywuC*PkcIS*58G1`)WVjoWi$!o3-?1cKN{S zm+La<5qszo}OsTJ9DaS!sB}TM}MSi YnZ>trtUI+cw-pqIp00i_>zopr09^E#?f?J) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_supreme.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/dagannoth_supreme.png index 721bd215e4c9646962dd8ad553799bb6805a3f05..4cb52e41563e8268ae248605fa3f19ab2f4ddc3e 100644 GIT binary patch literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^5NQDRZgt!7}2#~hYiAoI!iSr7G zat}-Jl{8gP%8keb9y=5NEVsI%q`?uTVyC&NKQ8Tk=5vz_%+?jf$7non_})%ChpY@=-NVAb7g^xvX literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3-oh+|s`SsnP(S5ZC|z{{xvoAZ?|SlpEn6 z;T96-6`AZGmf-6X>KvUG$fqnB80`_48IoQUolzQ>kR2+dCFkaEFRHIBX{zoS6reR;^Q1u9H)so|>ten5OFNW0PN^YHn-DDJ>-Dpf4mUwBS}= zJ8^O^RlV}Yi;Jw?+fv=^4bQNpc!?jn3<@PrS3j3^P6NQDIWgt!7}2ncm?@wTyE(OMYg z;Wn*2HPFGq&C)W)%X3p-<=W2DmW;@>pg?C+)7jNoojEZjF@8yYzUJE6OPcZ*HRjE$ z&2}&`$_Wq43JtL_Fo+R9AP+Q@sU*lRm|a=L;5v(IKV9w&v<_m0J~ zFF25*>GrBDqp9OfNcKa%Q~%jE-k+v;Kx6jJsOg`cahWrn@pxSmdKI;Vst0FqdHX8-^I literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}MSxF;E0Bf&XH!!*OUpn92TL8D zFjrSE8!KO1+b9pW7%xu;6QdAkr#K&y?A;>T622D@|Hpy1A`TiyHIRca@dK24sbX40v20Zn{`%Fwy+boCS;i|8M7OJGSiQ zrOA`uxlLRzu`&Puf%9u8FfbV|@hN0*bZu8@a{hk0p`Kyt74|h(U4uD5;pXY;=d#Wz Gp$Pzw@QRrL diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/general_graardor.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/general_graardor.png index f26ca05eca402a5c21078e5e88b81e5640928013..cefbc3c19b6588ad7f9bd6d1abab682d95100aee 100644 GIT binary patch literal 430 zcmeAS@N?(olHy`uVBq!ia0vp^5NUaO-32_C|5a3{Kol+bV6BCvg z6%`&Bm{6GznjIRL8tCik?h)dA;=r1g?9ABG*qE@en5+;-M;k3Gt;~vq^7y#$@W9{% zAAf&Ozi9V_SVxCI2UiCNZyRe%7jqjMa~pGW12whA#)|bT%T_Nfp3q%fT9T7pom8A3 zQyd$UoE#mM9u(;1m7e0};p`mZ?Bwd|5EEhRY-(z1U|?gVp`aiuB_SayC>ZF(>0!m$ zG5x+V(78+{L4Lsu)AIlS_5||Qdb&7V?_Vv1uzvO?0zVzaB00%APvt*o4EZCza*?Cq@rQUWa9EGrTdT640?;$n+q zV?vyre1WnK4t|~<4uK9jmO4$DX%Rs|VF3YwUS2`zL9yZCiBVA#x{E~x1+AP-!@>d- z6l9}ALp_|Gr6eR88!Jjna;gqa$pZS8xg^Lhn1Ny1W2sN;f!s5mE{-7*mvj4H7Bx8t zv_wjU3HN&(;9k7wnNla`>s%I5|E{QODQlX&27|_t6 z#<9vPQ>!<5Nkg2*bb)iu2F{xw&O067s1mA?aeY^!i1(s^H&4B;nq-@|ExazBs5mQZ z_04y8?%lPw343#Fvct8{-qZKZx;FdShPZf^i&8x7i$A9PvMaXjZ~bcYto!MW@8R<6 zf?LaBUs%`)e=^s^eL*nGu@r~mzXIEQ`znV*OM>-E2AYku+~uxOES27igHNTkN~ RJ@TMf^>p=fS?83{1OR0($rS(q diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/giant_mole.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/giant_mole.png index 5fb3f328e8c8971b09e187c56231478407d31c9f..48619319dce9ff0fecd9b01594894251eed4f7de 100644 GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^5NaY9kgt!7}2(U5L@~}5lRh0B~ zGS=5pbg?mr40N|NRM%0JHr7*dvd|G15y(miNsSJO3-t>1b@pjlosq+d$6`9N$+mOd(QUQFRVLvvUL|;^Kb+OmZz(q%Q~loCIEpQh3NnQ literal 422 zcmeAS@N?(olHy`uVBq!ia0vp^f} z>1!$Ks7k9UN{WgKSsAL^nrfNqDeGw|SH!r^n>X3XLdV0&sx95e)kfdb-q6>{*wx-V z)Ym!0!@|l`&rnbO+S<;$yXObEngdk?c{w@R7)J+r%qR`pvuD%huJniiH*-Us?R}XW zJJaGqz0zU=vlBx_g@iKWLz1KX7uLiSq($zTm^~psXzSKhXIFJx0y>MiB*-tAfnnNX zsZZ;H+-;sNjv*44eJ9)&YBJz)xve+NE8t=fqbLx(pZ@>9xwM4rcTLO9vptnuv{@at zPW|)Eas73}n_r_|8<^CZ88!APEwV64GmvrI)Y>7`Wh3c-@N9$5zbcvzW?wfg z>E%2yd7?pq=F1Dheu=Z5o;w{R@;d2R@eKWjJ5!$)ZJoF9mP5jB<~iD*cg4Lcv}pPs z%vBm{>O1*wo}k6t>pNnMYuNZADVgt!7}2+%jt4~`7Bu(iqTc*Ao}ynVs{-A>{T(XG5edutX?eER&htMUnp zV-Dve1rqh#oj4b2Nw1f2IJ-+hWW!#i7FX+n_ASaz=YvDyo6lywJt%FEeQwp&+fpW` z?sjf-;@mboIchtzeyZ<_1Wmc=6O!L>L@Apj*T*}sLQXv68A+A9B|Ns9$5(t7Kg0ytB zJp4So0=>*_%&qLL99$g?Obu+EY}GW>WEEshEKTwgRwkq;D5)qpdpNuKxP?ZC>KW-p zCr5|JhWm#2#-_$bB}Q>4OyU3<$6ONR7tFvg?XlFS^+4_tPZ!4!iOaDQZVNRl@VGRx zx&~z#Hm&{p|9{S*D;Ev*4=7H*D^c9ieEIM#;RDWz?w=-c95CQ|&5=Au$gy7T$Kok3 zHB+ucEkBW1bxB84e}RUu(Q{RS^&9!t=H*8;FMN7OMcE+AKV6FDN)XUHx3vIVCg!0HA1g`2YX_ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/hespori.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/hespori.png index 0c104674dbe6df264b138a22b26354cfb29d2ceb..a85a83ce3c9b4d8b527d65b8e6411307da3911cb 100644 GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^5NX-fG32_C|5D?<)yLCxbM_ta& z6}1}{lyz6d+FDrjHWhT&#}x-wt(slDd`98osrgYMAujgzhc>qCTh~|-TDNI&<+YHDC`-A{S~&~Z#9L4Lsu)AIlS z_5|`4c)B=-Xq;bq!CmOE0*^zWasgxb9q*jw-{<|lue+h=gVsOqdl_seX9+SYTz>Cu zr+L89OZVA<-=mF-x`HQS)GQFzG`rzo_3#D_;@cMR$7`X91uni8pK4-zM nLkvu3PF@PRe?dTYb7f7QjBAa8 za9dSXY-CnvUQ%^uP-k35cyC~piFS&BZi07aH83zZedDyRef+!b!|;^T|#0`Nk~{yQh;<;iG5v_h-Ha+U8I$7WnNuW zO--PZY@(EIr+R!~rogkrLzd5nNwv7vXjr+m4neZH=Nub_6js(!Vk zdQnPB!m)(s2NozT$?4NthH#6&Fm>2|rm=p*y?4JV`I4LG58zP~ U(`CLnBme*a07*qoM6N<$f|_5#U;qFB diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kalphite_queen.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kalphite_queen.png index 956e3a502d9fe18d57aa2cc692da9214ba109c42..c88f0bb4485af8e77a4801b2906758349f7d62b6 100644 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^5NRb_at)L*b(ER6rg-PE{MFmjQeB-rBQ+8V)LnyAV{=tPl9l$JDx9`Bw|ja@+vKDO z8>@gst*8tYBU>3~Ur8G`@vR4QHy_C9pOdj*O~Rbzv9p%OOq>($V``jStf3(z>3aY4 zcc86IB|(0{4Ab)e|Mmp(mUy~2hG?AMdf_JDAq4@}fSo+E%eJq*duRIp|1O7B*fMI2 zKH53@y%R|Lyq=@uz4;qK#yojJ?Hl(P%}T6Q7WZvAGw(uGhqijEygtKiQJGt7azws9 z*LLBm4eRfHX|zV+{O4|^AeB@ljrp#I63HiaXzDGT6tt?6v1^muas{RjNxG{R<}GnH z@!52sy+eE9;;q{rBu}lG-x|+m$ild#nB#WeS@XJc(g%9k`~+S`YJtMc)78&qol`;+ E0G2j~0RR91 literal 422 zcmV;X0a^ZuP)QfwPjsxBwA=B zRAM4PO(KewWN1f4V?;q^MMR*iU_D77V{<4;Stw9pDm6hIGCdqbQ6xG<7DrVlIz=7? zyE60u000AYQchC<0G8t#@~;2@0JBL%K~xyiP0-g8f-n#T(7?4Liir(lqr?^=p#1;0 znIhso?VQ<6_AVh^`S1zxJkK?*(1SDdTl6~{3<1j+jnTfH1k=zcX7jHRL<`E6D?J=_ zw%%;x9p(GOvHh3ebWYMN7ncN`U2pdX<(vjmYIGJqi=q@laG@$aYOR)1((nZoahg>c z&8jfS7~W-?O9jtnk``f#a~I1@Hci7|+Zt_DgLW5i{LTb4N`d^}$+6q{1M(pbjOx50 QyZ`_I07*qoM6N<$f}T31$^ZZW diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/king_black_dragon.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/king_black_dragon.png index 7efce3fe35e23d8305a2a42fe4aba621f5ead25e..c162208002d86654a9075123d9974daa23ae483d 100644 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^5NO=VKgt!7}2#}GKRFsnw6B1HW zR@TzcShHZk&UI@K?%1($>C&aMX6ota+_`aM)AHpj=FDC&ZQAUK6Q*``RTmdk78Vp_ zWCVD7t^FQ)2WSveNswPK!?gVWzdeDxsh%#5AsXkmPVnYCtia=PT3Xs;^1u4;`!jo` zTvc9en%lbZ8LwN~cX?Hh`#uvAn1yFO^?UVL?IzD0)`C2R{Y#`CTxoom^r>dbyh6W{ z#ox>;cV@K|zK~m(vYA~)8AeYQr=C8Bt`l>^sPupt7f@xUQ|BmX_Su*l=iQrkk3-wY8Os ziYh25n~{*Pq@=N>rMj=Ld2w*JtgED%n8UletDv7QEG&C-as=3s*8l(j19VbOQvd*# z;~Mg>0001*NklTD>5K*AxB@ID{Qbfn;ndC>MD55VUuNF@aLgt!7}2w2@C+FHuDxK*gL zg0CQxFF%nlJDMvdkh8y5sINq*xr(nnm#;pXuPmFdHk~iRmovzlGs1&&<=nYbD$3UP zi_UBp>S-35+aNTlLMSnsGclCY*PheUhSSBplnH17Q%R6tFvGO`|Gzzfykbum#}JM4 zXZ_uU8Vm%CmfWmf|NsBe%^wp^F;8J;k0?|4#lWKz!n6GY56=??PT?hjma{DNf)&b` zGOPu9924@LR=j#6wl}`^mI>E4<0nyKrSWNMiPpOwWY_)B%2NHQ;=-DKNTNH3?Rimg h_=e@DEp=fS?83{1OQC+V^IJA literal 351 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9Q!3-pIZrslUQjGyVA+G=b{|7Q5Ai|e(<=nY> zQG8i3oUJ*0F@cnEBVUu_&W3X`fG*q()n6z_}27@&TSCtDH2Kyzjo{K{ zsFO6)|EY;CSCrU`BwKEnOcjvb9XOkwyM{S oDR%C8xbA=LwoA;Ww-?oaWl#=ay=BfMDGmxFPgg&ebxsLQ0QOgVfB*mh diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kreearra.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kreearra.png index 0ef3398abf3c7852c16674016f4d47665fa5ec82..2bc96314764242724e04a310d27781a2bceef9ce 100644 GIT binary patch literal 343 zcmeAS@N?(olHy`uVBq!ia0vp^5NRZ$GJ{qp~1BA}}yB(x$7ip{=I+%(BwV#Kh-U_Lt`56lP@|NsJEk z_G-xWObfG03bA-{cFT?JeTU}eZ=8^po)8}&8M!AuVn%hCv%P(cziFt4zM`Dm(jQZE zfVMJ~1o;IsOw0fO+Y`v^_jGX#(Kx^LqC4MV10I$G87s5A!wP#Zzy3d8;-)#A{s$Qu70RLR|m<{|{tBKxchjQ&m-N zT3S>{NMB3Kq>he;T+bKR4xL$6dT4I`wC=8%{e4f)Zh3ZTPiA7`jNYD_l9I!T(R<<} zHcm(@%*v`P$j{HnxUs$OXj06K>ae=9vI%W%K|Veafr04>@m-A#4HXs6_V%SYIX%ry z0bZVpa&noGHu>@Pq5l4%9{OovRx$pjNg)>5$;qwN)$O%4@sW{Vc0RlVbR2U@kY6wZ z!?edzpVkApOFUg1LnJPTUWgQGG7w<7pfWeX!KHOYgZ82o513y3J)b7hdSU+hWof(G z1f2FKGAy2A@{{xVEuJKSJ5mjjESc8M@do~)++$C%HLn&bM&qc}+i6Z*pugj*} ztv8FVey;W-{)nAl>m8ZCSk50eHJ{$GkH4kawnyVrc2Rfqq7IY0@~No-0-0K?N7Jg9aU&q75Ae4(d1> diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kril_tsutsaroth.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/kril_tsutsaroth.png index 6b36fb211c25683884db6a057e0738e2ee3c6eaf..878a14c18beb8ac4edfb2cbccd45dd275d2cc9dd 100644 GIT binary patch literal 449 zcmeAS@N?(olHy`uVBq!ia0vp^5NNox532_C|5TL`(FvmfCr?38M zH=XImLK6&yd?YzjML45MpW0vEQkUuH zYA zqgrDu=U^yTsxNofM|z)=WSW-bR(sJkHlmTrqMg!wg_3;HBHS@ToI!%@?tJV{eC*DA z42J9satsVY@0pJS9nDk{){Bdn%#9w~R2cznfX zX?}$)=lMckgt|&^pO&eYPM8Mis> n>4hs4Z5eiTEMS^?B>lGF@uyq|jAzVr0!4(UtDnm{r-UW|E;XAn literal 549 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3-oh+|s`SsXqZeA+G=b{|7Q5z=@CDSCX?w zUnoqFy-|m+Q=dJ%Pd3#T+I#H8EPt$Q$#tEMYw|m*`s`IU2XKI84I;GWcfN7&vj7u6XclGQ@Ybv zKQ6$2pOa*BZAOF;XRQujh=;{$H=XT1`ZFd~9Skr$5@?tv%DKiybgrq;R(nxrK86jR zdZh(%TfFqvdFZ5RN$&GETwpFV!A3PrnX^=1ZkemrWLwo5W4TUgzFKKMUp~$%Nxm2% zPB{jKMb26??bRcdMcw(>gM>H>CHXuhIfI2czuFhM0)5V0666=mz%cEx)Ti}8?p040 z#}J9jxf7y;n*u~yEuV9{Iyvu3TI#l_Wa*VRNlR0rZl3-0|NnG8rpw*g=ijvFUz@iz zE&G-br=nw*i_lDiuo9yw%BhvgsUl~3)<(TFJlf;=N%cw6nff%51YYS=euq?EOV5tJ zZM`mdZ4I;k!1uK+_t)8JMXSp41Y~6A&zbl1++l88v!a{tSnm4$UR5sp z%Y6I3;`UEp-^<@Qo{-S`&!9@mR(pPe30wZBPruA++xeR<9)ITExA*3o=jD70k1p!g lidGA2@!7TH|A}qeV(Oi{gtmDXOBjG++SAp~Wt~$(696}f!Mgwe diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/mimic.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/mimic.png index 0666325dfac408c4daa22fbdc5becddcc6a953d3..7f523c6b879984d87cf348fba2874394ed4b2a52 100644 GIT binary patch literal 363 zcmeAS@N?(olHy`uVBq!ia0vp^5NTmh%gt!7}C{R;lkd^Jp6bQ88 zNK4Dl4dAVb;cZUjjdJ4Xa?WUN?GLr|o;Gdq=Czd!CZ;wTrezVlMWMWDJ{(@=9LDMl z9i3B(i)(Zg7@C@TYHHdR%+3i8j*N2%N%G)`j!y17)VBs`4O2;wUogY8{Qti_fxJzg zE{-7@=ePFXj5O@A(}N6#NlEm?nUs>qDqz{^WQIPO{`v0L70tQi znh>-rBkTR&eW&NGn{;mH*{!*+ZMCF&YbP0l+XkK D+B%H+ literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv@!3-oh+|s`Ssg?kr5ZC|z{{xv25F8xoWzOMm z%@Jb95$VVg>&B7f!I9>}QC3!;7s#ulzz`jsobAtBUENw++g?;uT@=b&7Qx%zF}b^Y zT2(Z!u{uLzV|R0NZ(S^JQzCC`GVg-fIh)s3b~$IXw)Ur`<%e2&$2o-9Xqfh73QU`} zm_b&SK~0Up#MH`7RTbz0=8_=4UCs)bWFHg4>!R&RM=<`ZbyFryGP`Xj7_sEl#PZTGg-iD0{`VW}@2|gnYp2AfKd*cEY?B4H<;C_MwZ3pG r)_(bKnT*X+>06l3aOHjDzg^AfzDzt@W#_6%pm6nc^>bP0l+XkKo4=T_ diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nightmare.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/nightmare.png index f8edd9b211ec893a8f0fab554cf2f821b7d7e0c9..c0f7645c02c50ca4a8f51792daa69a258ea4e5d0 100644 GIT binary patch literal 492 zcmVik5M4dR=OEU|?r; zP-k6TWot-Ys});bKvY~kNkc7yi$js}!w+p(es=MV=oI(X~MLnHNmk*QI7}>QO zK^YRld1DjB)f|o}HjM2|lnOwVuE=&Fd+a)~?x4CYs0 z1SD`l8k5en5ONLgH(~tC;WlctejmIAANWc5zCWUy?LiJKiRg(jrTlO_CJErKqL#MZ iw|n}GlQx__{>m5gGY{Kv1ji!)0000FY^EY8+P06IG!Ir=lPy{?juQr5Qe^SZmf%8;>xb6o}Ig(ezlu=lYL`@Z&;CaQhRAq zcxF+IaZq_;MR8j{Zdg56Mld^t2Ot0d00MMUPE!DuZ~yyA0002ANklmHXB0)*cA{~tukB{&Kf*ux&?X*4_9#XnP^_@c9Uf|9Ri3BvBY#2nb0ONW^R z98R~zgjGYq+qY?D)b$EhUL-n>&v#DA+$c zXUCL`4gD$Wrj|`_Oq!h@mb7xO)DV$OfI;k{hVrfuUf#1gdl>I9w@0?S)pecHKRp`u` zu;uM>Yr2ybwZu#+3+^uP?<)$JT^HV->rL6Lw6|b>d(P~Z%+|ul>WrYC z(x}?3kebY34!I;7V6bwP1o;IsOtV>fr}#kltH$pK7WM;0_j|fHhDcmaPH13q)6;Wf z6JZc}`0Syp=+j4!#RWu!o;d}oDQRe_=_z(Dnc(f^@+-NTnpODF1Y?q5H@zM&`~z<}E++an{Q!X+i7gh$&+$4t*o(NI(J=KdVbm6vd$@?2>=8p B34QNKFXv32_C|5TM4uAj`l|sH>i) zp^|E-tH;R@Yi{bRqh+I{q$ns@Y-yTjW}L01=AxmdBPAih%bRU)Q)!@8s;8Bpreq{5 zWgsXRBFHJl$=Q^V-e6~yZfjLxZ4s)gZLgvdq9kjsAgd+FYr)CTUtHLgpO+sIp5*7d zAi!&ir*opEd6tPmfSO8-ib8;bl)_dSU7&-QN`m}?8K&j`|LqCnZS!<-4AD5hbfT-+ zVFLl@?8-MY4uzy0`+a|1qmm9o_$f6sT_R*q-C++&{gwqbXiX~MnT wBF%BGvk%KmUbmq1hZGY}M3~*O?@K2BVmh{xi^ajK(hd~Bp00i_>zopr0K9>W(f|Me literal 488 zcmeAS@N?(olHy`uVBq!ia0vp^!ayvA)3QZ!Tw%uNCXIrDYYYHck;4D_5e)a+GM%oSt} z1O>wcIRo@`JhU`yl$3O&B-BJjv+ZqsbhOkM7-Sh36a)n&czJC&8T2?AV$Ds{jP&Z$ zQoHi=jAW&XElrdBeDfp1Te33yiwi3av`je}k_~hg1b8J{nwMFbPw{k4x3#LWv6SNE z4A;`o666g~Q)zavN%|T!59ny-k|4ie28L;mr9Q0(a&LLMIEF}Ej=k`*sL4QtHQ}V= zfv61{UAY=hnmEOF1w?Pxd;dR*moatO_wZ-4Q;N>X_U=k#FlIl!XtF~ zap{yR-wzy5-=+W9=|!ftwDpR|nd0+zZ<}kl;_;i;zkBxWe967^)%^Np#{a9Pzm5HV coXzkXyJLXh-&~LM8K9{0boFyt=akR{0BxAC0ssI2 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/scorpia.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/scorpia.png index db4c0ff9888f8ebb15c87652d26b21008fb56082..f39f9baa6e10dd18972337e5398f31e10db37eba 100644 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^5NZADVgt!7}2ynEq3H0{1F*jF~ zmp9haGtkjdS5ZArlu7K!&QmO-$2bwB|(0{ z4Ab)e|Mmp(x;&u+;iW<=oc3K*&we6Ty{n6X_wfwl zx`Vn-GI|2a&K(`+7OJLPck%WKQweVpog1If7IIQw-6W&*-B}-5Oa2AlbeHx{u=r$J zqp{b{Iw{;mOXB-2?v4+^8ltuO42cW>@QPW#HS4Xl*q7MW%lGV%Nt0=xc#&(L`N_3R UFI4S!2Y`I&>FVdQ&MBb@0LM~Y!~g&Q literal 333 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tQ2{<7u0Z<#|NlS|2m-yml@t`p z^YheIRc$RSeB9lvOic}RbmU}YtT-6_Jv_X4Ihrae+;}+>qax!YBAo5)a#B(ptgVgp z^t3cJf##SS8F{(5;u=|<$jXtrZ+$D4Adt4Hd1 zEx&f`0dtSlPQy~ixqQnE-!v*dDwxu6N=5w)}^O z_qqiW7Jly0e7%U1%`$6ik^M5s$haBYtL8SXQGWYvcSOnQd+)^KcJ5xg>HG8ksmEO6 XWtXwapP4>K5fmPtu6{1-oD!MNaY9kgt!7}2vAm3OpJ<5jg1ZT z^0F~E_i=M`wzHF$kqHY3P*+uzU{E$UHWp@(krEfrNl7u*(-RRCEXvA?2@8t~3DID) zRO2#KVA0do)GW`>vorCtGVpMBa>`Fn4{}Y*Oic8)k2Th`mu1nGcy_`TXdhEakY6yv zwEX|SJ%PMEo-U3d8t2!ZJ1Nv;Aixr^Jbe>8&+4w#YH-RzX!&iPbg)a@2oa?z*IV$Ue+9YKpObZS%pAg$%t#GH%Zq`TjEylltte$_5j`nrn@W1!^($iG_v|Hj)Q$&hRZryfJs-NG)Dt<74`f0>sK0+gWTc&? zWm0sMwV9bLi?)cMV0Ln{v9Ym*v9Xl6xCDc;5{rSdqGC~2mW{Cw0|TSCeXItHr96vn zcwk^=VxpzKTUlOiT3npEs;az?zP6^Oqm7L!hrTF-ytk{Xv8KHmm$9L)t~!sguZMe(kB_^PQ+|577MJDwTF$pX zhccH0`2{mDOnWT#X+4m8%hSa%MB;Mph3xPa1p&4PcPm5B2p!G~b6O_29{dS{F%5*n)R?}Td=^n3C-d^ zwiY)E?bxx0sq5&v{D8ZU-tC*Vsv^QS)%Wj>ElumM*>bL%udQ5}D84$b<<-p%!Rvn; za=UfhJF@#_?!S*a=U@6DdB$h6n%$FQJ{MNKFp#32_C|5b!X><5@x4b#J>x z7JBa&&U!Pc>s4pNtCs2~sZoz(10Mu9zh6A}bx-rtoTNwL-e=vdx7e9XHP-&Jf7j>T zTR(1C^gAeB#TtqkDsqWRGQQGcFYC)* zR24k%ce?CpyWiPjxs|~jGu_!{y1j;)O}c72{JdKtPEG*2iK!&WFPLFk{{P>eK;B+Y z7sn8d^J^zu7iv}zaY<#YzOEuw?YaK{|I$Jk&R5B5&s(|E%Mt_rF)&7+V+z>GeB9>Y zW9xehJrX)OzG=DfPbgeExzQxkcjS_m76v#WFsAUDkI=fL*{X3>V* zUm+a0KsMuDQKLC8ef9ZpI=XPu6Z)D0CLhYK8Uzq<6kxpF8W+Dt!!EhcLv zAM?Am^SZQ#E+=*=BI}Qa?30V*UQ)k9IG{K#U7L7g00003bW%=J005Tb8uG6I007=e zL_t&-({0fEQ-VMc2k_&*mk)|Eg)~wzpCE;S*%N!3uTcO0|Hiu;1e$4oxtY)G?(Hri z|Ag`WMiB$j kf939u)|9u%*x?4k_INxJ(IlturvLx|07*qoM6N<$f{Ld3-~a#s diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_gauntlet.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/the_gauntlet.png index d24830e178bc468b3a7a8d05af0e77ca475ab53a..3e03f805c1124ef40e62b752f8c26b7dbb42d171 100644 GIT binary patch literal 510 zcmVM)TAr0otf67^%XH1daK*b|s-sDtl|XWDI%j0GMS6BKj&(nAYZ+!zC{RltPDdI!HIDVy zq~F((+17{k)p_*MjP1~J^Ur+K&xP#HdD6~`*3DM&$am4kVCTYd$Gtk`xoNq!P1mw& zyRkISs4~c+O{SYJxRpqol2)0JQjv;Eg@P!bfJlFRG?IBYc5gjyXDobXCTn9Ta$YQB zTr6N%C|6P%N<|GKAb$(b@c;k-0(4SNQvjB4|NBV*007EKL_t(2&#jQv(!xLtM!RR1 zmJ03;zq`8&{{9aH!?dL3lHpusbLPutV(kEhiq|60@}fyRQDI&FVF}cu2&#I%) zgyPmmDY$#;Efv&VqQplFuI$s&|DcC?bfQrTW7^&G{gcvg_NCplk1Rs9;5g+EPQ4fP)QnTR9c>uYP+#?&B9xtmqmGVh3w9b_1BE;&^hC{ zCTn9FN<}E2fMBVhKXGqnw5xT`%XQDhbIZYOzqM((uU({^eACa7+17{k)pyaxF1VFc zl#xb!dP$y?f9uSo-`8rpxH@NLG?IBVk9H_>UJW83NSl&Prkj-7*NWE7WwNL`XJSx{ zib#KbB1}daIWksisPWf;V<=dGygT$f989!cEt*GK_RSBxu3_000AYQchC< z0G8t#@~;2@0Ov_WK~xyiV_?7n7*PNdGZRP*NFl_SSwMn}%&g4F>e!eW7?_yZk;E98 zIe-e8Ik}j@3YfuWFadQlFmv-TGXX_-`S^jN%*-4DKrulfVP<9#Q894|NhxM&8CjrS zCT2Nlc`gM-C1n*=H5PSF4Q8-gm^HPub#(PK^;tAPrh?rJ6g4n3GBzG+d8X^<0xVr!V00MMUPE!Du zZ~yyA0002aNklMEU6l_g2+6x(BV|dqKhRQuA_o@deVQcw zVXW)&C=Z-=TQc?6*zKvyNglN9P1Uf5hCxqmVTU3=jIG_gUE@}OLXM_n&R4urC?YJ7khLrG-IVtbsOzp=8+rl-YgYlUoWh^(y0 zs;bALqr+uof0LBCet(}@T5)}SooQ)=)Mu@Y00003bW%=J005Tb8uG6I008kxL_t&- z(^b&vR>Ck41>lmKv=XY|LPc?*A}y|9!37jiSrowq1=PB||634f3T1xfd}n6PtWN+rAN4ou}uQ*RI-@>%@QY_TKCD^?^8gk^w$G zzY1yBWgHVD_%?ss)-O{L%n$b8e;0w-V9)}F6*d^}O9a{;00000NkvXXu0mjfBNF5IF32_C|Fu-W-WRjMZ=Nas1 zYGaU7P@0^U9iN&O5giv080PNft7odErm7?=!JC;`5S5rTp*yj*GBh|cI4Q=rAlJv) z!`Z;t$iYs})UDqgxxJ!ehguLqoj+14~N-!UA1geQmwmtn96==PRG!`S&z#};Za;PTo=so(e!lFr-uo(dZLNT-QGT>|yt>JTm}~)ML9rc) zJYq~K8h_ii%1Uwu{jcw>%Ddt2Y5B8ef_7%vQS&Pcv^h7k=q#|E+V}C(AyF+?U%8S^ z4^^JNF1mlZDy~5DF|9U_p7VugWPV_aK(c~wwQR*#BcKtL*+n`%~3ML;|0002eNklfrLx*ld92pz$;MtsqxtmwQrYj|wbkyt zDen*%hWY-{{_I)^&jh`mZGIW1-L)({&$Hp9(EMlhaCXY)TB7VK>4$V^s? ht;rvi#a@Ja_8+tP6$M+4>$m^_002ovPDHLkV1nQf)rJ57 diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tzkal_zuk.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/tzkal_zuk.png index c227671ec899df08a3ad14ee4eb70ff7c56022aa..1c6a966f19d2b07d95a35a4809ee3ee821d0d3ff 100644 GIT binary patch literal 370 zcmeAS@N?(olHy`uVBq!ia0vp^5NYw@Sgt!7}IPi9Lb$4=dvA2(~ zu@3g}39>NL)zS(J2ynErvN1RJFfuUF*SFW!^!N0%GBq_fHug3#a?#f_)YVm2RaI6} z@={jtGcl4B5-O4r3=!b)wzm(qvIsOcwba!K)76xfme!FJ-=HGWCo9-4$rCNW;laz! z#~42oXgzaDkY6yvG>*&L5(|Lb1)eUBAsXlRUU27QR^(y5U?4AH<@5gK*MH(Zo0>W| z$>r<(K6z<+`E4;qhkxt1t2#x#ho0pNph$#RNrL z3;bAjmUq*PQ#_|kZZuBa`RiD(QDj5SulM_ngr2{B#p`*B{cz*G^K|udS?83{ F1OU_ddc*(# literal 583 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{Rd`U{nb3332`Z|36R!83cNH`M9~s zN=sW98(W*1xjQ-8TUqI9X{oEKswgQL>gk0A1i0ASJ7{ZKn3%XaIJh}Fdb_#?`}zj^ z_=NcS23eT7=1n8` zc{n@!dwSTIo0}OKnds|#@Ur*G3T{vl2@>E`R#I}Zwe_~Q5ApU6_49Mq)6J zw6n0NZ@gUr3?0^zAirP+hH0D}Pu_g&01906ba4!kxIFj5^`Juz608ZE3OEE9g&iE0 zuJq_F5nU3_-L|ge{(oJcPy8{)b5_sIFH1Wg+5GTIL6ro6N5?t=@I3$l$zf}As(XBp7vtDXeqxh5MK4#PP zMdmJjF23n{(bKh2tIcQWF1V}s`rCw8{0-mvCFjSd9L}$pB4`lyCd2>45=MQ0QG*tl z%_nOTuiXFpGj`pz2MRgctY0lEyZ1kH^OlqC=jL=?taNZAMYgt!7}Akb&v1Ct_l47}b9 zLi!90i40O<3=&#gQs(>$*$fKa3<`-1d{5^`mvX6wF{s)xDA+MbWiyD_b#ny(buyI% z`2{mf%m4q|6Udw7>EaloaenK?+g!|wJS-QiCNJ4F{oeoo(bl_{zUcCAJ=g5SXSitj zewB%t0U>8JUaxvBWt?#N%r?1qafcKtO&mUJE4Aldns@YQqehg->{SN4%@fubdnxGu zIKmP-Wl#7*4z1dQu@kfkc5%vl+an*Hv6F%IR{w&Z`${J)l|JM>N7Sh8fJ^TBcTvAj ia~)Z1fAi<|J&epu%x~@Ee!l>^j=|H_&t;ucLK6Tn6l1Rd literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5t-T^)#uK)l42Qnc*mVsA~K~#@{ zSBY0tmVr}>Q&5e8)06>7itd_ZZNnhw#31UyDWS$7Xv!dA%D}0{z+l6`smH)6%fR5o zz$^bh_$JUG=8_=4U=NXwxhq*=8?!T}7et?wNUvN*3*wKEmgfrlhy1ZdfIzW@ux|{4#Qfk>#z^iQQcV z8xKntE3C>&Z)NW}*Dgt!7}2vC)i6A=_tl#D;!qu1$iBL8Dtn31RjU80!?Qs3GxeOn3n(lwzopr0BN^#lK=n! literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5t`2jv5uK)l42QneRjhDlbm%)mI zAwZDBiI_&|F*FL{l?TkV8g9#92hpN?$)&gkx%Vmx!RC zoglBdAg{iv>d8X~kL=#9t*9u&z_4xgsvT?B%$q!U-J(UCmM>d1Z(h=xAU2?7%q2m7 z!3+%39!q^%59Dt5ba4!kxSV_8HD8kf4{O3UUPzq7DX~#o3S)g#P%-z;6z_tMf}Pf-4@ZrPI$YzwMt?y{Qn&742`R*t+`G*{W* SU%Nd(!RP7f=d#Wzp$Pzvrixww diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vetion.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vetion.png index cfc9d47a03bc22fa10ec065933e3708013f243b3..67a7b3d645d3fab48a46ddb0cb58767e7ca7fb69 100644 GIT binary patch literal 347 zcmeAS@N?(olHy`uVBq!ia0vp^5NYw@Sgt!7}2vB8E?TzbkmvggX zu+(MHm0^&{=gmv!NQ>i$4c7^ekP8pz2=&wU^OW*bRdv!A)VH$Ilj4vPk=oqgQC}WV zmSdBhloS_f6cMBv6eJTEz!4DX>7}XZ72xUVrtZeT;poUMZ$C1Pd5U}7j`D59#X z$*VbCZG#)odZv;fzhH)G`Tu`=0(o7YE{-7@=eJHcE_BF%hxMaX-`u#Ddk_EruW+uw zfZ0mu?vlAzJ@SqGG^g-%OyKnH-SaX*)z#4ZoVjD-#3?WP=5ve0nqB8h+Sl?{x%bw* z8+)fJJW+pjCuUXk(dWrNjhEK-Ym4Wl@yi8?`1f2}kzm3*FaMQTa$BW>v-|O_?5eJ+ j?XEs)6N8US|6ec8Uc&Ow)7oe{D2O~={an^LB{Ts5H;QfJ literal 391 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tlLLH0T>t<74`f0>Z(L7OQk*J- zYJjJwE`x4^M}0nTo+E?334=+FO?D(lL^?-Wq^FmytzjHTY&t^_7XSLGSzt>rJwQ9vKzt!z)C$Z|i-FKAl b_OE#PZ?WvATVH(h2Zg1ltDnm{r-UW|{SSsz diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vorkath.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/vorkath.png index 696669c35306f5dab14d48a9bbfb3f6ce5d81cef..c3732b1d0225342ec3ab508a0963fd1992713661 100644 GIT binary patch literal 478 zcmV<40U`d0P)RSjFN~{O;pX%%V?*#w!E@rp|MtrnVX}QmYk81n2k+* ziF|Wba85N za(HiUb8Bp5YB*V9R!~+^N>L|2MItpk)7Q~ro~~e;sj0E0U6rJ$ucCvEjeUlPfQ5T^ zZgW3oac68~G*VkwQdllbR8Uk+LOnu4ML;AvKOHhR5gi}^;YBF`0007XQchC~4BOD!q5OmEOz$e-#2z9EmqLPa_|VEX$dXLm(cX zK;jWA-~|b~$2_aRvO2iMlGedfXj*^^MEKU1Oz6697hSIb6g0VIBA5GfZ1=a8NK5*A zu;qyUJ+EA}-JeF6FLz3!rkat8`zL@{!7)TwR$(^b07*qoM6N<$f;hF#fdBvi literal 597 zcmV-b0;>IqP)zO=~A#k;|`P*hEBu)%P%#i_BSw!E@urnX?3sZfB7JYj3T!@A7S%9ovz zLPbD*bb4Ktq+FDuWumfTo~~|lYp%Ackd})|c!fxGe?@P3Ia_2A9UzO4hE9EoQiYM0 zosu+CTOu_)!^gk6zqY8aqJV{aaA|OAVrrF}kV0y7H&|gLIzJsUH;s$_5IdMv)r5uB1qC!TMYN!H$Y|@x z>*}fM>Khm`L)^#2EMuf&tgdTpVrpj2%n0@evxTLVwU&*ooxOvj6HLt6MaR|6-NTdB z%NwrFmD$V3*T+xSUco;ACKedv>+8!C91JyRaL5cQ+Z@kv|&>J_D`}_PoY^#pJYj8Q$zBtLcV}OU{687W;s(# zIMS>(#G*7vJ2T>XGWoAD*?KXna4^YaFN|L^eC9J*s1vtJq&6%}AS5^H4+XEzM2bP6yn3KA9O&J?2n^uB|frGS7B_}fjL`y_%VUdPf zo_I-?b-jtdI3vtZkt+3gC8bo6+z?yCK#w{RxMkw%8nLRX<=JtbVUn&!elQ6pfAOZq zXhk_Ww*pyN9p%#I3aA8+Sc9>tw4Q3L6*_IyEO#OgI%24jmgB0012v92|OSCvjpbAs!YX7Y@0L zVLL4#5DyE)qBIp16?9ApQ#u7_Hw+;f5R6|g$-1H9qG$iVe$tX`84e24tTs3r1G-}z zvtJskTNy1L7%(g#6bl1jJQA8>CHJ#+i%bEhgSd$ z2RAZ*C2M64KL7wQEeZt%1C2!h?YN2Vv4Q`-fcTbW{iJyIpnUM3Y4E&xs(VvpNG?b# zCi9wj@sMfPdt$U!?K#4ho@JN>?r?G8-2R2nGNEAlJmK z^vt2=-pmID1E7LxURhI_f@~5I3u#wKJ~1bMHZLk*PeBq63}sV8J1-?BBqT^XGn05@ zV^~lkARu{UQZy(XT2)m-JS!_GC<6uvXjx4U4i6RYSjYeX02XvoPE!CNra+HyurQhs z-symlV6oHC$WZY0SjecT0003BNklWS$a7#bNfF@ki7nV6cH zTUc6I+t}LKJ2*PAKnxRec5!uc_Ym{+^7ird^B03!5fB&@91DVH zdq%9iqq7U>q3)jEJ~3oJ3V^h+^iP;LX)+4~IuM&Ob=ve9Vq$`5!ZT;ho-=ped?7U9 z1q&A~&R-%Vj25;_mo3j{6A?x?TvUvM6V3qu*BLtJqan{R00000NkvXXu0mh|g2_5G A#sB~S diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zalcano.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zalcano.png index f2bdac1cea07b0239ff8fa057a8c12313ec3ce88..72a0a1714b22268e940714ba9285e09b8538689d 100644 GIT binary patch literal 407 zcmeAS@N?(olHy`uVBq!ia0vp^5NKFXv32_C|5a8kG9~>F!7aD4B zWo2n%VyLI*>gny{=H}t-Y-4V&t*x!BppcNB9+RA6>*Qo&V`FMypscDYqo5ET8yn~2 z6X)dMY-e}3P3o$Sl%%BOR0Y8@3Eu3Y;-svsBtPF6FHZ+o*Kbp0Kby$j)ss4_C2>?k zVn&Q$pRAy$pkRv>Z*M?bY&li=FZbU4Uly1)gVW-)3-`@m{-q!5lM@~%pLkGFpOD;kAht_$?m<7b z7AL+>Oxz-6ZT^j}3?Eo6v-xziW2V;a?%W}LnzMjY=X(3Lo{Bk7W}Lb4NvUU5*QZiG zvuN{&zhm#e;ESLB;qu1)sj@w%AFfEOc;cAAz;;~l>`zVR#lkP=74Li<5}z1SF;9KT uq)TsD<2CpD1v94cF=jFL>^kW2_h6i{Fh|IJq3>#-;PrI%b6Mw<&;$TbR*vxi literal 485 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5t2LgOTT>t<74`f1sS74xTNQj%4 zkBOyaKvZ# zTPG(y1EcJs;v_%cyLwXQHa4;f3J$KWu_>u>P7Yc+I!5*mpG{=HO_iOhAb7V;NUMUF)dn+p&bMp!b-VzC34_;0wB_$OlB?Vd888L#g3=BqkdOmJ$eX@dK zf}A>9TBZgDqJn}>wzjSg4!iBt{eZ4#E(!7rW?-21SnAVyAorrDi(`ny<=hE3Cp8%e zxO(a>=seV*{ciU;r87I4x_(%=q=w^U?iJF|)RxVk_S&ZC-5p@4s`}-u3K} WJ^Ttk6#{O9V#?Fi&t;ucLK6V*#jC&o diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zulrah.png b/runelite-client/src/main/resources/net/runelite/client/plugins/hiscore/bosses/zulrah.png index 7e2dc8807f59627687bcf2f085131e8d7e648c79..44a28c4cbd98d4eb4a5d3ae9a933ff6f754f0a8f 100644 GIT binary patch literal 346 zcmeAS@N?(olHy`uVBq!ia0vp^5NVNp`gt!7}VgNTc>xyO5CiK@9 z6{aoPB3e_&uc6N>EW)&F&%&8ATl)IS%FE+3Ga}Q|L!zRB($WGw%uLOl^pD<=-g#bX z{b7mjc_J;Hg7(3J%@g<|l6Y)gIOG&rCNE)#j$$yfWYFNda}($Yo{}KHV1|B!mwPsD zXmI#&AmI3or`AC6N>3NZ5RLP5&wC0rIq|%8N+iSGq%;z(I-@9*II+-@AB1DF&N{2Mlc-r}v$ht+glfbj|+XdbtZ4XV{#d>%M2pZ~xHUt93h5 zm?lmtdB$_b*q-m6%pc1i1rs)y`>pS?^zfC^`Rv!c`0UDC3~y($-mibhnFb0WPgg&e IbxsLQ0Amh${Qv*} literal 374 zcmeAS@N?(olHy`uVBq!ia0vp^LO?9c!3-o<`K&zvq~-_sgt!7}VgM%>Lqrmfx(g`33| zZ4q6vc Date: Mon, 1 Feb 2021 13:47:50 -0500 Subject: [PATCH 43/53] openosrs: use openosrs dir --- runelite-client/src/main/java/net/runelite/client/RuneLite.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 9d728a6865..f2b4a9ac8d 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -93,7 +93,7 @@ import org.slf4j.LoggerFactory; @Slf4j public class RuneLite { - public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite"); + public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".openosrs"); public static final File CACHE_DIR = new File(RUNELITE_DIR, "cache"); public static final File PLUGINS_DIR = new File(RUNELITE_DIR, "plugins"); public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles"); From b5b64bc9ee05e2bf7e8d49be8821cfd463722632 Mon Sep 17 00:00:00 2001 From: Broooklyn <54762282+Broooklyn@users.noreply.github.com> Date: Wed, 27 Jan 2021 12:00:26 -0500 Subject: [PATCH 44/53] loottracker: add Gold Chest tracking (Shades of Mort'ton) --- .../client/plugins/loottracker/LootTrackerPlugin.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java index 7bf83abca3..816041298a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java @@ -186,6 +186,11 @@ public class LootTrackerPlugin extends Plugin put(ObjectID.SILVER_CHEST_4128, "Silver key crimson"). put(ObjectID.SILVER_CHEST_4129, "Silver key black"). put(ObjectID.SILVER_CHEST_4130, "Silver key purple"). + put(ObjectID.GOLD_CHEST, "Gold key red"). + put(ObjectID.GOLD_CHEST_41213, "Gold key brown"). + put(ObjectID.GOLD_CHEST_41214, "Gold key crimson"). + put(ObjectID.GOLD_CHEST_41215, "Gold key black"). + put(ObjectID.GOLD_CHEST_41216, "Gold key purple"). build(); // Hallow Sepulchre Coffin handling From e4d5450283685ca7c39498bf48b6649cb7c9c062 Mon Sep 17 00:00:00 2001 From: Broooklyn <54762282+Broooklyn@users.noreply.github.com> Date: Wed, 27 Jan 2021 12:02:46 -0500 Subject: [PATCH 45/53] worldmap: add Shades of Mort'ton minigame location --- .../net/runelite/client/plugins/worldmap/MinigameLocation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java index a5f0b55ca0..cc387c4872 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/MinigameLocation.java @@ -55,6 +55,7 @@ enum MinigameLocation PYRAMID_PLUNDER("Pyramid Plunder", new WorldPoint(3288, 2787, 0)), RANGING_GUILD("Ranging Guild", new WorldPoint(2671, 3419, 0)), ROGUES_DEN("Rogues' Den", new WorldPoint(2905, 3537, 0)), + SHADES_OF_MORTTON("Shades of Mort'ton", new WorldPoint(3505, 3315, 0)), SORCERESSS_GARDEN("Sorceress's Garden", new WorldPoint(3285, 3180, 0)), TROUBLE_BREWING("Trouble Brewing", new WorldPoint(3811, 3021, 0)), VOLCANIC_MINE("Volcanic Mine", new WorldPoint(3812, 3810, 0)), From 5e7242388daedef973ee3504a1831a093d42fc0a Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 2 Feb 2021 21:03:56 -0500 Subject: [PATCH 46/53] image component: support setPreferredSize --- .../ui/overlay/components/ImageComponent.java | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java index 39ec431697..46f07f0515 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java @@ -24,35 +24,37 @@ */ package net.runelite.client.ui.overlay.components; +import com.google.common.base.MoreObjects; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.image.BufferedImage; import lombok.Getter; +import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.Setter; +import net.runelite.client.util.ImageUtil; @RequiredArgsConstructor -@Setter public class ImageComponent implements LayoutableRenderableEntity { + @NonNull private final BufferedImage image; + private BufferedImage scaledImage; + @Getter private final Rectangle bounds = new Rectangle(); + @Setter private Point preferredLocation = new Point(); @Override public Dimension render(Graphics2D graphics) { - if (image == null) - { - return null; - } - - graphics.drawImage(image, preferredLocation.x, preferredLocation.y, null); + BufferedImage i = MoreObjects.firstNonNull(scaledImage, image); + graphics.drawImage(i, preferredLocation.x, preferredLocation.y, null); final Dimension dimension = new Dimension(image.getWidth(), image.getHeight()); bounds.setLocation(preferredLocation); bounds.setSize(dimension); @@ -60,8 +62,15 @@ public class ImageComponent implements LayoutableRenderableEntity } @Override - public void setPreferredSize(Dimension dimension) + public void setPreferredSize(Dimension preferredSize) { - // Just use image dimensions for now + if (preferredSize == null || (preferredSize.width == image.getWidth() && preferredSize.height == image.getHeight())) + { + scaledImage = null; + } + else + { + scaledImage = ImageUtil.resizeImage(image, preferredSize.width, preferredSize.height); + } } -} \ No newline at end of file +} From bbfa08f8b7d2343d97ef40be608fcfc69f52de43 Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Mon, 25 Jan 2021 23:45:29 -0800 Subject: [PATCH 47/53] MenuOptionClicked: Add selectedItemIndex field --- .../main/java/net/runelite/api/events/MenuOptionClicked.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java index 8eb4707ae8..2cd15c48f9 100644 --- a/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java +++ b/runelite-api/src/main/java/net/runelite/api/events/MenuOptionClicked.java @@ -67,6 +67,10 @@ public class MenuOptionClicked * @see net.runelite.api.widgets.WidgetID */ private int widgetId; + /** + * The selected item index at the time of the option click. + */ + private int selectedItemIndex; /** * Whether or not the event has been consumed by a subscriber. */ From a58b2d3fdfd6dcb6c5c98b52a01995da351005f9 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 2 Feb 2021 23:26:18 -0500 Subject: [PATCH 48/53] Revert "image component: support setPreferredSize" This reverts commit 5e7242388daedef973ee3504a1831a093d42fc0a. --- .../ui/overlay/components/ImageComponent.java | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java index 46f07f0515..39ec431697 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ImageComponent.java @@ -24,37 +24,35 @@ */ package net.runelite.client.ui.overlay.components; -import com.google.common.base.MoreObjects; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.image.BufferedImage; import lombok.Getter; -import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.Setter; -import net.runelite.client.util.ImageUtil; @RequiredArgsConstructor +@Setter public class ImageComponent implements LayoutableRenderableEntity { - @NonNull private final BufferedImage image; - private BufferedImage scaledImage; - @Getter private final Rectangle bounds = new Rectangle(); - @Setter private Point preferredLocation = new Point(); @Override public Dimension render(Graphics2D graphics) { - BufferedImage i = MoreObjects.firstNonNull(scaledImage, image); - graphics.drawImage(i, preferredLocation.x, preferredLocation.y, null); + if (image == null) + { + return null; + } + + graphics.drawImage(image, preferredLocation.x, preferredLocation.y, null); final Dimension dimension = new Dimension(image.getWidth(), image.getHeight()); bounds.setLocation(preferredLocation); bounds.setSize(dimension); @@ -62,15 +60,8 @@ public class ImageComponent implements LayoutableRenderableEntity } @Override - public void setPreferredSize(Dimension preferredSize) + public void setPreferredSize(Dimension dimension) { - if (preferredSize == null || (preferredSize.width == image.getWidth() && preferredSize.height == image.getHeight())) - { - scaledImage = null; - } - else - { - scaledImage = ImageUtil.resizeImage(image, preferredSize.width, preferredSize.height); - } + // Just use image dimensions for now } -} +} \ No newline at end of file From a6841c5cebca365bd71cfa610af9e5bc534c4e89 Mon Sep 17 00:00:00 2001 From: Jonathan Lee Date: Wed, 3 Feb 2021 07:29:48 -0800 Subject: [PATCH 49/53] loot tracker: add support for isle of souls chests They have the same description and behavior as stone chest. From melky test: 2021-02-03 13:54:03 [Client] DEBUG n.r.c.p.l.LootTrackerPlugin - Tick: 417 2021-02-03 13:54:04 [Client] DEBUG client-patch - Chat message type SPAM: You manage to unlock the chest. 2021-02-03 13:54:04 [Client] DEBUG n.r.c.p.l.LootTrackerPlugin - Tick: 418 2021-02-03 13:54:04 [Client] DEBUG client-patch - Chat message type SPAM: You steal some loot from the chest. 2021-02-03 13:54:04 [Client] DEBUG n.r.c.p.l.LootTrackerPlugin - Received icc: [Item(id=12791, quantity=1), Item(id=13068, quantity=1), Item(id=13222, quantity=1), Item(id=13069, quantity=1), Item(id=5698, quantity=1), Item(id=6705, quantity=1), Item(id=6705, quantity=1), Item(id=6705, quantity=1), Item(id=6705, quantity=1), Item(id=6705, quantity=1), Item(id=6705, quantity=1), Item(id=6705, quantity=1), Item(id=228, quantity=2), Item(id=12631, quantity=1), Item(id=11953, quantity=1), Item(id=1523, quantity=1), Item(id=1523, quantity=1), Item(id=1355, quantity=1), Item(id=314, quantity=121), Item(id=1621, quantity=1), Item(id=2510, quantity=8)] tick: 418 --- .../client/plugins/loottracker/LootTrackerPlugin.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java index 816041298a..f3802e230a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java @@ -145,7 +145,8 @@ public class LootTrackerPlugin extends Plugin // Chest loot handling private static final String CHEST_LOOTED_MESSAGE = "You find some treasure in the chest!"; private static final Pattern LARRAN_LOOTED_PATTERN = Pattern.compile("You have opened Larran's (big|small) chest .*"); - private static final String STONE_CHEST_LOOTED_MESSAGE = "You steal some loot from the chest."; + // Used by Stone Chest, Isle of Souls chest, Dark Chest + private static final String OTHER_CHEST_LOOTED_MESSAGE = "You steal some loot from the chest."; private static final String DORGESH_KAAN_CHEST_LOOTED_MESSAGE = "You find treasure inside!"; private static final String GRUBBY_CHEST_LOOTED_MESSAGE = "You have opened the Grubby Chest"; private static final Pattern HAM_CHEST_LOOTED_PATTERN = Pattern.compile("Your (?[a-z]+) key breaks in the lock.*"); @@ -161,6 +162,8 @@ public class LootTrackerPlugin extends Plugin put(10835, "Dorgesh-Kaan Chest"). put(10834, "Dorgesh-Kaan Chest"). put(7323, "Grubby Chest"). + put(8593, "Isle of Souls Chest"). + put(7827, "Dark Chest"). build(); // Shade chest loot handling @@ -630,7 +633,7 @@ public class LootTrackerPlugin extends Plugin final String message = event.getMessage(); - if (message.equals(CHEST_LOOTED_MESSAGE) || message.equals(STONE_CHEST_LOOTED_MESSAGE) + if (message.equals(CHEST_LOOTED_MESSAGE) || message.equals(OTHER_CHEST_LOOTED_MESSAGE) || message.equals(DORGESH_KAAN_CHEST_LOOTED_MESSAGE) || message.startsWith(GRUBBY_CHEST_LOOTED_MESSAGE) || LARRAN_LOOTED_PATTERN.matcher(message).matches()) { From 9381e62f6d321a0af215765101c370d621c4aa8e Mon Sep 17 00:00:00 2001 From: Jonatino Date: Thu, 14 Jan 2021 14:50:58 -0500 Subject: [PATCH 50/53] Fix incorrect named value when storing FlatStorage caches --- cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java b/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java index 92a82e26b7..c8d651bcf6 100644 --- a/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java +++ b/cache/src/main/java/net/runelite/cache/fs/flat/FlatStorage.java @@ -220,7 +220,7 @@ public class FlatStorage implements Storage br.printf("revision=%d\n", idx.getRevision()); br.printf("compression=%d\n", idx.getCompression()); br.printf("crc=%d\n", idx.getCrc()); - br.printf("named=%b\n", idx.getCompression()); + br.printf("named=%b\n", idx.isNamed()); idx.getArchives().sort(Comparator.comparing(Archive::getArchiveId)); for (Archive archive : idx.getArchives()) From 27fb56f5b8cdfc8b376b1d42b48953e6c348277f Mon Sep 17 00:00:00 2001 From: Taylor Abraham Date: Fri, 11 Dec 2020 10:08:47 -0500 Subject: [PATCH 51/53] music: Make volume percent visible when hovering handle --- .../java/net/runelite/client/plugins/music/MusicPlugin.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java index 6f3421b08a..b557cc18b3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/music/MusicPlugin.java @@ -466,6 +466,7 @@ public class MusicPlugin extends Plugin public void update() { + handle.setNoClickThrough(false); handle.setOnDragListener((JavaScriptCallback) this::drag); handle.setOnDragCompleteListener((JavaScriptCallback) this::drag); handle.setHasListener(true); @@ -511,6 +512,9 @@ public class MusicPlugin extends Plugin int level = (x * channel.max) / getWidth(); level = Ints.constrainToRange(level, 0, channel.max); channel.setLevel(level); + + int percent = (int) Math.round((level * 100.0 / channel.getMax())); + sliderTooltip = new Tooltip(channel.getName() + ": " + percent + "%"); } protected int getWidth() From 263b02ac14ce1c298790915b46decac6445b06a9 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 3 Feb 2021 14:20:50 -0500 Subject: [PATCH 52/53] config manager: use createTempFile for config temp file With multiple clients with different configs saving at once, the same temp file was being used, which can cause it to not save or to move() a temp file from a different client --- .../src/main/java/net/runelite/client/config/ConfigManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 01d8ebfe1d..a2a4eef25c 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -394,7 +394,7 @@ public class ConfigManager parent.mkdirs(); - File tempFile = new File(parent, RuneLite.DEFAULT_CONFIG_FILE.getName() + ".tmp"); + File tempFile = File.createTempFile("runelite", null, parent); try (FileOutputStream out = new FileOutputStream(tempFile)) { From 4f6f518a153e4424c27c4c15cbc444e72744d7e6 Mon Sep 17 00:00:00 2001 From: Usman Akhtar <60450353+akhtar-u@users.noreply.github.com> Date: Wed, 3 Feb 2021 17:18:16 -0500 Subject: [PATCH 53/53] worldmap: use boosted level for map icon tooltips --- .../net/runelite/client/plugins/worldmap/WorldMapPlugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java index 1114d56720..dcac0c700f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/worldmap/WorldMapPlugin.java @@ -186,7 +186,7 @@ public class WorldMapPlugin extends Plugin { case AGILITY: { - int newAgilityLevel = statChanged.getLevel(); + int newAgilityLevel = statChanged.getBoostedLevel(); if (newAgilityLevel != agilityLevel) { agilityLevel = newAgilityLevel; @@ -196,7 +196,7 @@ public class WorldMapPlugin extends Plugin } case WOODCUTTING: { - int newWoodcutLevel = statChanged.getLevel(); + int newWoodcutLevel = statChanged.getBoostedLevel(); if (newWoodcutLevel != woodcuttingLevel) { woodcuttingLevel = newWoodcutLevel;