From ca377c719604f1ef396052eb17be2cf62ca0a5cd Mon Sep 17 00:00:00 2001 From: Lotto Date: Wed, 8 May 2019 00:42:55 +0200 Subject: [PATCH 01/17] xp tracker: display >1m exp with thousandths precision --- .../client/plugins/xptracker/XpInfoBox.java | 2 +- .../runelite/client/util/StackFormatter.java | 34 ++++++++++++++++++- .../client/util/StackFormatterTest.java | 25 ++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java index f6e4e77f27..4aac706e4f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java @@ -266,7 +266,7 @@ class XpInfoBox extends JPanel static String htmlLabel(String key, int value) { - String valueStr = StackFormatter.quantityToRSDecimalStack(value); + String valueStr = StackFormatter.quantityToRSDecimalStack(value, true); return String.format(HTML_LABEL_TEMPLATE, ColorUtil.toHexColor(ColorScheme.LIGHT_GRAY_COLOR), key, valueStr); } } diff --git a/runelite-client/src/main/java/net/runelite/client/util/StackFormatter.java b/runelite-client/src/main/java/net/runelite/client/util/StackFormatter.java index 40dda01a4e..c9282f7f46 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/StackFormatter.java +++ b/runelite-client/src/main/java/net/runelite/client/util/StackFormatter.java @@ -61,6 +61,14 @@ public class StackFormatter DecimalFormatSymbols.getInstance(Locale.ENGLISH) ); + /** + * A more precise decimal number formatter, outputting thousandths + */ + private static final NumberFormat PRECISE_DECIMAL_FORMATTER = new DecimalFormat( + "#,###.###", + DecimalFormatSymbols.getInstance(Locale.ENGLISH) + ); + /** * Convert a quantity to a nicely formatted stack size. * See the StackFormatterTest to see expected output. @@ -152,6 +160,24 @@ public class StackFormatter * with K after 100,000 and M after 10,000,000 */ public static String quantityToRSDecimalStack(int quantity) + { + return quantityToRSDecimalStack(quantity, false); + } + + /** + * Convert a quantity to stack size as it would + * appear in RuneScape. (with decimals) + *

+ * This differs from quantityToRSStack in that it displays + * decimals. Ex: 27100 is 27.1k (not 27k) + *

+ * + * @param quantity The quantity to convert. + * @param precise If true, the returned string will have thousandths precision if quantity is larger than 1 million. + * @return The stack size as it would appear in RS, with decimals, + * with K after 100,000 and M after 10,000,000 + */ + public static String quantityToRSDecimalStack(int quantity, boolean precise) { String quantityStr = String.valueOf(quantity); if (quantityStr.length() <= 4) @@ -160,7 +186,13 @@ public class StackFormatter } int power = (int) Math.log10(quantity); - return DECIMAL_FORMATTER.format(quantity / (Math.pow(10, (power / 3) * 3))) + SUFFIXES[power / 3]; + + // Output thousandths for values above a million + NumberFormat format = precise && power >= 6 + ? PRECISE_DECIMAL_FORMATTER + : DECIMAL_FORMATTER; + + return format.format(quantity / (Math.pow(10, (power / 3) * 3))) + SUFFIXES[power / 3]; } /** diff --git a/runelite-client/src/test/java/net/runelite/client/util/StackFormatterTest.java b/runelite-client/src/test/java/net/runelite/client/util/StackFormatterTest.java index 53a1c963d1..1e297a8513 100644 --- a/runelite-client/src/test/java/net/runelite/client/util/StackFormatterTest.java +++ b/runelite-client/src/test/java/net/runelite/client/util/StackFormatterTest.java @@ -97,6 +97,31 @@ public class StackFormatterTest assertEquals("-400B", StackFormatter.quantityToStackSize(-400_000_000_000L)); } + @Test + public void quantityToPreciseStackSize() + { + assertEquals("0", StackFormatter.quantityToRSDecimalStack(0)); + assertEquals("8500", StackFormatter.quantityToRSDecimalStack(8_500, true)); + assertEquals("10K", StackFormatter.quantityToRSDecimalStack(10_000, true)); + assertEquals("21.7K", StackFormatter.quantityToRSDecimalStack(21_710, true)); + assertEquals("100K", StackFormatter.quantityToRSDecimalStack(100_000, true)); + assertEquals("100.3K", StackFormatter.quantityToRSDecimalStack(100_310, true)); + assertEquals("1M", StackFormatter.quantityToRSDecimalStack(1_000_000, true)); + assertEquals("8.45M", StackFormatter.quantityToRSDecimalStack(8_450_000, true)); + assertEquals("8.451M", StackFormatter.quantityToRSDecimalStack(8_451_000, true)); + assertEquals("10M", StackFormatter.quantityToRSDecimalStack(10_000_000, true)); + assertEquals("12.8M", StackFormatter.quantityToRSDecimalStack(12_800_000, true)); + assertEquals("12.85M", StackFormatter.quantityToRSDecimalStack(12_850_000, true)); + assertEquals("12.851M", StackFormatter.quantityToRSDecimalStack(12_851_000, true)); + assertEquals("100M", StackFormatter.quantityToRSDecimalStack(100_000_000, true)); + assertEquals("250.1M", StackFormatter.quantityToRSDecimalStack(250_100_000, true)); + assertEquals("250.151M", StackFormatter.quantityToRSDecimalStack(250_151_000, true)); + assertEquals("1B", StackFormatter.quantityToRSDecimalStack(1_000_000_000, true)); + assertEquals("1.5B", StackFormatter.quantityToRSDecimalStack(1500_000_000, true)); + assertEquals("1.55B", StackFormatter.quantityToRSDecimalStack(1550_000_000, true)); + assertEquals("2.147B", StackFormatter.quantityToRSDecimalStack(Integer.MAX_VALUE, true)); + } + @Test public void stackSizeToQuantity() throws ParseException { From 85e787c8dd76fe9f7fb00c4ad670f14607c199fa Mon Sep 17 00:00:00 2001 From: John Kryspin Date: Thu, 9 May 2019 19:34:00 -0400 Subject: [PATCH 02/17] fishing plugin: fix trawler timer with one tick left --- .../net/runelite/client/plugins/fishing/FishingPlugin.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java index d27886c1aa..2f55bf8158 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingPlugin.java @@ -396,6 +396,11 @@ public class FishingPlugin extends Plugin } long timeLeft = TRAWLER_TIME_LIMIT_IN_SECONDS - Duration.between(trawlerStartTime, Instant.now()).getSeconds(); + if (timeLeft < 0) + { + timeLeft = 0; + } + int minutes = (int) timeLeft / 60; int seconds = (int) timeLeft % 60; From a92095b878c2ad24a476b39acd95d808f0f01f3e Mon Sep 17 00:00:00 2001 From: xdesr <49791189+xdesr@users.noreply.github.com> Date: Fri, 10 May 2019 13:16:44 +0100 Subject: [PATCH 03/17] Remove gray pixel from Dragon Scimitar cursor (#8725) --- .../customcursor/cursor-dragon-scimitar.png | Bin 570 -> 343 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/customcursor/cursor-dragon-scimitar.png b/runelite-client/src/main/resources/net/runelite/client/plugins/customcursor/cursor-dragon-scimitar.png index 1db7d1a0bc53d1e155c225adc800ad90ba3c51bb..b1a4bd230cac5b1b36fb65f26f1c254f766ace8e 100644 GIT binary patch delta 232 zcmVUY;AkBBTnbZmG^{QFkkajZovH?qvVIH%H>&R ibf&`R!VANH5W*XTYXy(6V+Uve0000(0r%1acITJ%W507^>757#dm_ z7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10A}YWq#1%+S)CsTOR&zfV$Yd-D@(X5g zcy=QV#7XjYcaeR~TsRTP;VkfoEC$jiz&QEW^R*zsvI56+Agut#?Z4*C1v1unx;Tbt zoUfgHlIf5FkIO_)rFB=Mx^MrlU*7V{RdPo`MWmWA$7%^HcEhqA46NoQZYws$VtlMF4J1$q2Jk?DU_qkqq#{9v* z{)x}qSI_!v?4RM&dcIYB*MEf;^F}AuzTM6R9-=^(tCqM%l%yn}$cBg+s2Ln~7gD+4oa0|P4qgHOlvK!JhKkei>9nO2EgL-VX_=Ybj+JYD@<);T3K F0RR;fpfUge From 637d305ceb992558f00923899c9e806dda126b3b Mon Sep 17 00:00:00 2001 From: Lotto Date: Sat, 11 May 2019 16:16:38 +0200 Subject: [PATCH 04/17] ui: add SplitComponent SplitComponent is a component containing two other components, with the area split between the two, either horizontally or vertically. Co-authored-by: Jasper Ketelaar --- .../blastfurnace/BlastFurnaceOverlay.java | 3 +- .../blastmine/BlastMineOreCountOverlay.java | 3 +- .../plugins/cerberus/CerberusOverlay.java | 3 +- .../InventoryViewerOverlay.java | 3 +- .../plugins/teamcapes/TeamCapesOverlay.java | 3 +- .../components/ComponentOrientation.java | 31 ++++++ .../ui/overlay/components/PanelComponent.java | 8 +- .../ui/overlay/components/SplitComponent.java | 105 ++++++++++++++++++ .../ui/overlay/infobox/InfoBoxOverlay.java | 5 +- 9 files changed, 150 insertions(+), 14 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ComponentOrientation.java create mode 100644 runelite-client/src/main/java/net/runelite/client/ui/overlay/components/SplitComponent.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BlastFurnaceOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BlastFurnaceOverlay.java index d57fd53fc9..48253cdfe3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BlastFurnaceOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BlastFurnaceOverlay.java @@ -35,6 +35,7 @@ import net.runelite.client.ui.overlay.Overlay; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.ImageComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -54,7 +55,7 @@ class BlastFurnaceOverlay extends Overlay this.plugin = plugin; this.client = client; setPosition(OverlayPosition.TOP_LEFT); - imagePanelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + imagePanelComponent.setOrientation(ComponentOrientation.HORIZONTAL); getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Blast furnace overlay")); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineOreCountOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineOreCountOverlay.java index d4566f89c8..f660eb2b63 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineOreCountOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineOreCountOverlay.java @@ -39,6 +39,7 @@ import net.runelite.client.ui.overlay.Overlay; import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.ImageComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -57,7 +58,7 @@ class BlastMineOreCountOverlay extends Overlay this.client = client; this.config = config; this.itemManager = itemManager; - panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + panelComponent.setOrientation(ComponentOrientation.HORIZONTAL); getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Blast mine overlay")); } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusOverlay.java index 5ddbf21f7a..2f384fcd80 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusOverlay.java @@ -31,6 +31,7 @@ import javax.inject.Singleton; import net.runelite.client.game.SkillIconManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.ImageComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -47,7 +48,7 @@ public class CerberusOverlay extends Overlay this.plugin = plugin; this.iconManager = iconManager; setPosition(OverlayPosition.BOTTOM_RIGHT); - panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + panelComponent.setOrientation(ComponentOrientation.HORIZONTAL); } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerOverlay.java index 71da3492aa..7162be5290 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/inventoryviewer/InventoryViewerOverlay.java @@ -37,6 +37,7 @@ import net.runelite.api.ItemContainer; import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.ImageComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -58,7 +59,7 @@ class InventoryViewerOverlay extends Overlay setPosition(OverlayPosition.BOTTOM_RIGHT); panelComponent.setWrapping(4); panelComponent.setGap(new Point(6, 4)); - panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + panelComponent.setOrientation(ComponentOrientation.HORIZONTAL); this.itemManager = itemManager; this.client = client; } 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 b5cc7858bf..9dbd2dc861 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 @@ -36,6 +36,7 @@ import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.OverlayPosition; import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.ImageComponent; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -55,7 +56,7 @@ public class TeamCapesOverlay extends Overlay this.plugin = plugin; this.config = config; this.manager = manager; - panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + panelComponent.setOrientation(ComponentOrientation.HORIZONTAL); panelComponent.setWrapping(4); getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Teamcapes overlay")); } diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ComponentOrientation.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ComponentOrientation.java new file mode 100644 index 0000000000..e06875e970 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ComponentOrientation.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018, Jasper Ketelaar + * 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.ui.overlay.components; + +public enum ComponentOrientation +{ + HORIZONTAL, + VERTICAL +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java index 5ea81f2006..6baf20985e 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/PanelComponent.java @@ -37,12 +37,6 @@ import lombok.Setter; public class PanelComponent implements LayoutableRenderableEntity { - public enum Orientation - { - HORIZONTAL, - VERTICAL; - } - @Getter private final Rectangle bounds = new Rectangle(); @@ -60,7 +54,7 @@ public class PanelComponent implements LayoutableRenderableEntity private final List children = new ArrayList<>(); @Setter - private Orientation orientation = Orientation.VERTICAL; + private ComponentOrientation orientation = ComponentOrientation.VERTICAL; @Setter private int wrapping = -1; diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/SplitComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/SplitComponent.java new file mode 100644 index 0000000000..2e77a7dde2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/SplitComponent.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2018, Jasper Ketelaar + * 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.ui.overlay.components; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Builder +public class SplitComponent implements LayoutableRenderableEntity +{ + private LayoutableRenderableEntity first; + private LayoutableRenderableEntity second; + + @Builder.Default + private Point preferredLocation = new Point(); + + @Builder.Default + private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0); + + @Builder.Default + private ComponentOrientation orientation = ComponentOrientation.VERTICAL; + + @Builder.Default + private Point gap = new Point(0, 0); + + @Builder.Default + @Getter + private final Rectangle bounds = new Rectangle(); + + @Override + public Dimension render(Graphics2D graphics) + { + graphics.translate(preferredLocation.x, preferredLocation.y); + first.setPreferredSize(preferredSize); + first.setPreferredLocation(new Point(0, 0)); + + final Dimension firstDimension = first.render(graphics); + int x = 0, y = 0; + + if (orientation == ComponentOrientation.VERTICAL) + { + y = firstDimension.height + gap.y; + } + else + { + x = firstDimension.width + gap.x; + } + + second.setPreferredLocation(new Point(x, y)); + // Make the second component fit to whatever size is left after the first component is rendered + second.setPreferredSize(new Dimension(preferredSize.width - x, preferredSize.height - y)); + + // The total width/height need to be determined as they are now always the same as the + // individual width/height (for example image width/height will just be the height of the image + // and not the height of the area the image is in + final Dimension secondDimension = second.render(graphics); + int totalWidth, totalHeight; + + if (orientation == ComponentOrientation.VERTICAL) + { + totalWidth = Math.max(firstDimension.width, secondDimension.width); + totalHeight = y + secondDimension.height; + } + else + { + totalHeight = Math.max(firstDimension.height, secondDimension.height); + totalWidth = x + secondDimension.width; + } + + graphics.translate(-preferredLocation.x, -preferredLocation.y); + + final Dimension dimension = new Dimension(totalWidth, totalHeight); + bounds.setLocation(preferredLocation); + bounds.setSize(dimension); + return dimension; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java index 58f20aae63..08412783f1 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/infobox/InfoBoxOverlay.java @@ -38,6 +38,7 @@ import net.runelite.api.Client; import net.runelite.client.config.RuneLiteConfig; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.InfoBoxComponent; import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity; import net.runelite.client.ui.overlay.components.PanelComponent; @@ -84,8 +85,8 @@ public class InfoBoxOverlay extends Overlay panelComponent.getChildren().clear(); panelComponent.setWrapping(config.infoBoxWrap()); panelComponent.setOrientation(config.infoBoxVertical() - ? PanelComponent.Orientation.VERTICAL - : PanelComponent.Orientation.HORIZONTAL); + ? ComponentOrientation.VERTICAL + : ComponentOrientation.HORIZONTAL); panelComponent.setPreferredSize(new Dimension(config.infoBoxSize(), config.infoBoxSize())); for (InfoBox box : infoBoxes) From 9a0d783bf9b8ae08f5d8a2d2e6836d610e27b91e Mon Sep 17 00:00:00 2001 From: Stephen Zhu Date: Mon, 15 Apr 2019 12:55:42 -0400 Subject: [PATCH 05/17] client: add smelting plugin Co-authored-by: Adam --- .../plugins/smelting/SmeltingConfig.java | 44 ++++++ .../plugins/smelting/SmeltingOverlay.java | 135 ++++++++++++++++++ .../plugins/smelting/SmeltingPlugin.java | 125 ++++++++++++++++ .../plugins/smelting/SmeltingSession.java | 53 +++++++ .../plugins/smelting/SmeltingPluginTest.java | 90 ++++++++++++ 5 files changed, 447 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingSession.java create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/smelting/SmeltingPluginTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingConfig.java new file mode 100644 index 0000000000..9671f29e1a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingConfig.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019, Stephen + * 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.smelting; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("smelting") +public interface SmeltingConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "statTimeout", + name = "Reset stats (minutes)", + description = "The time it takes for the current smelting session to be reset" + ) + default int statTimeout() + { + return 5; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java new file mode 100644 index 0000000000..7a49c00144 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingOverlay.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2019, Stephen + * 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.smelting; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.time.Duration; +import java.time.Instant; +import javax.inject.Inject; +import static net.runelite.api.AnimationID.SMITHING_CANNONBALL; +import static net.runelite.api.AnimationID.SMITHING_SMELTING; +import net.runelite.api.Client; +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import net.runelite.api.Skill; +import net.runelite.client.plugins.xptracker.XpTrackerService; +import net.runelite.client.ui.overlay.Overlay; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; +import net.runelite.client.ui.overlay.OverlayMenuEntry; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +class SmeltingOverlay extends Overlay +{ + private static final int SMELT_TIMEOUT = 5; + + private final Client client; + private final SmeltingPlugin plugin; + private final XpTrackerService xpTrackerService; + + private final PanelComponent panelComponent = new PanelComponent(); + + @Inject + SmeltingOverlay(Client client, SmeltingPlugin plugin, XpTrackerService xpTrackerService) + { + super(plugin); + this.client = client; + this.plugin = plugin; + this.xpTrackerService = xpTrackerService; + setPosition(OverlayPosition.TOP_LEFT); + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Smelting overlay")); + } + + @Override + public Dimension render(Graphics2D graphics) + { + SmeltingSession session = plugin.getSession(); + if (session == null) + { + return null; + } + + panelComponent.getChildren().clear(); + + if (isSmelting() || Duration.between(session.getLastItemSmelted(), Instant.now()).getSeconds() < SMELT_TIMEOUT) + { + panelComponent.getChildren().add(TitleComponent.builder() + .text("Smelting") + .color(Color.GREEN) + .build()); + } + else + { + panelComponent.getChildren().add(TitleComponent.builder() + .text("NOT smelting") + .color(Color.RED) + .build()); + } + + int actions = xpTrackerService.getActions(Skill.SMITHING); + if (actions > 0) + { + if (plugin.getSession().getBarsSmelted() > 0) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Bars:") + .right(Integer.toString(session.getBarsSmelted())) + .build()); + } + if (plugin.getSession().getCannonBallsSmelted() > 0) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Cannonballs:") + .right(Integer.toString(session.getCannonBallsSmelted())) + .build()); + } + if (actions > 2) + { + panelComponent.getChildren().add(LineComponent.builder() + .left("Actions/hr:") + .right(Integer.toString(xpTrackerService.getActionsHr(Skill.SMITHING))) + .build()); + } + } + + return panelComponent.render(graphics); + + } + + private boolean isSmelting() + { + switch (client.getLocalPlayer().getAnimation()) + { + case SMITHING_SMELTING: + case SMITHING_CANNONBALL: + return true; + default: + return false; + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java new file mode 100644 index 0000000000..21a3b5440b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingPlugin.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019, Stephen + * 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.smelting; + +import com.google.inject.Provides; +import java.time.Duration; +import java.time.Instant; +import javax.inject.Inject; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.ChatMessageType; +import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameTick; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDependency; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.xptracker.XpTrackerPlugin; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "Smelting", + description = "Show Smelting stats", + tags = {"overlay", "skilling"} +) +@PluginDependency(XpTrackerPlugin.class) +public class SmeltingPlugin extends Plugin +{ + @Inject + private SmeltingConfig config; + + @Inject + private SmeltingOverlay overlay; + + @Inject + private OverlayManager overlayManager; + + @Getter(AccessLevel.PACKAGE) + private SmeltingSession session; + + @Provides + SmeltingConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(SmeltingConfig.class); + } + + @Override + protected void startUp() + { + session = null; + overlayManager.add(overlay); + } + + @Override + protected void shutDown() + { + overlayManager.remove(overlay); + session = null; + } + + @Subscribe + public void onChatMessage(ChatMessage event) + { + if (event.getType() != ChatMessageType.SPAM) + { + return; + } + + if (event.getMessage().startsWith("You retrieve a bar of")) + { + if (session == null) + { + session = new SmeltingSession(); + } + session.increaseBarsSmelted(); + } + else if (event.getMessage().startsWith("You remove the cannonballs from the mould")) + { + if (session == null) + { + session = new SmeltingSession(); + } + session.increaseCannonBallsSmelted(); + } + } + + @Subscribe + public void onGameTick(GameTick event) + { + if (session != null) + { + final Duration statTimeout = Duration.ofMinutes(config.statTimeout()); + final Duration sinceCaught = Duration.between(session.getLastItemSmelted(), Instant.now()); + + if (sinceCaught.compareTo(statTimeout) >= 0) + { + session = null; + } + } + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingSession.java b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingSession.java new file mode 100644 index 0000000000..b49cfff6c0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/smelting/SmeltingSession.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, Stephen + * 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.smelting; + +import java.time.Instant; +import lombok.AccessLevel; +import lombok.Getter; + +class SmeltingSession +{ + @Getter(AccessLevel.PACKAGE) + private int barsSmelted; + + @Getter(AccessLevel.PACKAGE) + private int cannonBallsSmelted; + + @Getter(AccessLevel.PACKAGE) + private Instant lastItemSmelted; + + void increaseBarsSmelted() + { + barsSmelted++; + lastItemSmelted = Instant.now(); + } + + void increaseCannonBallsSmelted() + { + cannonBallsSmelted += 4; + lastItemSmelted = Instant.now(); + } +} \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/smelting/SmeltingPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/smelting/SmeltingPluginTest.java new file mode 100644 index 0000000000..1c8573f26c --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/smelting/SmeltingPluginTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2019, Stephen + * 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.smelting; + +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.ChatMessageType; +import net.runelite.api.events.ChatMessage; +import net.runelite.client.ui.overlay.OverlayManager; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class SmeltingPluginTest +{ + private static final String SMELT_CANNONBALL = "You remove the cannonballs from the mould"; + private static final String SMELT_BAR = "You retrieve a bar of steel."; + + @Inject + SmeltingPlugin smeltingPlugin; + + @Mock + @Bind + SmeltingConfig config; + + @Mock + @Bind + SmeltingOverlay smeltingOverlay; + + @Mock + @Bind + OverlayManager overlayManager; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testCannonballs() + { + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", SMELT_CANNONBALL, "", 0); + smeltingPlugin.onChatMessage(chatMessage); + + SmeltingSession smeltingSession = smeltingPlugin.getSession(); + assertNotNull(smeltingSession); + assertEquals(4, smeltingSession.getCannonBallsSmelted()); + } + + @Test + public void testBars() + { + ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", SMELT_BAR, "", 0); + smeltingPlugin.onChatMessage(chatMessage); + + SmeltingSession smeltingSession = smeltingPlugin.getSession(); + assertNotNull(smeltingSession); + assertEquals(1, smeltingSession.getBarsSmelted()); + } +} From 9623ed4b3068534d152cc17d1b2aedb2c9c561eb Mon Sep 17 00:00:00 2001 From: seandewar <6256228+seandewar@users.noreply.github.com> Date: Fri, 10 May 2019 18:46:02 +0100 Subject: [PATCH 06/17] constants: add GAME_TICK_LENGTH and use where needed Also update many usages of 20ms to CLIENT_TICK_LENGTH --- .../src/main/java/net/runelite/api/Constants.java | 8 ++++++++ .../src/main/java/net/runelite/client/callback/Hooks.java | 3 ++- .../runelite/client/plugins/antidrag/AntiDragConfig.java | 3 ++- .../client/plugins/barbarianassault/GameTimer.java | 3 ++- .../runelite/client/plugins/barbarianassault/Round.java | 3 ++- .../net/runelite/client/plugins/boosts/BoostsPlugin.java | 3 ++- .../client/plugins/idlenotifier/IdleNotifierPlugin.java | 6 ++++-- .../client/plugins/npchighlight/NpcSceneOverlay.java | 6 ++---- .../java/net/runelite/client/plugins/poh/PohPlugin.java | 7 ++++--- .../runelite/client/plugins/prayer/PrayerDoseOverlay.java | 3 ++- .../net/runelite/client/plugins/prayer/PrayerPlugin.java | 3 ++- .../client/plugins/runenergy/RunEnergyPlugin.java | 5 +++-- 12 files changed, 35 insertions(+), 18 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/Constants.java b/runelite-api/src/main/java/net/runelite/api/Constants.java index b1cfde8dde..ffb2c1ba66 100644 --- a/runelite-api/src/main/java/net/runelite/api/Constants.java +++ b/runelite-api/src/main/java/net/runelite/api/Constants.java @@ -89,4 +89,12 @@ public class Constants * the maximum framerate of 50 fps. */ public static final int CLIENT_TICK_LENGTH = 20; + + /** + * The number of milliseconds in a server game tick. + *

+ * This is the length of a single game cycle under ideal conditions. + * All game-play actions operate within multiples of this duration. + */ + public static final int GAME_TICK_LENGTH = 600; } diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index fea751ffcf..12de2c567b 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -42,6 +42,7 @@ import javax.inject.Singleton; import lombok.extern.slf4j.Slf4j; import net.runelite.api.BufferProvider; import net.runelite.api.Client; +import net.runelite.api.Constants; import net.runelite.api.MainBufferProvider; import net.runelite.api.NullItemID; import net.runelite.api.RenderOverview; @@ -79,7 +80,7 @@ import net.runelite.client.util.DeferredEventBus; @Slf4j public class Hooks implements Callbacks { - private static final long CHECK = 600; // ms - how often to run checks + private static final long CHECK = Constants.GAME_TICK_LENGTH; // ms - how often to run checks private static final Injector injector = RuneLite.getInjector(); private static final Client client = injector.getInstance(Client.class); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java index 1bed02603e..01767c5b4e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/antidrag/AntiDragConfig.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.antidrag; +import net.runelite.api.Constants; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -39,6 +40,6 @@ public interface AntiDragConfig extends Config ) default int dragDelay() { - return 600 / 20; // one game tick + return Constants.GAME_TICK_LENGTH / Constants.CLIENT_TICK_LENGTH; // one game tick } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/GameTimer.java index 6ed8c4957c..1aae11adbd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/GameTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/GameTimer.java @@ -28,6 +28,7 @@ import java.time.Duration; import java.time.Instant; import java.time.LocalTime; import java.time.format.DateTimeFormatter; +import net.runelite.api.Constants; class GameTimer { @@ -45,7 +46,7 @@ class GameTimer } else { - elapsed = Duration.between(startTime, now).minusMillis(600); + elapsed = Duration.between(startTime, now).minusMillis(Constants.GAME_TICK_LENGTH); } return formatTime(LocalTime.ofSecondOfDay(elapsed.getSeconds())); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Round.java b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Round.java index 7da563d9cd..4428d504b4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Round.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barbarianassault/Round.java @@ -29,6 +29,7 @@ import java.time.Instant; import javax.inject.Inject; import lombok.Getter; import lombok.Setter; +import net.runelite.api.Constants; class Round { @@ -52,7 +53,7 @@ class Round public Round(Role role) { this.roundRole = role; - this.roundStartTime = Instant.now().plusMillis(1200); + this.roundStartTime = Instant.now().plusMillis(2 * Constants.GAME_TICK_LENGTH); } public long getRoundTime() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java index 4f09b12a8b..1962320efb 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/boosts/BoostsPlugin.java @@ -33,6 +33,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import lombok.Getter; import net.runelite.api.Client; +import net.runelite.api.Constants; import net.runelite.api.Prayer; import net.runelite.api.Skill; import net.runelite.api.events.BoostedLevelChanged; @@ -372,6 +373,6 @@ public class BoostsPlugin extends Plugin int getChangeTime(final int time) { final long diff = System.currentTimeMillis() - lastTickMillis; - return time != -1 ? (int)(time * 0.6 - (diff / 1000d)) : time; + return time != -1 ? (int)((time * Constants.GAME_TICK_LENGTH - diff) / 1000d) : time; } } 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 129f7a26e9..bb7dee8b47 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 @@ -35,6 +35,7 @@ import net.runelite.api.Actor; import net.runelite.api.AnimationID; import static net.runelite.api.AnimationID.*; import net.runelite.api.Client; +import net.runelite.api.Constants; import net.runelite.api.GameState; import net.runelite.api.GraphicID; import net.runelite.api.Hitsplat; @@ -64,9 +65,10 @@ import net.runelite.client.plugins.PluginDescriptor; public class IdleNotifierPlugin extends Plugin { // This must be more than 500 client ticks (10 seconds) before you get AFK kicked - private static final int LOGOUT_WARNING_CLIENT_TICKS = ((4 * 60) + 40) * 50;// 4 minutes and 40 seconds + private static final int LOGOUT_WARNING_MILLIS = (4 * 60 + 40) * 1000; // 4 minutes and 40 seconds private static final int COMBAT_WARNING_MILLIS = 19 * 60 * 1000; // 19 minutes - private static final int COMBAT_WARNING_CLIENT_TICKS = COMBAT_WARNING_MILLIS / 20; + private static final int LOGOUT_WARNING_CLIENT_TICKS = LOGOUT_WARNING_MILLIS / Constants.CLIENT_TICK_LENGTH; + private static final int COMBAT_WARNING_CLIENT_TICKS = COMBAT_WARNING_MILLIS / Constants.CLIENT_TICK_LENGTH; private static final int HIGHEST_MONSTER_ATTACK_SPEED = 8; // Except Scarab Mage, but they are with other monsters private static final Duration SIX_HOUR_LOGOUT_WARNING_AFTER_DURATION = Duration.ofMinutes(340); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java index 6c41b2f24d..9e87b3f278 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcSceneOverlay.java @@ -36,6 +36,7 @@ import java.time.Instant; import java.util.Locale; import javax.inject.Inject; import net.runelite.api.Client; +import net.runelite.api.Constants; import net.runelite.api.NPC; import net.runelite.api.NPCComposition; import net.runelite.api.Perspective; @@ -54,9 +55,6 @@ public class NpcSceneOverlay extends Overlay // a dark background private static final Color TEXT_COLOR = Color.WHITE; - // Estimated time of a game tick in seconds - private static final double ESTIMATED_TICK_LENGTH = 0.6; - private static final NumberFormat TIME_LEFT_FORMATTER = DecimalFormat.getInstance(Locale.US); static @@ -123,7 +121,7 @@ public class NpcSceneOverlay extends Overlay } final Instant now = Instant.now(); - final double baseTick = ((npc.getDiedOnTick() + npc.getRespawnTime()) - client.getTickCount()) * ESTIMATED_TICK_LENGTH; + final double baseTick = ((npc.getDiedOnTick() + npc.getRespawnTime()) - client.getTickCount()) * (Constants.GAME_TICK_LENGTH / 1000.0); final double sinceLast = (now.toEpochMilli() - plugin.getLastTickUpdate().toEpochMilli()) / 1000.0; final double timeLeft = Math.max(0.0, baseTick - sinceLast); final String timeLeftStr = TIME_LEFT_FORMATTER.format(timeLeft); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java index 03a3f02729..04df91d05c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohPlugin.java @@ -39,6 +39,7 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Actor; import net.runelite.api.AnimationID; import net.runelite.api.Client; +import net.runelite.api.Constants; import net.runelite.api.DecorativeObject; import net.runelite.api.GameObject; import net.runelite.api.GameState; @@ -74,7 +75,6 @@ public class PohPlugin extends Plugin { static final Set BURNER_UNLIT = Sets.newHashSet(ObjectID.INCENSE_BURNER, ObjectID.INCENSE_BURNER_13210, ObjectID.INCENSE_BURNER_13212); static final Set BURNER_LIT = Sets.newHashSet(ObjectID.INCENSE_BURNER_13209, ObjectID.INCENSE_BURNER_13211, ObjectID.INCENSE_BURNER_13213); - private static final double ESTIMATED_TICK_LENGTH = 0.6; @Getter(AccessLevel.PACKAGE) private final Map pohObjects = new HashMap<>(); @@ -243,7 +243,8 @@ public class PohPlugin extends Plugin private static void updateBurner(IncenseBurner incenseBurner, int fmLevel) { - incenseBurner.setCountdownTimer((200 + fmLevel) * ESTIMATED_TICK_LENGTH); - incenseBurner.setRandomTimer(fmLevel * ESTIMATED_TICK_LENGTH); + final double tickLengthSeconds = Constants.GAME_TICK_LENGTH / 1000.0; + incenseBurner.setCountdownTimer((200 + fmLevel) * tickLengthSeconds); + incenseBurner.setRandomTimer(fmLevel * tickLengthSeconds); } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java index 6798d4e545..ab1d91fb16 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerDoseOverlay.java @@ -35,6 +35,7 @@ import javax.inject.Inject; import lombok.AccessLevel; import lombok.Setter; import net.runelite.api.Client; +import net.runelite.api.Constants; import net.runelite.api.Point; import net.runelite.api.Prayer; import net.runelite.api.Skill; @@ -50,7 +51,7 @@ import org.apache.commons.lang3.StringUtils; class PrayerDoseOverlay extends Overlay { - private static final float PULSE_TIME = 1200f; + private static final float PULSE_TIME = 2f * Constants.GAME_TICK_LENGTH; private static final Color START_COLOR = new Color(0, 255, 255); private static final Color END_COLOR = new Color(0, 92, 92); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java index 04b7ec194c..2755703f8f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerPlugin.java @@ -32,6 +32,7 @@ import javax.inject.Inject; import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.Client; +import net.runelite.api.Constants; import net.runelite.api.InventoryID; import net.runelite.api.Item; import net.runelite.api.ItemContainer; @@ -268,7 +269,7 @@ public class PrayerPlugin extends Plugin { long timeSinceLastTick = Duration.between(startOfLastTick, Instant.now()).toMillis(); - float tickProgress = (timeSinceLastTick % 600) / 600f; + float tickProgress = (timeSinceLastTick % Constants.GAME_TICK_LENGTH) / (float) Constants.GAME_TICK_LENGTH; return tickProgress * Math.PI; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runenergy/RunEnergyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/runenergy/RunEnergyPlugin.java index 7cef60a826..fff84a100d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runenergy/RunEnergyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runenergy/RunEnergyPlugin.java @@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; import javax.inject.Inject; import net.runelite.api.Client; +import net.runelite.api.Constants; import net.runelite.api.EquipmentInventorySlot; import net.runelite.api.InventoryID; import net.runelite.api.Item; @@ -171,7 +172,7 @@ public class RunEnergyPlugin extends Plugin String getEstimatedRunTimeRemaining(boolean inSeconds) { - // Calculate the amount of energy lost every 2 ticks (0.6 seconds). + // Calculate the amount of energy lost every tick. // Negative weight has the same depletion effect as 0 kg. final int effectiveWeight = Math.max(client.getWeight(), 0); double lossRate = (Math.min(effectiveWeight, 64) / 100.0) + 0.64; @@ -182,7 +183,7 @@ public class RunEnergyPlugin extends Plugin } // Calculate the number of seconds left - final double secondsLeft = (client.getEnergy() * 0.6) / lossRate; + final double secondsLeft = (client.getEnergy() * Constants.GAME_TICK_LENGTH) / (lossRate * 1000.0); // Return the text if (inSeconds) From a8728b9b566e330c3b75aaca9ba142c1bd0ef85e Mon Sep 17 00:00:00 2001 From: seandewar <6256228+seandewar@users.noreply.github.com> Date: Wed, 8 May 2019 04:11:25 +0100 Subject: [PATCH 07/17] regenmeter: add option to notify before next hp regen --- .../plugins/regenmeter/RegenMeterConfig.java | 10 ++++++++ .../plugins/regenmeter/RegenMeterPlugin.java | 23 +++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterConfig.java index b3b4dd546c..2e8b577381 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterConfig.java @@ -57,4 +57,14 @@ public interface RegenMeterConfig extends Config { return false; } + + @ConfigItem( + keyName = "notifyBeforeHpRegenDuration", + name = "Hitpoint Regen Notification (seconds)", + description = "Notify approximately when your next hitpoint is about to regen. A value of 0 will disable notification." + ) + default int getNotifyBeforeHpRegenSeconds() + { + return 0; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterPlugin.java index 8620b7fac3..004441b6e3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/regenmeter/RegenMeterPlugin.java @@ -1,5 +1,6 @@ /* - * Copyright (c) 2018 Abex + * Copyright (c) 2019, Sean Dewar + * Copyright (c) 2018, Abex * Copyright (c) 2018, Zimaya * Copyright (c) 2017, Adam * All rights reserved. @@ -30,6 +31,7 @@ import com.google.inject.Provides; import javax.inject.Inject; import lombok.Getter; import net.runelite.api.Client; +import net.runelite.api.Constants; import net.runelite.api.GameState; import net.runelite.api.Prayer; import net.runelite.api.Skill; @@ -37,6 +39,7 @@ import net.runelite.api.VarPlayer; import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.VarbitChanged; +import net.runelite.client.Notifier; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; @@ -46,7 +49,7 @@ import net.runelite.client.ui.overlay.OverlayManager; @PluginDescriptor( name = "Regeneration Meter", description = "Track and show the hitpoints and special attack regeneration timers", - tags = {"combat", "health", "hitpoints", "special", "attack", "overlay"} + tags = {"combat", "health", "hitpoints", "special", "attack", "overlay", "notifications"} ) public class RegenMeterPlugin extends Plugin { @@ -59,6 +62,9 @@ public class RegenMeterPlugin extends Plugin @Inject private OverlayManager overlayManager; + @Inject + private Notifier notifier; + @Inject private RegenMeterOverlay overlay; @@ -149,5 +155,18 @@ public class RegenMeterPlugin extends Plugin // Show it going down hitpointsPercentage = 1 - hitpointsPercentage; } + + if (config.getNotifyBeforeHpRegenSeconds() > 0 && currentHP < maxHP && shouldNotifyHpRegenThisTick(ticksPerHPRegen)) + { + notifier.notify("[" + client.getLocalPlayer().getName() + "] regenerates their next hitpoint soon!"); + } + } + + private boolean shouldNotifyHpRegenThisTick(int ticksPerHPRegen) + { + // if the configured duration lies between two ticks, choose the earlier tick + final int ticksBeforeHPRegen = ticksPerHPRegen - ticksSinceHPRegen; + final int notifyTick = (int) Math.ceil(config.getNotifyBeforeHpRegenSeconds() * 1000d / Constants.GAME_TICK_LENGTH); + return ticksBeforeHPRegen == notifyTick; } } From 1bfffb7c9d400aa809353754c1f246e7262cad18 Mon Sep 17 00:00:00 2001 From: Ryan H Date: Fri, 3 May 2019 20:25:28 -0400 Subject: [PATCH 08/17] barrows plugin: add prayer drain timer --- .../client/plugins/barrows/BarrowsConfig.java | 11 +++ .../client/plugins/barrows/BarrowsPlugin.java | 55 +++++++++++++ .../barrows/BarrowsPrayerDrainTimer.java | 77 +++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPrayerDrainTimer.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsConfig.java index 41f2bbc67d..663e03fbb3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsConfig.java @@ -97,4 +97,15 @@ public interface BarrowsConfig extends Config { return true; } + + @ConfigItem( + keyName = "showPrayerDrainTimer", + name = "Show Prayer Drain Timer", + description = "Configure whether or not a countdown until the next prayer drain is displayed", + position = 6 + ) + default boolean showPrayerDrainTimer() + { + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java index bc505755ff..72bf08fe7e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPlugin.java @@ -42,6 +42,7 @@ import net.runelite.api.ItemContainer; import net.runelite.api.NullObjectID; import net.runelite.api.ObjectID; import net.runelite.api.WallObject; +import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.GameObjectChanged; import net.runelite.api.events.GameObjectDespawned; import net.runelite.api.events.GameObjectSpawned; @@ -60,9 +61,11 @@ import net.runelite.client.chat.QueuedMessage; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.ItemManager; +import net.runelite.client.game.SpriteManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.StackFormatter; @PluginDescriptor( @@ -89,12 +92,16 @@ public class BarrowsPlugin extends Plugin WidgetInfo.BARROWS_PUZZLE_ANSWER3 ); + private static final int CRYPT_REGION_ID = 14231; + @Getter(AccessLevel.PACKAGE) private final Set walls = new HashSet<>(); @Getter(AccessLevel.PACKAGE) private final Set ladders = new HashSet<>(); + private boolean wasInCrypt = false; + @Getter private Widget puzzleAnswer; @@ -113,6 +120,12 @@ public class BarrowsPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private SpriteManager spriteManager; + + @Inject + private InfoBoxManager infoBoxManager; + @Inject private ChatMessageManager chatMessageManager; @@ -140,6 +153,8 @@ public class BarrowsPlugin extends Plugin walls.clear(); ladders.clear(); puzzleAnswer = null; + wasInCrypt = false; + stopPrayerDrainTimer(); // Restore widgets final Widget potential = client.getWidget(WidgetInfo.BARROWS_POTENTIAL); @@ -155,6 +170,15 @@ public class BarrowsPlugin extends Plugin } } + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals("barrows") && !config.showPrayerDrainTimer()) + { + stopPrayerDrainTimer(); + } + } + @Subscribe public void onWallObjectSpawned(WallObjectSpawned event) { @@ -220,11 +244,24 @@ public class BarrowsPlugin extends Plugin { if (event.getGameState() == GameState.LOADING) { + wasInCrypt = isInCrypt(); // on region changes the tiles get set to null walls.clear(); ladders.clear(); puzzleAnswer = null; } + else if (event.getGameState() == GameState.LOGGED_IN) + { + boolean isInCrypt = isInCrypt(); + if (wasInCrypt && !isInCrypt) + { + stopPrayerDrainTimer(); + } + else if (!wasInCrypt && isInCrypt) + { + startPrayerDrainTimer(); + } + } } @Subscribe @@ -271,4 +308,22 @@ public class BarrowsPlugin extends Plugin } } } + + private void startPrayerDrainTimer() + { + if (config.showPrayerDrainTimer()) + { + infoBoxManager.addInfoBox(new BarrowsPrayerDrainTimer(this, spriteManager)); + } + } + + private void stopPrayerDrainTimer() + { + infoBoxManager.removeIf(BarrowsPrayerDrainTimer.class::isInstance); + } + + private boolean isInCrypt() + { + return client.getLocalPlayer().getWorldLocation().getRegionID() == CRYPT_REGION_ID; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPrayerDrainTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPrayerDrainTimer.java new file mode 100644 index 0000000000..4428a54f07 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/barrows/BarrowsPrayerDrainTimer.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019, Ryan + * 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.barrows; + +import java.awt.Color; +import java.time.Duration; +import java.time.Instant; +import net.runelite.api.SpriteID; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.ui.overlay.infobox.InfoBox; +import net.runelite.client.ui.overlay.infobox.InfoBoxPriority; + +class BarrowsPrayerDrainTimer extends InfoBox +{ + private static final long PRAYER_DRAIN_INTERVAL_MS = 18200; + + private final Instant startTime; + + BarrowsPrayerDrainTimer(BarrowsPlugin plugin, SpriteManager spriteManager) + { + super(spriteManager.getSprite(SpriteID.TAB_PRAYER, 0), plugin); + setPriority(InfoBoxPriority.MED); + setTooltip("Prayer Drain"); + startTime = Instant.now(); + } + + @Override + public String getText() + { + Duration timeLeft = Duration.between(Instant.now(), getNextPrayerDrainTime()); + int seconds = (int) (timeLeft.toMillis() / 1000L); + return String.format("0:%02d", seconds); + } + + @Override + public Color getTextColor() + { + Duration timeLeft = Duration.between(Instant.now(), getNextPrayerDrainTime()); + + //check if timer has 10% of time left + if (timeLeft.getSeconds() < (PRAYER_DRAIN_INTERVAL_MS / 1000 * .10)) + { + return Color.RED.brighter(); + } + + return Color.WHITE; + } + + private Instant getNextPrayerDrainTime() + { + Duration timePassed = Duration.between(startTime, Instant.now()); + // Get how many intervals have passed so far and add one more to find the next prayer drain time + return startTime.plusMillis((timePassed.toMillis() / PRAYER_DRAIN_INTERVAL_MS + 1) * PRAYER_DRAIN_INTERVAL_MS); + } +} From 78bf68e03639bd0f7be733e9ae794f3bfe6c68eb Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 May 2019 19:56:47 -0400 Subject: [PATCH 09/17] chat: ensure queued messages are always cleared after adding Mark queued message type as non null because addChatMessage will throw if it is. This was causing the client to get stuck trying to add the same broken message each loop. --- .../net/runelite/client/chat/ChatMessageManager.java | 10 ++++++++-- .../java/net/runelite/client/chat/QueuedMessage.java | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java index bc0d3bc58a..da4c222fd6 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/ChatMessageManager.java @@ -548,8 +548,14 @@ public class ChatMessageManager { if (!queuedMessages.isEmpty()) { - queuedMessages.forEach(this::add); - queuedMessages.clear(); + try + { + queuedMessages.forEach(this::add); + } + finally + { + queuedMessages.clear(); + } } } diff --git a/runelite-client/src/main/java/net/runelite/client/chat/QueuedMessage.java b/runelite-client/src/main/java/net/runelite/client/chat/QueuedMessage.java index 9c88826af7..f89ce84b43 100644 --- a/runelite-client/src/main/java/net/runelite/client/chat/QueuedMessage.java +++ b/runelite-client/src/main/java/net/runelite/client/chat/QueuedMessage.java @@ -26,12 +26,14 @@ package net.runelite.client.chat; import lombok.Builder; import lombok.Data; +import lombok.NonNull; import net.runelite.api.ChatMessageType; @Data @Builder public class QueuedMessage { + @NonNull private final ChatMessageType type; private final String value; private String name; From 6165bfabdff33be84e24df9477212a132db9b618 Mon Sep 17 00:00:00 2001 From: Lotto Date: Tue, 7 May 2019 01:07:26 +0200 Subject: [PATCH 10/17] xp tracker: show on canvas Co-authored-by: Jasper Ketelaar --- .../client/plugins/xptracker/XpInfoBox.java | 20 +++ .../plugins/xptracker/XpInfoBoxOverlay.java | 129 ++++++++++++++++++ .../plugins/xptracker/XpTrackerPlugin.java | 30 +++- .../ui/overlay/components/SplitComponent.java | 7 +- 4 files changed, 180 insertions(+), 6 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java index f6e4e77f27..7846807341 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBox.java @@ -67,6 +67,9 @@ class XpInfoBox extends JPanel private static final String HTML_LABEL_TEMPLATE = "%s%s"; + private static final String REMOVE_STATE = "Remove from canvas"; + private static final String ADD_STATE = "Add to canvas"; + // Instance members private final JPanel panel; @@ -89,6 +92,7 @@ class XpInfoBox extends JPanel private final JLabel expLeft = new JLabel(); private final JLabel actionsLeft = new JLabel(); private final JMenuItem pauseSkill = new JMenuItem("Pause"); + private final JMenuItem canvasItem = new JMenuItem(ADD_STATE); private final XpTrackerConfig xpTrackerConfig; @@ -128,6 +132,21 @@ class XpInfoBox extends JPanel popupMenu.add(reset); popupMenu.add(resetOthers); popupMenu.add(pauseSkill); + popupMenu.add(canvasItem); + + canvasItem.addActionListener(e -> + { + if (canvasItem.getText().equals(REMOVE_STATE)) + { + xpTrackerPlugin.removeOverlay(skill); + canvasItem.setText(ADD_STATE); + } + else + { + xpTrackerPlugin.addOverlay(skill); + canvasItem.setText(REMOVE_STATE); + } + }); JLabel skillIcon = new JLabel(new ImageIcon(iconManager.getSkillImage(skill))); skillIcon.setHorizontalAlignment(SwingConstants.CENTER); @@ -177,6 +196,7 @@ class XpInfoBox extends JPanel void reset() { + canvasItem.setText(ADD_STATE); container.remove(statsPanel); panel.remove(this); panel.revalidate(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java new file mode 100644 index 0000000000..99c5880901 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2018, Jasper Ketelaar + * 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.xptracker; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import lombok.AccessLevel; +import lombok.Getter; +import net.runelite.api.Skill; +import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.components.ComponentOrientation; +import net.runelite.client.ui.overlay.components.ImageComponent; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.ProgressBarComponent; +import net.runelite.client.ui.overlay.components.SplitComponent; +import net.runelite.client.util.StackFormatter; + +class XpInfoBoxOverlay extends Overlay +{ + private static final int PANEL_PREFERRED_WIDTH = 150; + private static final int BORDER_SIZE = 2; + private static final int XP_AND_PROGRESS_BAR_GAP = 2; + private static final int XP_AND_ICON_GAP = 4; + private static final Rectangle XP_AND_ICON_COMPONENT_BORDER = new Rectangle(2, 1, 4, 0); + + private final PanelComponent panel = new PanelComponent(); + private final PanelComponent iconXpSplitPanel = new PanelComponent(); + private final XpTrackerPlugin plugin; + + @Getter(AccessLevel.PACKAGE) + private final Skill skill; + private final BufferedImage icon; + + XpInfoBoxOverlay( + XpTrackerPlugin plugin, + Skill skill, + BufferedImage icon) + { + super(plugin); + this.plugin = plugin; + this.skill = skill; + this.icon = icon; + panel.setBorder(new Rectangle(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); + panel.setGap(new Point(0, XP_AND_PROGRESS_BAR_GAP)); + panel.setPreferredSize(new Dimension(PANEL_PREFERRED_WIDTH, 0)); + iconXpSplitPanel.setBorder(XP_AND_ICON_COMPONENT_BORDER); + iconXpSplitPanel.setBackgroundColor(null); + iconXpSplitPanel.setPreferredSize(new Dimension(PANEL_PREFERRED_WIDTH, 0)); + } + + @Override + public Dimension render(Graphics2D graphics) + { + panel.getChildren().clear(); + iconXpSplitPanel.getChildren().clear(); + + //Setting the font to rs small font so that the overlay isn't huge + graphics.setFont(FontManager.getRunescapeSmallFont()); + + final XpSnapshotSingle snapshot = plugin.getSkillSnapshot(skill); + + final LineComponent xpLine = LineComponent.builder() + .left("XP Gained:") + .right(StackFormatter.quantityToRSDecimalStack(snapshot.getXpGainedInSession())) + .build(); + + final LineComponent xpHour = LineComponent.builder() + .left("XP/Hour:") + .right(StackFormatter.quantityToRSDecimalStack(snapshot.getXpPerHour())) + .build(); + + final SplitComponent xpSplit = SplitComponent.builder() + .first(xpLine) + .second(xpHour) + .orientation(ComponentOrientation.VERTICAL) + .build(); + + final ImageComponent imageComponent = new ImageComponent(icon); + final SplitComponent iconXpSplit = SplitComponent.builder() + .first(imageComponent) + .second(xpSplit) + .orientation(ComponentOrientation.HORIZONTAL) + .gap(new Point(XP_AND_ICON_GAP, 0)) + .build(); + + iconXpSplitPanel.getChildren().add(iconXpSplit); + + final ProgressBarComponent progressBarComponent = new ProgressBarComponent(); + progressBarComponent.setValue(snapshot.getSkillProgressToGoal()); + + panel.getChildren().add(iconXpSplitPanel); + panel.getChildren().add(progressBarComponent); + + return panel.render(graphics); + } + + @Override + public String getName() + { + return super.getName() + skill.getName(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index a8d65962a5..8f08b0ba7b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -59,6 +59,7 @@ import static net.runelite.client.plugins.xptracker.XpWorldType.NORMAL; import net.runelite.client.task.Schedule; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; +import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ImageUtil; import net.runelite.http.api.xp.XpClient; @@ -98,6 +99,9 @@ public class XpTrackerPlugin extends Plugin @Inject private NPCManager npcManager; + @Inject + private OverlayManager overlayManager; + private NavigationButton navButton; private XpPanel xpPanel; private XpWorldType lastWorldType; @@ -142,6 +146,7 @@ public class XpTrackerPlugin extends Plugin @Override protected void shutDown() throws Exception { + overlayManager.removeIf(e -> e instanceof XpInfoBoxOverlay); xpState.reset(); clientToolbar.removeNavigation(navButton); } @@ -208,6 +213,27 @@ public class XpTrackerPlugin extends Plugin return xpType; } + /** + * Adds an overlay to the canvas for tracking a specific skill. + * + * @param skill the skill for which the overlay should be added + */ + void addOverlay(Skill skill) + { + removeOverlay(skill); + overlayManager.add(new XpInfoBoxOverlay(this, skill, skillIconManager.getSkillImage(skill))); + } + + /** + * Removes an overlay from the overlayManager if it's present. + * + * @param skill the skill for which the overlay should be removed. + */ + void removeOverlay(Skill skill) + { + overlayManager.removeIf(e -> e instanceof XpInfoBoxOverlay && ((XpInfoBoxOverlay) e).getSkill() == skill); + } + /** * Reset internal state and re-initialize all skills with XP currently cached by the RS client * This is called by the user manually clicking resetSkillState in the UI. @@ -230,6 +256,7 @@ public class XpTrackerPlugin extends Plugin } xpState.initializeSkill(skill, currentXp); + removeOverlay(skill); } } @@ -242,6 +269,7 @@ public class XpTrackerPlugin extends Plugin xpState.reset(); xpPanel.resetAllInfoBoxes(); xpPanel.updateTotal(new XpSnapshotSingle.XpSnapshotSingleBuilder().build()); + overlayManager.removeIf(e -> e instanceof XpInfoBoxOverlay); } /** @@ -254,6 +282,7 @@ public class XpTrackerPlugin extends Plugin int currentXp = client.getSkillExperience(skill); xpState.resetSkill(skill, currentXp); xpPanel.resetSkill(skill); + removeOverlay(skill); } /** @@ -272,7 +301,6 @@ public class XpTrackerPlugin extends Plugin } } - @Subscribe public void onExperienceChanged(ExperienceChanged event) { diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/SplitComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/SplitComponent.java index 2e77a7dde2..75ab98f137 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/SplitComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/SplitComponent.java @@ -58,9 +58,8 @@ public class SplitComponent implements LayoutableRenderableEntity @Override public Dimension render(Graphics2D graphics) { - graphics.translate(preferredLocation.x, preferredLocation.y); + first.setPreferredLocation(preferredLocation); first.setPreferredSize(preferredSize); - first.setPreferredLocation(new Point(0, 0)); final Dimension firstDimension = first.render(graphics); int x = 0, y = 0; @@ -74,7 +73,7 @@ public class SplitComponent implements LayoutableRenderableEntity x = firstDimension.width + gap.x; } - second.setPreferredLocation(new Point(x, y)); + second.setPreferredLocation(new Point(x + preferredLocation.x, y + preferredLocation.y)); // Make the second component fit to whatever size is left after the first component is rendered second.setPreferredSize(new Dimension(preferredSize.width - x, preferredSize.height - y)); @@ -95,8 +94,6 @@ public class SplitComponent implements LayoutableRenderableEntity totalWidth = x + secondDimension.width; } - graphics.translate(-preferredLocation.x, -preferredLocation.y); - final Dimension dimension = new Dimension(totalWidth, totalHeight); bounds.setLocation(preferredLocation); bounds.setSize(dimension); From e18652f517e0f49d6a7b6d98875eacd9e1e783e0 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 May 2019 19:59:11 -0400 Subject: [PATCH 11/17] party plugin: add partyinfo debug command --- .../client/plugins/party/PartyPlugin.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java index b824f17157..2d7bddc3a6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java @@ -37,6 +37,7 @@ import java.util.Map; import java.util.UUID; import javax.annotation.Nullable; import javax.inject.Inject; +import javax.inject.Named; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.api.ChatMessageType; @@ -48,6 +49,7 @@ import net.runelite.api.Skill; import net.runelite.api.SoundEffectID; import net.runelite.api.Tile; import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.CommandExecuted; import net.runelite.api.events.FocusChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.MenuOptionClicked; @@ -120,6 +122,10 @@ public class PartyPlugin extends Plugin implements KeyListener @Inject private ChatMessageManager chatMessageManager; + @Inject + @Named("developerMode") + boolean developerMode; + @Getter private final Map partyDataMap = Collections.synchronizedMap(new HashMap<>()); @@ -448,6 +454,23 @@ public class PartyPlugin extends Plugin implements KeyListener worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance); } + @Subscribe + public void onCommandExecuted(CommandExecuted commandExecuted) + { + if (!developerMode || !commandExecuted.getCommand().equals("partyinfo")) + { + return; + } + + chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Party " + party.getPartyId()).build()); + chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Local Party " + party.getLocalPartyId()).build()); + chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Local ID " + party.getLocalMember().getMemberId()).build()); + for (PartyMember partyMember : party.getMembers()) + { + chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value(" " + partyMember.getName() + " " + partyMember.getMemberId()).build()); + } + } + @Nullable PartyData getPartyData(final UUID uuid) { From c95cd3bfd52b6f843acbcb2af38729076157d9ab Mon Sep 17 00:00:00 2001 From: Lotto Date: Tue, 7 May 2019 02:47:11 +0200 Subject: [PATCH 12/17] xp tracker: add start and goal levels to on-canvas tracker --- .../plugins/xptracker/XpInfoBoxOverlay.java | 12 ++++++++++ .../components/ProgressBarComponent.java | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java index 99c5880901..8718f44468 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.xptracker; +import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; @@ -31,8 +32,10 @@ import java.awt.Rectangle; import java.awt.image.BufferedImage; import lombok.AccessLevel; import lombok.Getter; +import net.runelite.api.Experience; import net.runelite.api.Skill; import net.runelite.client.ui.FontManager; +import net.runelite.client.ui.SkillColor; import net.runelite.client.ui.overlay.Overlay; import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.ImageComponent; @@ -113,6 +116,15 @@ class XpInfoBoxOverlay extends Overlay iconXpSplitPanel.getChildren().add(iconXpSplit); final ProgressBarComponent progressBarComponent = new ProgressBarComponent(); + + progressBarComponent.setBackgroundColor(new Color(61, 56, 49)); + progressBarComponent.setForegroundColor(SkillColor.find(skill).getColor()); + + progressBarComponent.setLeftLabel(String.valueOf(snapshot.getStartLevel())); + progressBarComponent.setRightLabel(snapshot.getEndGoalXp() == Experience.MAX_SKILL_XP + ? "200M" + : String.valueOf(snapshot.getEndLevel())); + progressBarComponent.setValue(snapshot.getSkillProgressToGoal()); panel.getChildren().add(iconXpSplitPanel); diff --git a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java index ba4634deec..cadced4e96 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/overlay/components/ProgressBarComponent.java @@ -46,10 +46,14 @@ public class ProgressBarComponent implements LayoutableRenderableEntity private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.0"); private static final DecimalFormat DECIMAL_FORMAT_ABS = new DecimalFormat("#0"); + private static final int SIDE_LABEL_OFFSET = 4; + private long minimum; private long maximum = 100; private double value; private LabelDisplayMode labelDisplayMode = LabelDisplayMode.PERCENTAGE; + private String leftLabel; + private String rightLabel; private Color foregroundColor = new Color(82, 161, 82); private Color backgroundColor = new Color(255, 255, 255, 127); private Color fontColor = Color.WHITE; @@ -99,6 +103,24 @@ public class ProgressBarComponent implements LayoutableRenderableEntity textComponent.setText(textToWrite); textComponent.render(graphics); + if (leftLabel != null) + { + final TextComponent leftTextComponent = new TextComponent(); + leftTextComponent.setPosition(new Point(barX + SIDE_LABEL_OFFSET, progressTextY)); + leftTextComponent.setColor(fontColor); + leftTextComponent.setText(leftLabel); + leftTextComponent.render(graphics); + } + + if (rightLabel != null) + { + final TextComponent leftTextComponent = new TextComponent(); + leftTextComponent.setPosition(new Point(barX + width - metrics.stringWidth(rightLabel) - SIDE_LABEL_OFFSET, progressTextY)); + leftTextComponent.setColor(fontColor); + leftTextComponent.setText(rightLabel); + leftTextComponent.render(graphics); + } + final Dimension dimension = new Dimension(width, height); bounds.setLocation(preferredLocation); bounds.setSize(dimension); From ad16bf5b3f55223d775936ae9b20ffb421c1a4d1 Mon Sep 17 00:00:00 2001 From: Lotto Date: Tue, 7 May 2019 17:00:51 +0200 Subject: [PATCH 13/17] xp tracker (onscreen): add toggle between displaying XP Left/XP Gained --- .../client/plugins/xptracker/XpInfoBoxOverlay.java | 8 ++++++-- .../client/plugins/xptracker/XpTrackerConfig.java | 11 +++++++++++ .../client/plugins/xptracker/XpTrackerPlugin.java | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java index 8718f44468..290dffe01f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java @@ -56,6 +56,7 @@ class XpInfoBoxOverlay extends Overlay private final PanelComponent panel = new PanelComponent(); private final PanelComponent iconXpSplitPanel = new PanelComponent(); private final XpTrackerPlugin plugin; + private final XpTrackerConfig config; @Getter(AccessLevel.PACKAGE) private final Skill skill; @@ -63,11 +64,13 @@ class XpInfoBoxOverlay extends Overlay XpInfoBoxOverlay( XpTrackerPlugin plugin, + XpTrackerConfig config, Skill skill, BufferedImage icon) { super(plugin); this.plugin = plugin; + this.config = config; this.skill = skill; this.icon = icon; panel.setBorder(new Rectangle(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); @@ -90,8 +93,9 @@ class XpInfoBoxOverlay extends Overlay final XpSnapshotSingle snapshot = plugin.getSkillSnapshot(skill); final LineComponent xpLine = LineComponent.builder() - .left("XP Gained:") - .right(StackFormatter.quantityToRSDecimalStack(snapshot.getXpGainedInSession())) + .left(config.displayXpLeftOnScreen() ? "XP Left:" : "XP Gained:") + .right(StackFormatter.quantityToRSDecimalStack(config.displayXpLeftOnScreen() + ? snapshot.getXpRemainingToGoal() : snapshot.getXpGainedInSession())) .build(); final LineComponent xpHour = LineComponent.builder() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java index d32abf2aa9..f14b442825 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java @@ -74,4 +74,15 @@ public interface XpTrackerConfig extends Config { return 0; } + + @ConfigItem( + position = 4, + keyName = "onScreenXpLeft", + name = "Display XP Left on-screen", + description = "Display remaining experience instead of experience gained on on-screen trackers" + ) + default boolean displayXpLeftOnScreen() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java index 8f08b0ba7b..7d3006ddc9 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerPlugin.java @@ -221,7 +221,7 @@ public class XpTrackerPlugin extends Plugin void addOverlay(Skill skill) { removeOverlay(skill); - overlayManager.add(new XpInfoBoxOverlay(this, skill, skillIconManager.getSkillImage(skill))); + overlayManager.add(new XpInfoBoxOverlay(this, xpTrackerConfig, skill, skillIconManager.getSkillImage(skill))); } /** From bf2eccc54714350894054b556635203df25ef959 Mon Sep 17 00:00:00 2001 From: Lotto Date: Tue, 7 May 2019 21:44:17 +0200 Subject: [PATCH 14/17] xp tracker: add right-click configure on on-screen trackers --- .../runelite/client/plugins/xptracker/XpInfoBoxOverlay.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java index 290dffe01f..d5172d6452 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java @@ -37,6 +37,7 @@ import net.runelite.api.Skill; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.SkillColor; import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayMenuEntry; import net.runelite.client.ui.overlay.components.ComponentOrientation; import net.runelite.client.ui.overlay.components.ImageComponent; import net.runelite.client.ui.overlay.components.LineComponent; @@ -44,6 +45,8 @@ import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.components.ProgressBarComponent; import net.runelite.client.ui.overlay.components.SplitComponent; import net.runelite.client.util.StackFormatter; +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; class XpInfoBoxOverlay extends Overlay { @@ -79,6 +82,7 @@ class XpInfoBoxOverlay extends Overlay iconXpSplitPanel.setBorder(XP_AND_ICON_COMPONENT_BORDER); iconXpSplitPanel.setBackgroundColor(null); iconXpSplitPanel.setPreferredSize(new Dimension(PANEL_PREFERRED_WIDTH, 0)); + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "XP Tracker overlay")); } @Override From 7e6476ce6702acd7ea3d496657d5d4e7a46434f2 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 11 May 2019 19:59:51 -0400 Subject: [PATCH 15/17] party service: check joins are for the current party The server can resume party membership on handshake to parties other than the current client party (eg. if the client is restarted or for any other reason the current party changes). This desyncs otherwise if the joins aren't checked to be in the current party. --- .../net/runelite/http/api/ws/messages/party/UserJoin.java | 1 + .../src/main/java/net/runelite/client/ws/PartyService.java | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserJoin.java b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserJoin.java index 81abe76827..7f940e8060 100644 --- a/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserJoin.java +++ b/http-api/src/main/java/net/runelite/http/api/ws/messages/party/UserJoin.java @@ -34,5 +34,6 @@ import net.runelite.http.api.ws.WebsocketMessage; public class UserJoin extends WebsocketMessage { private final UUID memberId; + private final UUID partyId; private final String name; } diff --git a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java b/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java index 47e9c18148..caec527320 100644 --- a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java +++ b/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java @@ -114,6 +114,13 @@ public class PartyService @Subscribe public void onUserJoin(final UserJoin message) { + if (!partyId.equals(message.getPartyId())) + { + // This can happen when a session is resumed server side after the client party + // changes when disconnected. + return; + } + final PartyMember partyMember = new PartyMember(message.getMemberId(), message.getName()); members.add(partyMember); From 34b30313ca05ca57cff305f878395daa498c71b9 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Sun, 12 May 2019 17:42:13 +0200 Subject: [PATCH 16/17] Add options for actions left and done for on screen XP Add configurable option for on screen XP display mode, what now includes: - Actions done - Actions left - Xp gained - Xp left Signed-off-by: Tomas Slusny --- .../plugins/xptracker/XpInfoBoxOverlay.java | 33 ++++++++++++++++--- .../plugins/xptracker/XpTrackerConfig.java | 28 +++++++++++++--- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java index d5172d6452..32b9a44bfe 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpInfoBoxOverlay.java @@ -96,15 +96,38 @@ class XpInfoBoxOverlay extends Overlay final XpSnapshotSingle snapshot = plugin.getSkillSnapshot(skill); + final String leftStr; + final int rightNum; + + switch (config.onScreenDisplayMode()) + { + case ACTIONS_DONE: + leftStr = snapshot.getActionType().getLabel() + " Done"; + rightNum = snapshot.getActionsInSession(); + break; + case ACTIONS_LEFT: + leftStr = snapshot.getActionType().getLabel() + " Left"; + rightNum = snapshot.getActionsRemainingToGoal(); + break; + case XP_LEFT: + leftStr = config.onScreenDisplayMode().toString(); + rightNum = snapshot.getXpRemainingToGoal(); + break; + case XP_GAINED: + default: + leftStr = config.onScreenDisplayMode().toString(); + rightNum = snapshot.getXpGainedInSession(); + break; + } + final LineComponent xpLine = LineComponent.builder() - .left(config.displayXpLeftOnScreen() ? "XP Left:" : "XP Gained:") - .right(StackFormatter.quantityToRSDecimalStack(config.displayXpLeftOnScreen() - ? snapshot.getXpRemainingToGoal() : snapshot.getXpGainedInSession())) - .build(); + .left(leftStr + ":") + .right(StackFormatter.quantityToRSDecimalStack(rightNum, true)) + .build(); final LineComponent xpHour = LineComponent.builder() .left("XP/Hour:") - .right(StackFormatter.quantityToRSDecimalStack(snapshot.getXpPerHour())) + .right(StackFormatter.quantityToRSDecimalStack(snapshot.getXpPerHour(), true)) .build(); final SplitComponent xpSplit = SplitComponent.builder() diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java index f14b442825..6bac32802a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xptracker/XpTrackerConfig.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.xptracker; +import lombok.AllArgsConstructor; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @@ -31,6 +32,23 @@ import net.runelite.client.config.ConfigItem; @ConfigGroup("xpTracker") public interface XpTrackerConfig extends Config { + @AllArgsConstructor + enum OnScreenDisplayMode + { + XP_GAINED("XP Gained"), + XP_LEFT("XP Left"), + ACTIONS_DONE("Actions Done"), + ACTIONS_LEFT("Actions Left"); + + private final String name; + + @Override + public String toString() + { + return name; + } + } + @ConfigItem( position = 0, keyName = "hideMaxed", @@ -77,12 +95,12 @@ public interface XpTrackerConfig extends Config @ConfigItem( position = 4, - keyName = "onScreenXpLeft", - name = "Display XP Left on-screen", - description = "Display remaining experience instead of experience gained on on-screen trackers" + keyName = "onScreenDisplayMode", + name = "On-screen tracker display mode", + description = "Configures the information displayed in the first line of on-screen XP overlays" ) - default boolean displayXpLeftOnScreen() + default OnScreenDisplayMode onScreenDisplayMode() { - return false; + return OnScreenDisplayMode.XP_GAINED; } } From 7d22663756d4dbb7a629cb4129c2faf60ef587ed Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 12 May 2019 11:57:40 -0400 Subject: [PATCH 17/17] client: use immutablemap for maps built in class initializers --- .../client/game/ItemVariationMapping.java | 8 +- .../client/plugins/agility/Courses.java | 10 ++- .../plugins/attackstyles/WeaponType.java | 22 +++-- .../client/plugins/blastfurnace/BarsOres.java | 10 ++- .../plugins/blastmine/BlastMineRockType.java | 10 ++- .../client/plugins/bosstimer/Boss.java | 10 ++- .../plugins/cerberus/CerberusGhost.java | 13 +-- .../chatcommands/SkillAbbreviations.java | 86 ++++++++++--------- .../plugins/discord/DiscordGameEventType.java | 17 ++-- .../client/plugins/fishing/FishingSpot.java | 12 +-- .../client/plugins/implings/Impling.java | 10 ++- .../plugins/itemcharges/ItemWithCharge.java | 18 +++- .../ItemIdentification.java | 10 ++- .../runelite/client/plugins/poh/PohIcons.java | 26 ++++-- .../client/plugins/prayer/PrayerItems.java | 8 +- .../plugins/prayer/PrayerRestoreType.java | 8 +- .../puzzlesolver/VarrockMuseumAnswer.java | 10 ++- .../client/plugins/runecraft/AbyssRifts.java | 10 ++- .../client/plugins/runepouch/Runes.java | 8 +- .../runelite/client/plugins/slayer/Task.java | 10 ++- .../plugins/tithefarm/TitheFarmPlantType.java | 12 +-- .../client/plugins/woodcutting/Axe.java | 10 ++- .../client/plugins/woodcutting/Tree.java | 10 ++- 23 files changed, 223 insertions(+), 125 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/game/ItemVariationMapping.java b/runelite-client/src/main/java/net/runelite/client/game/ItemVariationMapping.java index c471a1a814..9629bd99ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/game/ItemVariationMapping.java +++ b/runelite-client/src/main/java/net/runelite/client/game/ItemVariationMapping.java @@ -25,12 +25,12 @@ package net.runelite.client.game; +import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Collection; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -39,7 +39,7 @@ import java.util.Map; */ public class ItemVariationMapping { - private static final Map MAPPINGS = new HashMap<>(); + private static final Map MAPPINGS; static { @@ -51,6 +51,7 @@ public class ItemVariationMapping final InputStream geLimitData = ItemVariationMapping.class.getResourceAsStream("/item_variations.json"); final Map> itemVariations = gson.fromJson(new InputStreamReader(geLimitData), typeToken.getType()); + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); for (Collection value : itemVariations.values()) { final Iterator iterator = value.iterator(); @@ -58,9 +59,10 @@ public class ItemVariationMapping while (iterator.hasNext()) { - MAPPINGS.put(iterator.next(), base); + builder.put(iterator.next(), base); } } + MAPPINGS = builder.build(); } /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/Courses.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Courses.java index bbd6b181cb..cc732561c0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/Courses.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/Courses.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.agility; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.Getter; import net.runelite.api.coords.WorldPoint; @@ -48,7 +48,7 @@ enum Courses RELLEKA(780.0, 475, 10553), ARDOUGNE(793.0, 529, 10547); - private final static Map coursesByRegion = new HashMap<>(); + private final static Map coursesByRegion; @Getter private final double totalXp; @@ -64,10 +64,14 @@ enum Courses static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (Courses course : values()) { - coursesByRegion.put(course.regionId, course); + builder.put(course.regionId, course); } + + coursesByRegion = builder.build(); } Courses(double totalXp, int lastObstacleXp, int regionId, WorldPoint... courseEndWorldPoints) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/WeaponType.java b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/WeaponType.java index ef9ba0a188..0a0e443d55 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/WeaponType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/attackstyles/WeaponType.java @@ -24,9 +24,17 @@ */ package net.runelite.client.plugins.attackstyles; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; -import static net.runelite.client.plugins.attackstyles.AttackStyle.*; +import static net.runelite.client.plugins.attackstyles.AttackStyle.ACCURATE; +import static net.runelite.client.plugins.attackstyles.AttackStyle.AGGRESSIVE; +import static net.runelite.client.plugins.attackstyles.AttackStyle.CASTING; +import static net.runelite.client.plugins.attackstyles.AttackStyle.CONTROLLED; +import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE; +import static net.runelite.client.plugins.attackstyles.AttackStyle.DEFENSIVE_CASTING; +import static net.runelite.client.plugins.attackstyles.AttackStyle.LONGRANGE; +import static net.runelite.client.plugins.attackstyles.AttackStyle.OTHER; +import static net.runelite.client.plugins.attackstyles.AttackStyle.RANGING; enum WeaponType { @@ -59,16 +67,20 @@ enum WeaponType TYPE_26(AGGRESSIVE, AGGRESSIVE, null, AGGRESSIVE), TYPE_27(ACCURATE, null, null, OTHER); - private static final Map weaponTypes = new HashMap<>(); - private final AttackStyle[] attackStyles; + private static final Map weaponTypes; + static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (WeaponType weaponType : values()) { - weaponTypes.put(weaponType.ordinal(), weaponType); + builder.put(weaponType.ordinal(), weaponType); } + + weaponTypes = builder.build(); } WeaponType(AttackStyle... attackStyles) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BarsOres.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BarsOres.java index 1f9bc2c244..52a295afd3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BarsOres.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastfurnace/BarsOres.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.blastfurnace; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.Getter; import net.runelite.api.ItemID; @@ -50,14 +50,18 @@ public enum BarsOres SILVER_BAR(Varbits.BLAST_FURNACE_SILVER_BAR, ItemID.SILVER_BAR), GOLD_BAR(Varbits.BLAST_FURNACE_GOLD_BAR, ItemID.GOLD_BAR); - private static final Map VARBIT = new HashMap<>(); + private static final Map VARBIT; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (BarsOres s : values()) { - VARBIT.put(s.getVarbit(), s); + builder.put(s.getVarbit(), s); } + + VARBIT = builder.build(); } @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockType.java b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockType.java index 7c7bda870a..20e1d37f58 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/blastmine/BlastMineRockType.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.blastmine; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.Getter; import net.runelite.api.ObjectID; @@ -37,17 +37,21 @@ public enum BlastMineRockType LIT(ObjectID.POT_OF_DYNAMITE_28585, ObjectID.POT_OF_DYNAMITE_28586), EXPLODED(ObjectID.SHATTERED_ROCKFACE, ObjectID.SHATTERED_ROCKFACE_28588); - private static final Map rockTypes = new HashMap<>(); + private static final Map rockTypes; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (BlastMineRockType type : values()) { for (int spotId : type.getObjectIds()) { - rockTypes.put(spotId, type); + builder.put(spotId, type); } } + + rockTypes = builder.build(); } @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java index 95839b9e96..47752f415b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/bosstimer/Boss.java @@ -25,9 +25,9 @@ */ package net.runelite.client.plugins.bosstimer; +import com.google.common.collect.ImmutableMap; import java.time.Duration; import java.time.temporal.ChronoUnit; -import java.util.HashMap; import java.util.Map; import net.runelite.api.ItemID; import net.runelite.api.NpcID; @@ -59,7 +59,7 @@ enum Boss DUSK(NpcID.DUSK_7889, 2, ChronoUnit.MINUTES, ItemID.NOON), ALCHEMICAL_HYDRA(NpcID.ALCHEMICAL_HYDRA_8622, 25200, ChronoUnit.MILLIS, ItemID.IKKLE_HYDRA); - private static final Map bosses = new HashMap<>(); + private static final Map bosses; private final int id; private final Duration spawnTime; @@ -67,10 +67,14 @@ enum Boss static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (Boss boss : values()) { - bosses.put(boss.getId(), boss); + builder.put(boss.getId(), boss); } + + bosses = builder.build(); } private Boss(int id, long period, ChronoUnit unit, int itemSpriteId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusGhost.java b/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusGhost.java index 7bdf9d6788..744085c9a4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusGhost.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cerberus/CerberusGhost.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.cerberus; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import java.util.Optional; import lombok.Getter; @@ -41,18 +41,21 @@ public enum CerberusGhost MAGE(NpcID.SUMMONED_SOUL_5868, Skill.MAGIC), MELEE(NpcID.SUMMONED_SOUL_5869, Skill.ATTACK); - private static final Map MAP = new HashMap<>(); private final int npcId; private final Skill type; + private static final Map MAP; + static { - final CerberusGhost[] values = CerberusGhost.values(); + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); - for (final CerberusGhost ghost : values) + for (final CerberusGhost ghost : values()) { - MAP.put(ghost.getNpcId(), ghost); + builder.put(ghost.getNpcId(), ghost); } + + MAP = builder.build(); } /** diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/SkillAbbreviations.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/SkillAbbreviations.java index da89769172..754c2f869e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/SkillAbbreviations.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/SkillAbbreviations.java @@ -24,56 +24,58 @@ */ package net.runelite.client.plugins.chatcommands; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import net.runelite.api.Skill; class SkillAbbreviations { - private static final Map MAP = new HashMap<>(); + private static final Map MAP; static { - MAP.put("ATK", Skill.ATTACK.getName()); - MAP.put("ATT", Skill.ATTACK.getName()); - MAP.put("DEF", Skill.DEFENCE.getName()); - MAP.put("STR", Skill.STRENGTH.getName()); - MAP.put("HEALTH", Skill.HITPOINTS.getName()); - MAP.put("HIT", Skill.HITPOINTS.getName()); - MAP.put("HITPOINT", Skill.HITPOINTS.getName()); - MAP.put("HP", Skill.HITPOINTS.getName()); - MAP.put("RANGE", Skill.RANGED.getName()); - MAP.put("RANGING", Skill.RANGED.getName()); - MAP.put("RNG", Skill.RANGED.getName()); - MAP.put("PRAY", Skill.PRAYER.getName()); - MAP.put("MAG", Skill.MAGIC.getName()); - MAP.put("MAGE", Skill.MAGIC.getName()); - MAP.put("COOK", Skill.COOKING.getName()); - MAP.put("WC", Skill.WOODCUTTING.getName()); - MAP.put("WOOD", Skill.WOODCUTTING.getName()); - MAP.put("WOODCUT", Skill.WOODCUTTING.getName()); - MAP.put("FLETCH", Skill.FLETCHING.getName()); - MAP.put("FISH", Skill.FISHING.getName()); - MAP.put("FM", Skill.FIREMAKING.getName()); - MAP.put("FIRE", Skill.FIREMAKING.getName()); - MAP.put("CRAFT", Skill.CRAFTING.getName()); - MAP.put("SMITH", Skill.SMITHING.getName()); - MAP.put("MINE", Skill.MINING.getName()); - MAP.put("HL", Skill.HERBLORE.getName()); - MAP.put("HERB", Skill.HERBLORE.getName()); - MAP.put("AGI", Skill.AGILITY.getName()); - MAP.put("AGIL", Skill.AGILITY.getName()); - MAP.put("THIEF", Skill.THIEVING.getName()); - MAP.put("SLAY", Skill.SLAYER.getName()); - MAP.put("FARM", Skill.FARMING.getName()); - MAP.put("RC", Skill.RUNECRAFT.getName()); - MAP.put("RUNE", Skill.RUNECRAFT.getName()); - MAP.put("RUNECRAFTING", Skill.RUNECRAFT.getName()); - MAP.put("HUNT", Skill.HUNTER.getName()); - MAP.put("CON", Skill.CONSTRUCTION.getName()); - MAP.put("CONSTRUCT", Skill.CONSTRUCTION.getName()); - MAP.put("ALL", Skill.OVERALL.getName()); - MAP.put("TOTAL", Skill.OVERALL.getName()); + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + builder.put("ATK", Skill.ATTACK.getName()); + builder.put("ATT", Skill.ATTACK.getName()); + builder.put("DEF", Skill.DEFENCE.getName()); + builder.put("STR", Skill.STRENGTH.getName()); + builder.put("HEALTH", Skill.HITPOINTS.getName()); + builder.put("HIT", Skill.HITPOINTS.getName()); + builder.put("HITPOINT", Skill.HITPOINTS.getName()); + builder.put("HP", Skill.HITPOINTS.getName()); + builder.put("RANGE", Skill.RANGED.getName()); + builder.put("RANGING", Skill.RANGED.getName()); + builder.put("RNG", Skill.RANGED.getName()); + builder.put("PRAY", Skill.PRAYER.getName()); + builder.put("MAG", Skill.MAGIC.getName()); + builder.put("MAGE", Skill.MAGIC.getName()); + builder.put("COOK", Skill.COOKING.getName()); + builder.put("WC", Skill.WOODCUTTING.getName()); + builder.put("WOOD", Skill.WOODCUTTING.getName()); + builder.put("WOODCUT", Skill.WOODCUTTING.getName()); + builder.put("FLETCH", Skill.FLETCHING.getName()); + builder.put("FISH", Skill.FISHING.getName()); + builder.put("FM", Skill.FIREMAKING.getName()); + builder.put("FIRE", Skill.FIREMAKING.getName()); + builder.put("CRAFT", Skill.CRAFTING.getName()); + builder.put("SMITH", Skill.SMITHING.getName()); + builder.put("MINE", Skill.MINING.getName()); + builder.put("HL", Skill.HERBLORE.getName()); + builder.put("HERB", Skill.HERBLORE.getName()); + builder.put("AGI", Skill.AGILITY.getName()); + builder.put("AGIL", Skill.AGILITY.getName()); + builder.put("THIEF", Skill.THIEVING.getName()); + builder.put("SLAY", Skill.SLAYER.getName()); + builder.put("FARM", Skill.FARMING.getName()); + builder.put("RC", Skill.RUNECRAFT.getName()); + builder.put("RUNE", Skill.RUNECRAFT.getName()); + builder.put("RUNECRAFTING", Skill.RUNECRAFT.getName()); + builder.put("HUNT", Skill.HUNTER.getName()); + builder.put("CON", Skill.CONSTRUCTION.getName()); + builder.put("CONSTRUCT", Skill.CONSTRUCTION.getName()); + builder.put("ALL", Skill.OVERALL.getName()); + builder.put("TOTAL", Skill.OVERALL.getName()); + MAP = builder.build(); } /** 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 7258c6c7bb..cd05521228 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 @@ -25,8 +25,8 @@ */ package net.runelite.client.plugins.discord; -import java.util.ArrayList; -import java.util.HashMap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import java.util.List; import java.util.Map; import lombok.AllArgsConstructor; @@ -250,16 +250,18 @@ enum DiscordGameEventType RAIDS_CHAMBERS_OF_XERIC("Chambers of Xeric", DiscordAreaType.RAIDS, Varbits.IN_RAID), RAIDS_THEATRE_OF_BLOOD("Theatre of Blood", DiscordAreaType.RAIDS, Varbits.THEATRE_OF_BLOOD); - private static final Map FROM_REGION = new HashMap<>(); - private static final List FROM_VARBITS = new ArrayList<>(); + private static final Map FROM_REGION; + private static final List FROM_VARBITS; static { + ImmutableMap.Builder regionMapBuilder = new ImmutableMap.Builder<>(); + ImmutableList.Builder fromVarbitsBuilder = ImmutableList.builder(); for (DiscordGameEventType discordGameEventType : DiscordGameEventType.values()) { if (discordGameEventType.getVarbits() != null) { - FROM_VARBITS.add(discordGameEventType); + fromVarbitsBuilder.add(discordGameEventType); continue; } @@ -270,10 +272,11 @@ enum DiscordGameEventType for (int region : discordGameEventType.getRegionIds()) { - assert !FROM_REGION.containsKey(region); - FROM_REGION.put(region, discordGameEventType); + regionMapBuilder.put(region, discordGameEventType); } } + FROM_REGION = regionMapBuilder.build(); + FROM_VARBITS = fromVarbitsBuilder.build(); } private String imageKey; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java index 0221e7c32c..94f774ccc0 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fishing/FishingSpot.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.fishing; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.Getter; import net.runelite.api.ItemID; @@ -160,7 +160,7 @@ enum FishingSpot FISHING_SPOT_8523); @Getter - private static final Map SPOTS = new HashMap<>(); + private static final Map SPOTS; private final String name; private final int fishSpriteId; @@ -168,15 +168,17 @@ enum FishingSpot static { - FishingSpot[] spots = values(); + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); - for (FishingSpot spot : spots) + for (FishingSpot spot : values()) { for (int spotId : spot.getIds()) { - SPOTS.put(spotId, spot); + builder.put(spotId, spot); } } + + SPOTS = builder.build(); } FishingSpot(String spot, int fishSpriteId, int... ids) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/implings/Impling.java b/runelite-client/src/main/java/net/runelite/client/plugins/implings/Impling.java index 0273b5da04..473fad2c23 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/implings/Impling.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/implings/Impling.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.implings; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.AllArgsConstructor; import lombok.Getter; @@ -70,14 +70,18 @@ enum Impling private ImplingType implingType; private final int npcId; - private static final Map IMPLINGS = new HashMap<>(); + private static final Map IMPLINGS; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (Impling impling : values()) { - IMPLINGS.put(impling.npcId, impling); + builder.put(impling.npcId, impling); } + + IMPLINGS = builder.build(); } static Impling findImpling(int npcId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java index 10f905aff4..f696097817 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java @@ -24,13 +24,19 @@ */ package net.runelite.client.plugins.itemcharges; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import javax.annotation.Nullable; import lombok.AllArgsConstructor; import lombok.Getter; import static net.runelite.api.ItemID.*; -import static net.runelite.client.plugins.itemcharges.ItemChargeType.*; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.ABYSSAL_BRACELET; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.BELLOWS; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.FUNGICIDE_SPRAY; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.IMPBOX; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.TELEPORT; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERCAN; +import static net.runelite.client.plugins.itemcharges.ItemChargeType.WATERSKIN; @AllArgsConstructor @Getter @@ -168,14 +174,18 @@ enum ItemWithCharge private final int id; private final int charges; - private static final Map ID_MAP = new HashMap<>(); + private static final Map ID_MAP; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (ItemWithCharge itemCharge : values()) { - ID_MAP.put(itemCharge.getId(), itemCharge); + builder.put(itemCharge.getId(), itemCharge); } + + ID_MAP = builder.build(); } @Nullable diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java index 8ef3efcf8b..622ab1c04e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentification.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.itemidentification; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import net.runelite.api.ItemID; @@ -100,17 +100,21 @@ enum ItemIdentification this.itemIDs = ids; } - private static final Map itemIdentifications = new HashMap<>(); + private static final Map itemIdentifications; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (ItemIdentification i : values()) { for (int id : i.itemIDs) { - itemIdentifications.put(id, i); + builder.put(id, i); } } + + itemIdentifications = builder.build(); } static ItemIdentification get(int id) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohIcons.java b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohIcons.java index 1cde69a8ea..656cf85716 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohIcons.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohIcons.java @@ -24,12 +24,22 @@ */ package net.runelite.client.plugins.poh; +import com.google.common.collect.ImmutableMap; import java.awt.image.BufferedImage; -import java.util.HashMap; import java.util.Map; import lombok.Getter; +import static net.runelite.api.NullObjectID.NULL_13615; +import static net.runelite.api.NullObjectID.NULL_13618; +import static net.runelite.api.NullObjectID.NULL_13620; +import static net.runelite.api.NullObjectID.NULL_13622; +import static net.runelite.api.NullObjectID.NULL_13625; +import static net.runelite.api.NullObjectID.NULL_13627; +import static net.runelite.api.NullObjectID.NULL_13629; +import static net.runelite.api.NullObjectID.NULL_13632; +import static net.runelite.api.NullObjectID.NULL_13634; +import static net.runelite.api.NullObjectID.NULL_29228; +import static net.runelite.api.NullObjectID.NULL_29229; import static net.runelite.api.ObjectID.*; -import static net.runelite.api.NullObjectID.*; import net.runelite.client.util.ImageUtil; public enum PohIcons @@ -56,7 +66,7 @@ public enum PohIcons ALTAR("altar", ALTAR_13179, ALTAR_13180, ALTAR_13181, ALTAR_13182, ALTAR_13183, ALTAR_13184, ALTAR_13185, ALTAR_13186, ALTAR_13187, ALTAR_13188, ALTAR_13189, ALTAR_13190, ALTAR_13191, ALTAR_13192, ALTAR_13193, ALTAR_13194, - ALTAR_13194, ALTAR_13196, ALTAR_13197, ALTAR_13198, ALTAR_13199 + ALTAR_13196, ALTAR_13197, ALTAR_13198, ALTAR_13199 ), POOLS("pool", POOL_OF_RESTORATION, POOL_OF_REVITALISATION, POOL_OF_REJUVENATION, FANCY_REJUVENATION_POOL, ORNATE_REJUVENATION_POOL), GLORY("glory", AMULET_OF_GLORY), @@ -83,7 +93,7 @@ public enum PohIcons DIGSITE_PENDANT, DIGSITE_PENDANT_33417, DIGSITE_PENDANT_33418, DIGSITE_PENDANT_33420 ); - private static final Map minimapIcons = new HashMap<>(); + private static final Map minimapIcons; @Getter private final String imageResource; @@ -94,15 +104,17 @@ public enum PohIcons static { - PohIcons[] icons = values(); + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); - for (PohIcons icon : icons) + for (PohIcons icon : values()) { for (Integer spotId : icon.getIds()) { - minimapIcons.put(spotId, icon); + builder.put(spotId, icon); } } + + minimapIcons = builder.build(); } PohIcons(String imageResource, int... ids) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java index 24ffbc5a56..d07ff8cf6c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerItems.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.prayer; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.AllArgsConstructor; import lombok.Getter; @@ -453,17 +453,19 @@ enum PrayerItems DAMAGED_BOOK_3841(ItemID.DAMAGED_BOOK_3841, 5), FALADOR_SHIELD_4(ItemID.FALADOR_SHIELD_4, 5); - private static final Map prayerBonuses = new HashMap<>(); + private static final Map prayerBonuses; private final int itemId; private final int prayerBonus; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); for (PrayerItems item : values()) { - prayerBonuses.put(item.getItemId(), item.getPrayerBonus()); + builder.put(item.getItemId(), item.getPrayerBonus()); } + prayerBonuses = builder.build(); } static int getItemPrayerBonus(int itemId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerRestoreType.java b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerRestoreType.java index 2ef3c1a46f..d30b790a9e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerRestoreType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/prayer/PrayerRestoreType.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.prayer; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import net.runelite.api.ItemID; @@ -36,7 +36,7 @@ enum PrayerRestoreType HOLYWRENCH(ItemID.PRAYER_CAPE, ItemID.PRAYER_CAPET, ItemID.PRAYER_CAPE_10643, ItemID.MAX_CAPE, ItemID.MAX_CAPE_13282, ItemID.MAX_CAPE_13342, ItemID.HOLY_WRENCH, ItemID.RING_OF_THE_GODS_I); - private static final Map prayerRestores = new HashMap<>(); + private static final Map prayerRestores; private final int[] items; @@ -47,13 +47,15 @@ enum PrayerRestoreType static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); for (PrayerRestoreType prayerRestoreType : values()) { for (int itemId : prayerRestoreType.items) { - prayerRestores.put(itemId, prayerRestoreType); + builder.put(itemId, prayerRestoreType); } } + prayerRestores = builder.build(); } static PrayerRestoreType getType(final int itemId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/VarrockMuseumAnswer.java b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/VarrockMuseumAnswer.java index e574dd1023..0e4307d550 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/VarrockMuseumAnswer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/puzzlesolver/VarrockMuseumAnswer.java @@ -25,7 +25,7 @@ */ package net.runelite.client.plugins.puzzlesolver; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -135,14 +135,18 @@ enum VarrockMuseumAnswer LEECH_5("What is special about Morytanian leeches?", "They attack by jumping."), LEECH_6("How does a leech change when it feeds?", "It doubles in size."); - private static final Map MATCHES = new HashMap<>(); + private static final Map MATCHES; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (VarrockMuseumAnswer varrockMuseumAnswer : VarrockMuseumAnswer.values()) { - MATCHES.put(varrockMuseumAnswer.question, varrockMuseumAnswer.answer); + builder.put(varrockMuseumAnswer.question, varrockMuseumAnswer.answer); } + + MATCHES = builder.build(); } private final String question; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/AbyssRifts.java b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/AbyssRifts.java index 60f02d5080..1ecedafe00 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/AbyssRifts.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runecraft/AbyssRifts.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.runecraft; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.Getter; import static net.runelite.api.ItemID.AIR_RUNE; @@ -64,14 +64,18 @@ public enum AbyssRifts @Getter private final int itemId; - private static final Map rifts = new HashMap<>(); + private static final Map rifts; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (AbyssRifts s : values()) { - rifts.put(s.getObjectId(), s); + builder.put(s.getObjectId(), s); } + + rifts = builder.build(); } AbyssRifts(int objectId, int itemId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/Runes.java b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/Runes.java index 26dd1148a9..b5aebe9bf6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/Runes.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/runepouch/Runes.java @@ -25,8 +25,8 @@ package net.runelite.client.plugins.runepouch; +import com.google.common.collect.ImmutableMap; import java.awt.image.BufferedImage; -import java.util.HashMap; import java.util.Map; import lombok.Getter; import lombok.Setter; @@ -85,14 +85,16 @@ public enum Runes @Setter private BufferedImage image; - private static final Map runes = new HashMap<>(); + private static final Map runes; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); for (Runes rune : values()) { - runes.put(rune.getId(), rune); + builder.put(rune.getId(), rune); } + runes = builder.build(); } Runes(int id, int itemId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java index 69725f6d1b..5ba47383e1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/Task.java @@ -26,7 +26,7 @@ package net.runelite.client.plugins.slayer; import com.google.common.base.Preconditions; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.Getter; import net.runelite.api.ItemID; @@ -174,7 +174,7 @@ enum Task ZUK("TzKal-Zuk", ItemID.TZREKZUK); // - private static final Map tasks = new HashMap<>(); + private static final Map tasks; private final String name; private final int itemSpriteId; @@ -184,10 +184,14 @@ enum Task static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (Task task : values()) { - tasks.put(task.getName().toLowerCase(), task); + builder.put(task.getName().toLowerCase(), task); } + + tasks = builder.build(); } Task(String name, int itemSpriteId, String... targetNames) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantType.java b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantType.java index 413838c144..04a48e6eb3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantType.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/tithefarm/TitheFarmPlantType.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.tithefarm; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.Getter; import net.runelite.api.ObjectID; @@ -60,19 +60,21 @@ public enum TitheFarmPlantType @Getter private final int[] objectIds; - private static final Map plantTypes = new HashMap<>(); + private static final Map plantTypes; static { - TitheFarmPlantType[] types = values(); + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); - for (TitheFarmPlantType type : types) + for (TitheFarmPlantType type : values()) { for (int spotId : type.getObjectIds()) { - plantTypes.put(spotId, type); + builder.put(spotId, type); } } + + plantTypes = builder.build(); } TitheFarmPlantType(String name, int baseId, int... objectIds) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java index 80b4dc7b92..7b8a5c5f4e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.woodcutting; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.AllArgsConstructor; import lombok.Getter; @@ -67,14 +67,18 @@ enum Axe private final Integer animId; private final Integer itemId; - private static final Map AXE_ANIM_IDS = new HashMap<>(); + private static final Map AXE_ANIM_IDS; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (Axe axe : values()) { - AXE_ANIM_IDS.put(axe.animId, axe); + builder.put(axe.animId, axe); } + + AXE_ANIM_IDS = builder.build(); } static Axe findAxeByAnimId(int animId) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java index 021ce9da9f..befc78df8c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Tree.java @@ -24,7 +24,7 @@ */ package net.runelite.client.plugins.woodcutting; -import java.util.HashMap; +import com.google.common.collect.ImmutableMap; import java.util.Map; import lombok.Getter; import static net.runelite.api.ObjectID.REDWOOD; @@ -42,17 +42,21 @@ enum Tree this.treeIds = treeIds; } - private static final Map TREES = new HashMap<>(); + private static final Map TREES; static { + ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (Tree tree : values()) { for (int treeId : tree.treeIds) { - TREES.put(treeId, tree); + builder.put(treeId, tree); } } + + TREES = builder.build(); } static Tree findTree(int objectId)