From 896b417e665e88f00d5323f460332496667ddc4f Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Sat, 22 Feb 2020 22:16:52 -0800 Subject: [PATCH 01/27] util: Add subdirectory option to image captures This commit adds an optional and nullable `subDir` string to the `takeScreenshot()` function, allowing screenshots to be filed into a subdirectory within the player's screenshots folder. --- .../runelite/client/util/ImageCapture.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java index 2c7cf40b3f..a07e0240bb 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java +++ b/runelite-client/src/main/java/net/runelite/client/util/ImageCapture.java @@ -25,6 +25,7 @@ */ package net.runelite.client.util; +import com.google.common.base.Strings; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.datatransfer.Clipboard; @@ -40,6 +41,7 @@ import java.text.SimpleDateFormat; import java.util.Base64; import java.util.Date; import java.util.EnumSet; +import javax.annotation.Nullable; import javax.imageio.ImageIO; import javax.inject.Inject; import javax.inject.Singleton; @@ -80,10 +82,11 @@ public class ImageCapture * * @param screenshot BufferedImage to capture. * @param fileName Filename to use, without file extension. + * @param subDir Directory within the player screenshots dir to store the captured screenshot to. * @param notify Send a notification to the system tray when the image is captured. * @param imageUploadStyle which method to use to upload the screenshot (Imgur or directly to clipboard). */ - public void takeScreenshot(BufferedImage screenshot, String fileName, boolean notify, ImageUploadStyle imageUploadStyle) + public void takeScreenshot(BufferedImage screenshot, String fileName, @Nullable String subDir, boolean notify, ImageUploadStyle imageUploadStyle) { if (client.getGameState() == GameState.LOGIN_SCREEN) { @@ -106,6 +109,12 @@ public class ImageCapture { playerDir += "-League"; } + + if (!Strings.isNullOrEmpty(subDir)) + { + playerDir += File.separator + subDir; + } + playerFolder = new File(SCREENSHOT_DIR, playerDir); } else @@ -157,6 +166,20 @@ public class ImageCapture } } + /** + * Saves a screenshot of the client window to the screenshot folder as a PNG, + * and optionally uploads it to an image-hosting service. + * + * @param screenshot BufferedImage to capture. + * @param fileName Filename to use, without file extension. + * @param notify Send a notification to the system tray when the image is captured. + * @param imageUploadStyle which method to use to upload the screenshot (Imgur or directly to clipboard). + */ + public void takeScreenshot(BufferedImage screenshot, String fileName, boolean notify, ImageUploadStyle imageUploadStyle) + { + takeScreenshot(screenshot, fileName, null, notify, imageUploadStyle); + } + /** * Uploads a screenshot to the Imgur image-hosting service, * and copies the image link to the clipboard. From 030a052ea179c2331e074b93dccf4a6a0509eba0 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Sun, 13 Oct 2019 11:13:48 +0200 Subject: [PATCH 02/27] Use XpTrackerService to determine goals in Agility plugin - Merge laps until next level and laps until next goal together - Switch to XpTrackerService for determining goal experience Signed-off-by: Tomas Slusny --- .../client/plugins/agility/AgilityConfig.java | 31 ++++++------------- .../client/plugins/agility/AgilityPlugin.java | 11 +++++-- .../plugins/agility/AgilitySession.java | 21 +++---------- .../plugins/agility/LapCounterOverlay.java | 10 +----- 4 files changed, 25 insertions(+), 48 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityConfig.java index 9c3fca73ad..b84f9b5c7b 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityConfig.java @@ -69,8 +69,8 @@ public interface AgilityConfig extends Config @ConfigItem( keyName = "lapsToLevel", - name = "Show Laps Until Level", - description = "Show number of laps remaining until next level is reached.", + name = "Show Laps Until Goal", + description = "Show number of laps remaining until next goal is reached.", position = 3 ) default boolean lapsToLevel() @@ -78,22 +78,11 @@ public interface AgilityConfig extends Config return true; } - @ConfigItem( - keyName = "lapsToGoal", - name = "Show Laps Until Goal", - description = "Show number of laps remaining until experience tracker goal is reached", - position = 4 - ) - default boolean lapsToGoal() - { - return false; - } - @ConfigItem( keyName = "overlayColor", name = "Overlay Color", description = "Color of Agility overlay", - position = 5 + position = 4 ) default Color getOverlayColor() { @@ -104,7 +93,7 @@ public interface AgilityConfig extends Config keyName = "highlightMarks", name = "Highlight Marks of Grace", description = "Enable/disable the highlighting of retrievable Marks of Grace", - position = 6 + position = 5 ) default boolean highlightMarks() { @@ -115,7 +104,7 @@ public interface AgilityConfig extends Config keyName = "markHighlight", name = "Mark Highlight Color", description = "Color of highlighted Marks of Grace", - position = 7 + position = 6 ) default Color getMarkColor() { @@ -126,7 +115,7 @@ public interface AgilityConfig extends Config keyName = "highlightShortcuts", name = "Highlight Agility Shortcuts", description = "Enable/disable the highlighting of Agility shortcuts", - position = 8 + position = 7 ) default boolean highlightShortcuts() { @@ -137,7 +126,7 @@ public interface AgilityConfig extends Config keyName = "trapOverlay", name = "Show Trap Overlay", description = "Enable/disable the highlighting of traps on Agility courses", - position = 9 + position = 8 ) default boolean showTrapOverlay() { @@ -148,7 +137,7 @@ public interface AgilityConfig extends Config keyName = "trapHighlight", name = "Trap Overlay Color", description = "Color of Agility trap overlay", - position = 10 + position = 9 ) default Color getTrapColor() { @@ -159,7 +148,7 @@ public interface AgilityConfig extends Config keyName = "agilityArenaNotifier", name = "Agility Arena notifier", description = "Notify on ticket location change in Agility Arena", - position = 11 + position = 10 ) default boolean notifyAgilityArena() { @@ -170,7 +159,7 @@ public interface AgilityConfig extends Config keyName = "agilityArenaTimer", name = "Agility Arena timer", description = "Configures whether Agility Arena timer is displayed", - position = 12 + position = 11 ) default boolean showAgilityArenaTimer() { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java index de865f8339..dad500879d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilityPlugin.java @@ -67,7 +67,10 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.game.AgilityShortcut; import net.runelite.client.game.ItemManager; 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.plugins.xptracker.XpTrackerService; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; @@ -76,6 +79,7 @@ import net.runelite.client.ui.overlay.infobox.InfoBoxManager; description = "Show helpful information about agility courses and obstacles", tags = {"grace", "marks", "overlay", "shortcuts", "skilling", "traps"} ) +@PluginDependency(XpTrackerPlugin.class) @Slf4j public class AgilityPlugin extends Plugin { @@ -111,6 +115,9 @@ public class AgilityPlugin extends Plugin @Inject private ItemManager itemManager; + @Inject + private XpTrackerService xpTrackerService; + @Getter private AgilitySession session; @@ -211,14 +218,14 @@ public class AgilityPlugin extends Plugin if (session != null && session.getCourse() == course) { - session.incrementLapCount(client); + session.incrementLapCount(client, xpTrackerService); } else { session = new AgilitySession(course); // New course found, reset lap count and set new course session.resetLapCount(); - session.incrementLapCount(client); + session.incrementLapCount(client, xpTrackerService); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilitySession.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilitySession.java index 72e9a0dd07..2b8c46d7b1 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilitySession.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/AgilitySession.java @@ -28,9 +28,8 @@ import java.time.Instant; import lombok.Getter; import lombok.Setter; import net.runelite.api.Client; -import net.runelite.api.Experience; import net.runelite.api.Skill; -import net.runelite.api.VarPlayer; +import net.runelite.client.plugins.xptracker.XpTrackerService; @Getter @Setter @@ -39,7 +38,6 @@ class AgilitySession private final Courses course; private Instant lastLapCompleted; private int totalLaps; - private int lapsTillLevel; private int lapsTillGoal; AgilitySession(Courses course) @@ -47,30 +45,21 @@ class AgilitySession this.course = course; } - void incrementLapCount(Client client) + void incrementLapCount(Client client, XpTrackerService xpTrackerService) { lastLapCompleted = Instant.now(); ++totalLaps; - int currentExp = client.getSkillExperience(Skill.AGILITY); - int nextLevel = client.getRealSkillLevel(Skill.AGILITY) + 1; + final int currentExp = client.getSkillExperience(Skill.AGILITY); + final int goalXp = xpTrackerService.getEndGoalXp(Skill.AGILITY); + final int goalRemainingXp = goalXp - currentExp; - int remainingXp; - do - { - remainingXp = nextLevel <= Experience.MAX_VIRT_LEVEL ? Experience.getXpForLevel(nextLevel) - currentExp : 0; - nextLevel++; - } while (remainingXp < 0); - - lapsTillLevel = remainingXp > 0 ? (int) Math.ceil(remainingXp / course.getTotalXp()) : 0; - int goalRemainingXp = client.getVar(VarPlayer.AGILITY_GOAL_END) - currentExp; lapsTillGoal = goalRemainingXp > 0 ? (int) Math.ceil(goalRemainingXp / course.getTotalXp()) : 0; } void resetLapCount() { totalLaps = 0; - lapsTillLevel = 0; lapsTillGoal = 0; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/agility/LapCounterOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/agility/LapCounterOverlay.java index a53f6bac4e..d1df2ea98f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/agility/LapCounterOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/agility/LapCounterOverlay.java @@ -85,15 +85,7 @@ class LapCounterOverlay extends Overlay .right(Integer.toString(session.getTotalLaps())) .build()); - if (config.lapsToLevel() && session.getLapsTillLevel() > 0) - { - panelComponent.getChildren().add(LineComponent.builder() - .left("Laps until level:") - .right(Integer.toString(session.getLapsTillLevel())) - .build()); - } - - if (config.lapsToGoal() && session.getLapsTillGoal() > 0) + if (config.lapsToLevel() && session.getLapsTillGoal() > 0) { panelComponent.getChildren().add(LineComponent.builder() .left("Laps until goal:") From 171afd2e2f78a32f942d83f94c58708fc3c20ccf Mon Sep 17 00:00:00 2001 From: dekvall Date: Sun, 23 Feb 2020 21:03:23 +0100 Subject: [PATCH 03/27] loot tracker: add drift net reward --- runelite-api/src/main/java/net/runelite/api/InventoryID.java | 4 ++++ .../src/main/java/net/runelite/api/widgets/WidgetID.java | 1 + .../client/plugins/loottracker/LootTrackerPlugin.java | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/runelite-api/src/main/java/net/runelite/api/InventoryID.java b/runelite-api/src/main/java/net/runelite/api/InventoryID.java index 83a8ffe68e..dfe25ff2ed 100644 --- a/runelite-api/src/main/java/net/runelite/api/InventoryID.java +++ b/runelite-api/src/main/java/net/runelite/api/InventoryID.java @@ -57,6 +57,10 @@ public enum InventoryID * Monkey madness puzzle box inventory. */ MONKEY_MADNESS_PUZZLE_BOX(221), + /** + * Drift net fishing reward + */ + DRIFT_NET_FISHING_REWARD(307), /** * Kingdom Of Miscellania reward inventory. */ diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 8cda386cd5..a2298314da 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -118,6 +118,7 @@ public class WidgetID public static final int WORLD_SWITCHER_GROUP_ID = 69; public static final int DIALOG_OPTION_GROUP_ID = 219; public static final int DIALOG_PLAYER_GROUP_ID = 217; + public static final int DRIFT_NET_FISHING_REWARD_GROUP_ID = 607; public static final int FOSSIL_ISLAND_OXYGENBAR_ID = 609; public static final int MINIGAME_TAB_ID = 76; public static final int SPELLBOOK_GROUP_ID = 218; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java index f62e2b4e79..ae0237939a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java @@ -445,6 +445,10 @@ public class LootTrackerPlugin extends Plugin event = "Fishing Trawler"; container = client.getItemContainer(InventoryID.FISHING_TRAWLER_REWARD); break; + case (WidgetID.DRIFT_NET_FISHING_REWARD_GROUP_ID): + event = "Drift Net"; + container = client.getItemContainer(InventoryID.DRIFT_NET_FISHING_REWARD); + break; default: return; } From c50d60503d413c2ff0129a1f804f54f9ba6d5bb7 Mon Sep 17 00:00:00 2001 From: melkypie <5113962+melkypie@users.noreply.github.com> Date: Tue, 25 Feb 2020 19:13:07 +0200 Subject: [PATCH 04/27] itemidentification: add impling jars option Adds the ability to have impling jars be identified with an overlay over the item. --- .../ItemIdentification.java | 20 +++++++++++++++++-- .../ItemIdentificationConfig.java | 10 ++++++++++ .../ItemIdentificationOverlay.java | 6 ++++++ 3 files changed, 34 insertions(+), 2 deletions(-) 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 059c7acd8f..01b7a48583 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 @@ -195,7 +195,22 @@ enum ItemIdentification CADANTINE_POTION(Type.POTION, "Cadan", "C", ItemID.CADANTINE_POTION_UNF), LANTADYME_POTION(Type.POTION, "Lanta", "L", ItemID.LANTADYME_POTION_UNF), DWARF_WEED_POTION(Type.POTION, "Dwarf", "D", ItemID.DWARF_WEED_POTION_UNF), - TORSTOL_POTION(Type.POTION, "Torstol", "TOR", ItemID.TORSTOL_POTION_UNF); + TORSTOL_POTION(Type.POTION, "Torstol", "TOR", ItemID.TORSTOL_POTION_UNF), + + // Impling jars + BABY_IMPLING(Type.IMPLING_JAR, "Baby", "B", ItemID.BABY_IMPLING_JAR), + YOUNG_IMPLING(Type.IMPLING_JAR, "Young", "Y", ItemID.YOUNG_IMPLING_JAR), + GOURMET_IMPLING(Type.IMPLING_JAR, "Gourmet", "G", ItemID.GOURMET_IMPLING_JAR), + EARTH_IMPLING(Type.IMPLING_JAR, "Earth", "EAR", ItemID.EARTH_IMPLING_JAR), + ESSENCE_IMPLING(Type.IMPLING_JAR, "Essen", "ESS", ItemID.ESSENCE_IMPLING_JAR), + ECLECTIC_IMPLING(Type.IMPLING_JAR, "Eclect", "ECL", ItemID.ECLECTIC_IMPLING_JAR), + NATURE_IMPLING(Type.IMPLING_JAR, "Nature", "NAT", ItemID.NATURE_IMPLING_JAR), + MAGPIE_IMPLING(Type.IMPLING_JAR, "Magpie", "M", ItemID.MAGPIE_IMPLING_JAR), + NINJA_IMPLING(Type.IMPLING_JAR, "Ninja", "NIN", ItemID.NINJA_IMPLING_JAR), + CRYSTAL_IMPLING(Type.IMPLING_JAR, "Crystal", "C", ItemID.CRYSTAL_IMPLING_JAR), + DRAGON_IMPLING(Type.IMPLING_JAR, "Dragon", "D", ItemID.DRAGON_IMPLING_JAR), + LUCKY_IMPLING(Type.IMPLING_JAR, "Lucky", "L", ItemID.LUCKY_IMPLING_JAR); + final Type type; final String medName; @@ -239,6 +254,7 @@ enum ItemIdentification SAPLING, ORE, GEM, - POTION + POTION, + IMPLING_JAR } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationConfig.java index ca05bfdcba..13cc1e941d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationConfig.java @@ -113,4 +113,14 @@ public interface ItemIdentificationConfig extends Config { return false; } + + @ConfigItem( + keyName = "showImplingJars", + name = "Impling jars", + description = "Show identification on Impling jars" + ) + default boolean showImplingJars() + { + return false; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java index b09ff5ab89..fe24261146 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemidentification/ItemIdentificationOverlay.java @@ -101,6 +101,12 @@ class ItemIdentificationOverlay extends WidgetItemOverlay return; } break; + case IMPLING_JAR: + if (!config.showImplingJars()) + { + return; + } + break; } graphics.setFont(FontManager.getRunescapeSmallFont()); From 1a388f1765c1d2a7cd82628ed9f18d6287484f96 Mon Sep 17 00:00:00 2001 From: melkypie <5113962+melkypie@users.noreply.github.com> Date: Thu, 27 Feb 2020 12:42:53 +0200 Subject: [PATCH 05/27] mining: update duration to use GAME_TICKS instead of milliseconds --- .../client/plugins/mining/MiningOverlay.java | 4 +- .../runelite/client/plugins/mining/Rock.java | 43 ++++++++++--------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java index c0d06474cf..85a6897c5f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java @@ -44,8 +44,8 @@ import net.runelite.client.ui.overlay.components.ProgressPieComponent; class MiningOverlay extends Overlay { // Range of Motherlode vein respawn time - not 100% confirmed but based on observation - static final int ORE_VEIN_MAX_RESPAWN_TIME = 166; - private static final int ORE_VEIN_MIN_RESPAWN_TIME = 90; + static final int ORE_VEIN_MAX_RESPAWN_TIME = 277; // Game ticks + private static final int ORE_VEIN_MIN_RESPAWN_TIME = 150; // Game ticks private static final float ORE_VEIN_RANDOM_PERCENT_THRESHOLD = (float) ORE_VEIN_MIN_RESPAWN_TIME / ORE_VEIN_MAX_RESPAWN_TIME; private static final Color DARK_GREEN = new Color(0, 100, 0); private static final int MOTHERLODE_UPPER_FLOOR_HEIGHT = -500; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java index 582d7fd14a..3ff56007ac 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java @@ -30,20 +30,21 @@ import java.util.Map; import lombok.AccessLevel; import lombok.Getter; import static net.runelite.api.ObjectID.*; +import static net.runelite.client.util.RSTimeUnit.*; enum Rock { - TIN(Duration.ofMillis(2400), 0, ROCKS_11360, ROCKS_11361), - COPPER(Duration.ofMillis(2400), 0, ROCKS_10943, ROCKS_11161), - IRON(Duration.ofMillis(5400), 0, ROCKS_11364, ROCKS_11365, ROCKS_36203) + TIN(Duration.of(4, GAME_TICKS), 0, ROCKS_11360, ROCKS_11361), + COPPER(Duration.of(4, GAME_TICKS), 0, ROCKS_10943, ROCKS_11161), + IRON(Duration.of(9, GAME_TICKS), 0, ROCKS_11364, ROCKS_11365, ROCKS_36203) { @Override Duration getRespawnTime(int region) { - return region == MINING_GUILD ? Duration.ofMillis(2400) : super.respawnTime; + return region == MINING_GUILD ? Duration.of(4, GAME_TICKS) : super.respawnTime; } }, - COAL(Duration.ofMillis(29400), 0, ROCKS_11366, ROCKS_11367, ROCKS_36204) + COAL(Duration.of(49, GAME_TICKS), 0, ROCKS_11366, ROCKS_11367, ROCKS_36204) { @Override Duration getRespawnTime(int region) @@ -51,46 +52,46 @@ enum Rock switch (region) { case MINING_GUILD: - return Duration.ofMillis(14400); + return Duration.of(24, GAME_TICKS); case MISCELLANIA: - return Duration.ofMillis(6600); + return Duration.of(11, GAME_TICKS); default: return super.respawnTime; } } }, - SILVER(Duration.ofMinutes(1), 0, ROCKS_11368, ROCKS_11369, ROCKS_36205), - SANDSTONE(Duration.ofMillis(5400), 0, ROCKS_11386), - GOLD(Duration.ofMinutes(1), 0, ROCKS_11370, ROCKS_11371, ROCKS_36206), - GRANITE(Duration.ofMillis(5400), 0, ROCKS_11387), - MITHRIL(Duration.ofMinutes(2), 0, ROCKS_11372, ROCKS_11373, ROCKS_36207) + SILVER(Duration.of(100, GAME_TICKS), 0, ROCKS_11368, ROCKS_11369, ROCKS_36205), + SANDSTONE(Duration.of(9, GAME_TICKS), 0, ROCKS_11386), + GOLD(Duration.of(100, GAME_TICKS), 0, ROCKS_11370, ROCKS_11371, ROCKS_36206), + GRANITE(Duration.of(9, GAME_TICKS), 0, ROCKS_11387), + MITHRIL(Duration.of(200, GAME_TICKS), 0, ROCKS_11372, ROCKS_11373, ROCKS_36207) { @Override Duration getRespawnTime(int region) { - return region == MINING_GUILD ? Duration.ofMinutes(1) : super.respawnTime; + return region == MINING_GUILD ? Duration.of(100, GAME_TICKS) : super.respawnTime; } }, - ADAMANTITE(Duration.ofMinutes(4), 0, ROCKS_11374, ROCKS_11375, ROCKS_36208) + ADAMANTITE(Duration.of(400, GAME_TICKS), 0, ROCKS_11374, ROCKS_11375, ROCKS_36208) { @Override Duration getRespawnTime(int region) { - return region == MINING_GUILD || region == WILDERNESS_RESOURCE_AREA ? Duration.ofMinutes(2) : super.respawnTime; + return region == MINING_GUILD || region == WILDERNESS_RESOURCE_AREA ? Duration.of(200, GAME_TICKS) : super.respawnTime; } }, - RUNITE(Duration.ofMinutes(12), 0, ROCKS_11376, ROCKS_11377, ROCKS_36209) + RUNITE(Duration.of(1200, GAME_TICKS), 0, ROCKS_11376, ROCKS_11377, ROCKS_36209) { @Override Duration getRespawnTime(int region) { - return region == MINING_GUILD ? Duration.ofMinutes(6) : super.respawnTime; + return region == MINING_GUILD ? Duration.of(600, GAME_TICKS) : super.respawnTime; } }, - ORE_VEIN(Duration.ofSeconds(MiningOverlay.ORE_VEIN_MAX_RESPAWN_TIME), 150), - AMETHYST(Duration.ofSeconds(75), 120), - ASH_VEIN(Duration.ofSeconds(30), 0, ASH_PILE), - GEM_ROCK(Duration.ofMinutes(1), 0, ROCKS_11380, ROCKS_11381); + ORE_VEIN(Duration.of(MiningOverlay.ORE_VEIN_MAX_RESPAWN_TIME, GAME_TICKS), 150), + AMETHYST(Duration.of(125, GAME_TICKS), 120), + ASH_VEIN(Duration.of(50, GAME_TICKS), 0, ASH_PILE), + GEM_ROCK(Duration.of(100, GAME_TICKS), 0, ROCKS_11380, ROCKS_11381); private static final int WILDERNESS_RESOURCE_AREA = 12605; private static final int MISCELLANIA = 10044; From a366bdd32ae79a236226434c3c42f2d25f6bfd31 Mon Sep 17 00:00:00 2001 From: melkypie <5113962+melkypie@users.noreply.github.com> Date: Thu, 27 Feb 2020 12:59:52 +0200 Subject: [PATCH 06/27] mining: add urt, efh, te and basalt respawn timers --- .../main/java/net/runelite/client/plugins/mining/Rock.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java index 3ff56007ac..dabe0ececc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java @@ -91,7 +91,11 @@ enum Rock ORE_VEIN(Duration.of(MiningOverlay.ORE_VEIN_MAX_RESPAWN_TIME, GAME_TICKS), 150), AMETHYST(Duration.of(125, GAME_TICKS), 120), ASH_VEIN(Duration.of(50, GAME_TICKS), 0, ASH_PILE), - GEM_ROCK(Duration.of(100, GAME_TICKS), 0, ROCKS_11380, ROCKS_11381); + GEM_ROCK(Duration.of(100, GAME_TICKS), 0, ROCKS_11380, ROCKS_11381), + URT_SALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33254), + EFH_SALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33255), + TE_SALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33256), + BASALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33257); private static final int WILDERNESS_RESOURCE_AREA = 12605; private static final int MISCELLANIA = 10044; From c95bc2b5b7f8f0413e6f0cebb65dfe0e97230170 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 26 Feb 2020 17:19:18 -0500 Subject: [PATCH 07/27] cache: update kit definition --- .../java/net/runelite/cache/definitions/KitDefinition.java | 4 ++-- .../net/runelite/cache/definitions/loaders/KitLoader.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cache/src/main/java/net/runelite/cache/definitions/KitDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/KitDefinition.java index bd2ee535f5..001910138e 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/KitDefinition.java +++ b/cache/src/main/java/net/runelite/cache/definitions/KitDefinition.java @@ -35,8 +35,8 @@ public class KitDefinition public short[] retextureToFind; public short[] retextureToReplace; public int bodyPartId = -1; - public int[] modelIds; - public int[] models = new int[] + public int[] models; + public int[] chatheadModels = new int[] { -1, -1, -1, -1, -1 }; diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/KitLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/KitLoader.java index 9bd3f89a2f..5ae51f78e9 100644 --- a/cache/src/main/java/net/runelite/cache/definitions/loaders/KitLoader.java +++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/KitLoader.java @@ -53,11 +53,11 @@ public class KitLoader else if (opcode == 2) { int length = is.readUnsignedByte(); - def.modelIds = new int[length]; + def.models = new int[length]; for (int index = 0; index < length; ++index) { - def.modelIds[index] = is.readUnsignedShort(); + def.models[index] = is.readUnsignedShort(); } } else if (opcode == 3) @@ -90,7 +90,7 @@ public class KitLoader } else if (opcode >= 60 && opcode < 70) { - def.models[opcode - 60] = is.readShort(); + def.chatheadModels[opcode - 60] = is.readUnsignedShort(); } } From 41c8d8aff167544e116a3554fb3882155d0cdcb1 Mon Sep 17 00:00:00 2001 From: Jordan Atwood Date: Tue, 11 Feb 2020 22:48:31 -0800 Subject: [PATCH 08/27] HotColdLocation: Center some location spots Center some hot-cold locations as reported and verified from the mega issue. Ref: runelite/runelite#9601 --- .../clues/hotcold/HotColdLocation.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java index f7f498ad2d..39b0a2033e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/hotcold/HotColdLocation.java @@ -53,10 +53,10 @@ public enum HotColdLocation { ASGARNIA_WARRIORS(new WorldPoint(2860, 3562, 0), ASGARNIA, "North of the Warriors' Guild in Burthorpe."), ASGARNIA_JATIX(new WorldPoint(2915, 3425, 0), ASGARNIA, "East of Jatix's Herblore Shop in Taverley."), - ASGARNIA_BARB(new WorldPoint(3036, 3439, 0), ASGARNIA, "West of Barbarian Village."), - ASGARNIA_MIAZRQA(new WorldPoint(2973, 3489, 0), ASGARNIA, "North of Miazrqa's tower, outside Goblin Village."), - ASGARNIA_COW(new WorldPoint(3033, 3308, 0), ASGARNIA, "In the cow pen north of Sarah's Farming Shop."), - ASGARNIA_PARTY_ROOM(new WorldPoint(3026, 3363, 0), ASGARNIA, "Outside the Falador Party Room."), + ASGARNIA_BARB(new WorldPoint(3033, 3438, 0), ASGARNIA, "West of Barbarian Village."), + ASGARNIA_MIAZRQA(new WorldPoint(2972, 3486, 0), ASGARNIA, "North of Miazrqa's tower, outside Goblin Village."), + ASGARNIA_COW(new WorldPoint(3031, 3304, 0), ASGARNIA, "In the cow pen north of Sarah's Farming Shop."), + ASGARNIA_PARTY_ROOM(new WorldPoint(3030, 3364, 0), ASGARNIA, "Outside the Falador Party Room."), ASGARNIA_CRAFT_GUILD(new WorldPoint(2917, 3295, 0), ASGARNIA, "Outside the Crafting Guild cow pen."), ASGARNIA_RIMMINGTON(new WorldPoint(2978, 3241, 0), ASGARNIA, "In the centre of the Rimmington mine."), ASGARNIA_MUDSKIPPER(new WorldPoint(2987, 3110, 0), ASGARNIA, "Mudskipper Point, near the starfish in the south-west corner."), @@ -67,7 +67,7 @@ public enum HotColdLocation DESERT_BEDABIN_CAMP(new WorldPoint(3164, 3050, 0), DESERT, "Bedabin Camp, dig around the north tent."), DESERT_UZER(new WorldPoint(3431, 3106, 0), DESERT, "West of Uzer."), DESERT_POLLNIVNEACH(new WorldPoint(3287, 2975, 0), DESERT, "West of Pollnivneach."), - DESERT_MTA(new WorldPoint(3350, 3293, 0), DESERT, "Next to Mage Training Arena."), + DESERT_MTA(new WorldPoint(3347, 3295, 0), DESERT, "Next to Mage Training Arena."), DESERT_SHANTY(new WorldPoint(3294, 3106, 0), DESERT, "South-west of Shantay Pass."), DRAYNOR_MANOR_MUSHROOMS(true, new WorldPoint(3096, 3379, 0), MISTHALIN, "Patch of mushrooms just northwest of Draynor Manor"), DRAYNOR_WHEAT_FIELD(true, new WorldPoint(3120, 3282, 0), MISTHALIN, "Inside the wheat field next to Draynor Village"), @@ -88,26 +88,26 @@ public enum HotColdLocation FREMENNIK_PROVINCE_MISC_COURTYARD(new WorldPoint(2527, 3868, 0), FREMENNIK_PROVINCE, "Outside Miscellania's courtyard."), FREMENNIK_PROVINCE_FREMMY_ISLES_MINE(new WorldPoint(2374, 3850, 0), FREMENNIK_PROVINCE, "Central Fremennik Isles mine."), FREMENNIK_PROVINCE_WEST_ISLES_MINE(new WorldPoint(2313, 3854, 0), FREMENNIK_PROVINCE, "West Fremennik Isles mine."), - FREMENNIK_PROVINCE_WEST_JATIZSO_ENTRANCE(new WorldPoint(2391, 3813, 0), FREMENNIK_PROVINCE, "West of the Jatizso mine entrance."), + FREMENNIK_PROVINCE_WEST_JATIZSO_ENTRANCE(new WorldPoint(2393, 3812, 0), FREMENNIK_PROVINCE, "West of the Jatizso mine entrance."), FREMENNIK_PROVINCE_PIRATES_COVE(new WorldPoint(2210, 3814, 0), FREMENNIK_PROVINCE, "Pirates' Cove"), FREMENNIK_PROVINCE_ASTRAL_ALTER(new WorldPoint(2147, 3862, 0), FREMENNIK_PROVINCE, "Astral altar"), FREMENNIK_PROVINCE_LUNAR_VILLAGE(new WorldPoint(2084, 3916, 0), FREMENNIK_PROVINCE, "Lunar Isle, inside the village."), FREMENNIK_PROVINCE_LUNAR_NORTH(new WorldPoint(2106, 3949, 0), FREMENNIK_PROVINCE, "Lunar Isle, north of the village."), ICE_MOUNTAIN(true, new WorldPoint(3007, 3475, 0), MISTHALIN, "Atop Ice Mountain"), KANDARIN_SINCLAR_MANSION(new WorldPoint(2730, 3588, 0), KANDARIN, "North-west of the Sinclair Mansion, near the log balance shortcut."), - KANDARIN_CATHERBY(new WorldPoint(2774, 3433, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation."), + KANDARIN_CATHERBY(new WorldPoint(2774, 3436, 0), KANDARIN, "Catherby, between the bank and the beehives, near small rock formation."), KANDARIN_GRAND_TREE(new WorldPoint(2448, 3503, 0), KANDARIN, "Grand Tree, just east of the terrorchick gnome enclosure."), KANDARIN_SEERS(new WorldPoint(2735, 3486, 0), KANDARIN, "Between the Seers' Village bank and Camelot."), KANDARIN_MCGRUBORS_WOOD(new WorldPoint(2653, 3485, 0), KANDARIN, "McGrubor's Wood"), - KANDARIN_FISHING_BUILD(new WorldPoint(2586, 3372, 0), KANDARIN, "South of Fishing Guild"), - KANDARIN_WITCHHAVEN(new WorldPoint(2708, 3304, 0), KANDARIN, "Outside Witchaven, west of Jeb, Holgart, and Caroline."), + KANDARIN_FISHING_BUILD(new WorldPoint(2590, 3369, 0), KANDARIN, "South of Fishing Guild"), + KANDARIN_WITCHHAVEN(new WorldPoint(2707, 3306, 0), KANDARIN, "Outside Witchaven, west of Jeb, Holgart, and Caroline."), KANDARIN_NECRO_TOWER(new WorldPoint(2667, 3241, 0), KANDARIN, "Ground floor inside the Necromancer Tower. Easily accessed by using fairy ring code djp."), KANDARIN_FIGHT_ARENA(new WorldPoint(2587, 3135, 0), KANDARIN, "South of the Fight Arena, north-west of the Nightmare Zone."), KANDARIN_TREE_GNOME_VILLAGE(new WorldPoint(2526, 3160, 0), KANDARIN, "Tree Gnome Village, near the general store icon."), KANDARIN_GRAVE_OF_SCORPIUS(new WorldPoint(2464, 3228, 0), KANDARIN, "Grave of Scorpius"), - KANDARIN_KHAZARD_BATTLEFIELD(new WorldPoint(2518, 3249, 0), KANDARIN, "Khazard Battlefield, in the small ruins south of tracker gnome 2."), + KANDARIN_KHAZARD_BATTLEFIELD(new WorldPoint(2522, 3252, 0), KANDARIN, "Khazard Battlefield, south of Tracker gnome 2."), KANDARIN_WEST_ARDY(new WorldPoint(2535, 3322, 0), KANDARIN, "West Ardougne, near the staircase outside the Civic Office."), - KANDARIN_SW_TREE_GNOME_STRONGHOLD(new WorldPoint(2411, 3431, 0), KANDARIN, "South-west Tree Gnome Stronghold"), + KANDARIN_SW_TREE_GNOME_STRONGHOLD(new WorldPoint(2411, 3429, 0), KANDARIN, "South-west Tree Gnome Stronghold"), KANDARIN_OUTPOST(new WorldPoint(2457, 3362, 0), KANDARIN, "South of the Tree Gnome Stronghold, north-east of the Outpost."), KANDARIN_BAXTORIAN_FALLS(new WorldPoint(2534, 3479, 0), KANDARIN, "South-east of Almera's house on Baxtorian Falls."), KANDARIN_BA_AGILITY_COURSE(new WorldPoint(2540, 3548, 0), KANDARIN, "Inside the Barbarian Agility Course. Completion of Alfred Grimhand's Barcrawl is required."), @@ -119,17 +119,17 @@ public enum HotColdLocation KARAMJA_KHARAZI_SW(new WorldPoint(2783, 2898, 0), KARAMJA, "South-western part of Kharazi Jungle."), KARAMJA_CRASH_ISLAND(new WorldPoint(2909, 2737, 0), KARAMJA, "Northern part of Crash Island."), LUMBRIDGE_COW_FIELD(true, new WorldPoint(3174, 3336, 0), MISTHALIN, "Cow field north of Lumbridge"), - MISTHALIN_VARROCK_STONE_CIRCLE(new WorldPoint(3225, 3355, 0), MISTHALIN, "South of the stone circle near Varrock's entrance."), + MISTHALIN_VARROCK_STONE_CIRCLE(new WorldPoint(3225, 3356, 0), MISTHALIN, "South of the stone circle near Varrock's entrance."), MISTHALIN_LUMBRIDGE(new WorldPoint(3238, 3169, 0), MISTHALIN, "Just north-west of the Lumbridge Fishing tutor."), MISTHALIN_LUMBRIDGE_2(new WorldPoint(3170, 3278, 0), MISTHALIN, "North of the pond between Lumbridge and Draynor Village."), - MISTHALIN_GERTUDES(new WorldPoint(3158, 3421, 0), MISTHALIN, "North-east of Gertrude's house west of Varrock."), + MISTHALIN_GERTUDES(new WorldPoint(3154, 3421, 0), MISTHALIN, "North-east of Gertrude's house west of Varrock."), MISTHALIN_DRAYNOR_BANK(new WorldPoint(3098, 3234, 0), MISTHALIN, "South of Draynor Village bank."), MISTHALIN_LUMBER_YARD(new WorldPoint(3303, 3483, 0), MISTHALIN, "South of Lumber Yard, east of Assistant Serf."), MORYTANIA_BURGH_DE_ROTT(new WorldPoint(3545, 3253, 0), MORYTANIA, "In the north-east area of Burgh de Rott, by the reverse-L-shaped ruins."), MORYTANIA_PORT_PHASMATYS(new WorldPoint(3613, 3485, 0), MORYTANIA, "West of Port Phasmatys, south-east of fairy ring."), - MORYTANIA_HOLLOWS(new WorldPoint(3500, 3423, 0), MORYTANIA, "Inside The Hollows, south of the bridge which was repaired in a quest."), + MORYTANIA_HOLLOWS(new WorldPoint(3499, 3421, 0), MORYTANIA, "Inside The Hollows, south of the bridge which was repaired in a quest."), MORYTANIA_SWAMP(new WorldPoint(3422, 3374, 0), MORYTANIA, "Inside the Mort Myre Swamp, north-west of the Nature Grotto."), - MORYTANIA_HAUNTED_MINE(new WorldPoint(3441, 3259, 0), MORYTANIA, "At Haunted Mine quest start."), + MORYTANIA_HAUNTED_MINE(new WorldPoint(3444, 3255, 0), MORYTANIA, "At Haunted Mine quest start."), MORYTANIA_MAUSOLEUM(new WorldPoint(3499, 3539, 0), MORYTANIA, "South of the Mausoleum."), MORYTANIA_MOS_LES_HARMLESS(new WorldPoint(3744, 3041, 0), MORYTANIA, "Northern area of Mos Le'Harmless, between the lakes."), MORYTANIA_MOS_LES_HARMLESS_BAR(new WorldPoint(3670, 2974, 0), MORYTANIA, "Near Mos Le'Harmless southern bar."), @@ -140,22 +140,22 @@ public enum HotColdLocation WESTERN_PROVINCE_PISCATORIS(new WorldPoint(2334, 3685, 0), WESTERN_PROVINCE, "Piscatoris Fishing Colony"), WESTERN_PROVINCE_PISCATORIS_HUNTER_AREA(new WorldPoint(2359, 3564, 0), WESTERN_PROVINCE, "Eastern part of Piscatoris Hunter area, south-west of the Falconry."), WESTERN_PROVINCE_ARANDAR(new WorldPoint(2370, 3319, 0), WESTERN_PROVINCE, "South-west of the crystal gate to Arandar."), - WESTERN_PROVINCE_ELF_CAMP_EAST(new WorldPoint(2270, 3244, 0), WESTERN_PROVINCE, "East of Iorwerth Camp."), + WESTERN_PROVINCE_ELF_CAMP_EAST(new WorldPoint(2268, 3242, 0), WESTERN_PROVINCE, "East of Iorwerth Camp."), WESTERN_PROVINCE_ELF_CAMP_NW(new WorldPoint(2174, 3280, 0), WESTERN_PROVINCE, "North-west of Iorwerth Camp."), WESTERN_PROVINCE_LLETYA(new WorldPoint(2337, 3166, 0), WESTERN_PROVINCE, "In Lletya."), - WESTERN_PROVINCE_TYRAS(new WorldPoint(2204, 3157, 0), WESTERN_PROVINCE, "Near Tyras Camp."), + WESTERN_PROVINCE_TYRAS(new WorldPoint(2206, 3158, 0), WESTERN_PROVINCE, "Near Tyras Camp."), WESTERN_PROVINCE_ZULANDRA(new WorldPoint(2196, 3057, 0), WESTERN_PROVINCE, "The northern house at Zul-Andra."), WILDERNESS_5(new WorldPoint(3173, 3556, 0), WILDERNESS, "North of the Grand Exchange, level 5 Wilderness."), WILDERNESS_12(new WorldPoint(3038, 3612, 0), WILDERNESS, "South-east of the Dark Warriors' Fortress, level 12 Wilderness."), WILDERNESS_20(new WorldPoint(3225, 3676, 0), WILDERNESS, "East of the Corporeal Beast's lair, level 20 Wilderness."), WILDERNESS_27(new WorldPoint(3174, 3736, 0), WILDERNESS, "Inside the Ruins north of the Graveyard of Shadows, level 27 Wilderness."), - WILDERNESS_28(new WorldPoint(3374, 3734, 0), WILDERNESS, "East of Venenatis' nest, level 28 Wilderness."), + WILDERNESS_28(new WorldPoint(3377, 3737, 0), WILDERNESS, "East of Venenatis' nest, level 28 Wilderness."), WILDERNESS_32(new WorldPoint(3311, 3773, 0), WILDERNESS, "North of Venenatis' nest, level 32 Wilderness."), WILDERNESS_35(new WorldPoint(3153, 3795, 0), WILDERNESS, "East of the Wilderness canoe exit, level 35 Wilderness."), WILDERNESS_37(new WorldPoint(2975, 3811, 0), WILDERNESS, "South-east of the Chaos Temple, level 37 Wilderness."), WILDERNESS_38(new WorldPoint(3293, 3813, 0), WILDERNESS, "South of Callisto, level 38 Wilderness."), WILDERNESS_49(new WorldPoint(3140, 3910, 0), WILDERNESS, "South-west of the Deserted Keep, level 49 Wilderness."), - WILDERNESS_54(new WorldPoint(2983, 3946, 0), WILDERNESS, "West of the Wilderness Agility Course, level 54 Wilderness."), + WILDERNESS_54(new WorldPoint(2981, 3944, 0), WILDERNESS, "West of the Wilderness Agility Course, level 54 Wilderness."), ZEAH_BLASTMINE_BANK(new WorldPoint(1507, 3856, 0), ZEAH, "Next to the bank in the Lovakengj blast mine."), ZEAH_BLASTMINE_NORTH(new WorldPoint(1488, 3881, 0), ZEAH, "Northern part of the Lovakengj blast mine."), ZEAH_LOVAKITE_FURNACE(new WorldPoint(1507, 3819, 0), ZEAH, "Next to the lovakite furnace in Lovakengj."), @@ -174,11 +174,11 @@ public enum HotColdLocation ZEAH_ESSENCE_MINE_NE(new WorldPoint(1773, 3867, 0), ZEAH, "North-east of the Arceuus essence mine."), ZEAH_PISCARILUS_MINE(new WorldPoint(1768, 3705, 0), ZEAH, "South of the Piscarilius mine."), ZEAH_GOLDEN_FIELD_TAVERN(new WorldPoint(1718, 3647, 0), ZEAH, "South of The Golden Field tavern in the northern area of Hosidius."), - ZEAH_MESS_HALL(new WorldPoint(1658, 3621, 0), ZEAH, "East of the Mess hall."), + ZEAH_MESS_HALL(new WorldPoint(1656, 3621, 0), ZEAH, "East of the Mess hall."), ZEAH_WATSONS_HOUSE(new WorldPoint(1653, 3573, 0), ZEAH, "East of Watson's house."), ZEAH_VANNAHS_FARM_STORE(new WorldPoint(1806, 3521, 0), ZEAH, "North of Vannah's Farm Store, between the chicken coop and willow trees."), ZEAH_FARMING_GUILD_W(new WorldPoint(1208, 3736, 0), ZEAH, "West of the Farming Guild."), - ZEAH_DAIRY_COW(new WorldPoint(1320, 3718, 0), ZEAH, "North-east of the Kebos Lowlands, east of the dairy cow."), + ZEAH_DAIRY_COW(new WorldPoint(1324, 3722, 0), ZEAH, "North-east of the Kebos Lowlands, east of the dairy cow."), ZEAH_CRIMSON_SWIFTS(new WorldPoint(1186, 3583, 0), ZEAH, "South-west of the Kebos Swamp, below the crimson swifts."); private final boolean beginnerClue; From ed0846f487c8bb32853db4450186b4768c7d99f8 Mon Sep 17 00:00:00 2001 From: DeliciousLunch55 Date: Fri, 28 Feb 2020 00:29:23 -0600 Subject: [PATCH 09/27] clues: Improve Yanille dungeon basement clue hint --- .../runelite/client/plugins/cluescrolls/clues/CrypticClue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java index 8071452ca5..dd327a795a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java @@ -172,7 +172,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc new CrypticClue("Someone watching the fights in the Duel Arena is your next destination.", "Jeed", new WorldPoint(3360, 3242, 0), "Talk to Jeed, found on the upper floors, at the Duel Arena."), new CrypticClue("It seems to have reached the end of the line, and it's still empty.", MINE_CART_6045, new WorldPoint(3041, 9820, 0), "Search the carts in the northern part of the Dwarven Mine."), new CrypticClue("You'll have to plug your nose if you use this source of herbs.", null, "Kill an Aberrant or Deviant spectre."), - new CrypticClue("When you get tired of fighting, go deep, deep down until you need an antidote.", CRATE_357, new WorldPoint(2576, 9583, 0), "Go to Yanille Agility dungeon and fall into the place with the poison spiders. Search the crate by the stairs leading up."), + new CrypticClue("When you get tired of fighting, go deep, deep down until you need an antidote.", CRATE_357, new WorldPoint(2576, 9583, 0), "Go to Yanille Agility dungeon and fall into the place with the poison spiders by praying at the Chaos altar. Search the crate by the stairs leading up."), new CrypticClue("Search the bookcase in the monastery.", BOOKCASE_380, new WorldPoint(3054, 3484, 0), "Search the southeastern bookcase at Edgeville Monastery."), new CrypticClue("Surprising? I bet he is...", "Sir Prysin", new WorldPoint(3205, 3474, 0), "Talk to Sir Prysin in Varrock Palace."), new CrypticClue("Search upstairs in the houses of Seers' Village for some drawers.", DRAWERS_25766, new WorldPoint(2716, 3471, 1), "Located in the house with the spinning wheel. South of the Seers' Village bank."), From 634758626c7fb409eeb47b283a257927bfdf9144 Mon Sep 17 00:00:00 2001 From: JZomerlei Date: Fri, 28 Feb 2020 05:20:41 -0500 Subject: [PATCH 10/27] Add Mythical Cape icon to POH (#10828) --- .../runelite/client/plugins/poh/PohConfig.java | 10 ++++++++++ .../net/runelite/client/plugins/poh/PohIcons.java | 3 ++- .../runelite/client/plugins/poh/PohOverlay.java | 4 ++++ .../runelite/client/plugins/poh/mythicalcape.png | Bin 0 -> 291 bytes 4 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 runelite-client/src/main/resources/net/runelite/client/plugins/poh/mythicalcape.png diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohConfig.java index 9496352800..317be3b2cf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohConfig.java @@ -160,4 +160,14 @@ public interface PohConfig extends Config { return true; } + + @ConfigItem( + keyName = "showMythicalCape", + name = "Show Mythical Cape", + description = "Configures whether or not the Mythical Cape is displayed" + ) + default boolean showMythicalCape() + { + return true; + } } 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 b5b972f61e..370f8061a5 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 @@ -86,7 +86,8 @@ public enum PohIcons ), DIGSITEPENDANT("digsitependant", DIGSITE_PENDANT, DIGSITE_PENDANT_33417, DIGSITE_PENDANT_33418, DIGSITE_PENDANT_33420 - ); + ), + MYTHICALCAPE("mythicalcape", MYTHICAL_CAPE, MOUNTED_MYTHICAL_CAPE); private static final Map minimapIcons; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohOverlay.java index 368e763f8f..73d970a5a2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/poh/PohOverlay.java @@ -144,5 +144,9 @@ public class PohOverlay extends Overlay { iconList.add(PohIcons.XERICSTALISMAN); } + if (config.showMythicalCape()) + { + iconList.add(PohIcons.MYTHICALCAPE); + } } } diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/poh/mythicalcape.png b/runelite-client/src/main/resources/net/runelite/client/plugins/poh/mythicalcape.png new file mode 100644 index 0000000000000000000000000000000000000000..9e2d64d3285b744309b6c0802440084ec558c53f GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^{2Tb|4GQ211!mgbRNoF7E2EnL3rIDhN;Z7184uGhJ0XY5}oaG?Kl#MG|N*AGL# zJ@+W`EI6#aNj~O9fbxOac}!dXm93to#AevY`TcBki(E_oyT$|aL?>HlOQ!tu?3sPc z;YK9u+#9n*gvIlowtgHRdWyf6Gkd}h%j55Xeqiu)^>bP0l+XkKDVT3D literal 0 HcmV?d00001 From ddcaab68f75cb38c77872d291a0c629e189692f5 Mon Sep 17 00:00:00 2001 From: loldudester Date: Mon, 24 Feb 2020 15:34:34 +0000 Subject: [PATCH 11/27] GroundItems: Keep item lists in input order --- .../client/plugins/grounditems/GroundItemsPlugin.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index f9919508a3..17f73286dc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -36,12 +36,10 @@ import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Queue; -import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; import javax.inject.Inject; @@ -548,8 +546,8 @@ public class GroundItemsPlugin extends Plugin void updateList(String item, boolean hiddenList) { - final Set hiddenItemSet = new HashSet<>(hiddenItemList); - final Set highlightedItemSet = new HashSet<>(highlightedItemsList); + final List hiddenItemSet = new ArrayList<>(hiddenItemList); + final List highlightedItemSet = new ArrayList<>(highlightedItemsList); if (hiddenList) { @@ -560,7 +558,7 @@ public class GroundItemsPlugin extends Plugin hiddenItemSet.removeIf(item::equalsIgnoreCase); } - final Set items = hiddenList ? hiddenItemSet : highlightedItemSet; + final List items = hiddenList ? hiddenItemSet : highlightedItemSet; if (!items.removeIf(item::equalsIgnoreCase)) { From 98aa9fb7d79e48169b39472c8115ad21dec303d4 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Thu, 27 Feb 2020 05:28:07 +0100 Subject: [PATCH 12/27] Move matchesSearchTerms util to Text class Signed-off-by: Tomas Slusny --- .../ExternalPluginManifest.java | 3 +++ .../client/plugins/config/PluginListItem.java | 22 +------------------ .../plugins/config/PluginListPanel.java | 2 +- .../java/net/runelite/client/util/Text.java | 20 +++++++++++++++++ 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginManifest.java b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginManifest.java index 95b5fe5637..0678bf768c 100644 --- a/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginManifest.java +++ b/runelite-client/src/main/java/net/runelite/client/externalplugins/ExternalPluginManifest.java @@ -29,6 +29,7 @@ import com.google.common.io.Files; import java.io.File; import java.io.IOException; import java.net.URL; +import javax.annotation.Nullable; import lombok.Data; import lombok.EqualsAndHashCode; import net.runelite.client.RuneLite; @@ -45,7 +46,9 @@ public class ExternalPluginManifest private String displayName; private String version; private String author; + @Nullable private String description; + @Nullable private String[] tags; @EqualsAndHashCode.Exclude private URL support; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java index 9b1575acc3..2c5cfe5bbd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java @@ -52,12 +52,9 @@ import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.SwingUtil; -import org.apache.commons.text.similarity.JaroWinklerDistance; class PluginListItem extends JPanel { - private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance(); - private static final ImageIcon CONFIG_ICON; private static final ImageIcon CONFIG_ICON_HOVER; private static final ImageIcon ON_STAR; @@ -68,6 +65,7 @@ class PluginListItem extends JPanel @Getter private final PluginConfigurationDescriptor pluginConfig; + @Getter private final List keywords = new ArrayList<>(); private final JToggleButton pinButton; @@ -202,24 +200,6 @@ class PluginListItem extends JPanel onOffToggle.setSelected(enabled); } - /** - * Checks if all the search terms in the given list matches at least one keyword. - * - * @return true if all search terms matches at least one keyword, or false if otherwise. - */ - boolean matchesSearchTerms(String[] searchTerms) - { - for (String term : searchTerms) - { - if (keywords.stream().noneMatch((t) -> t.contains(term) || - DISTANCE.apply(t, term) > 0.9)) - { - return false; - } - } - return true; - } - private void openGroupConfigPanel() { pluginListPanel.openConfigurationPanel(pluginConfig); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java index 2e96a4dae9..57ac970cae 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java @@ -271,7 +271,7 @@ class PluginListPanel extends PluginPanel final String[] searchTerms = text.toLowerCase().split(" "); pluginList.forEach(listItem -> { - if (pinned == listItem.isPinned() && listItem.matchesSearchTerms(searchTerms)) + if (pinned == listItem.isPinned() && Text.matchesSearchTerms(searchTerms, listItem.getKeywords())) { mainPanel.add(listItem); } diff --git a/runelite-client/src/main/java/net/runelite/client/util/Text.java b/runelite-client/src/main/java/net/runelite/client/util/Text.java index 78c08f16aa..6fc303a97e 100644 --- a/runelite-client/src/main/java/net/runelite/client/util/Text.java +++ b/runelite-client/src/main/java/net/runelite/client/util/Text.java @@ -32,12 +32,14 @@ import java.util.Collection; import java.util.List; import java.util.regex.Pattern; import org.apache.commons.text.WordUtils; +import org.apache.commons.text.similarity.JaroWinklerDistance; /** * A set of utilities to use when dealing with text. */ public class Text { + private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance(); private static final Pattern TAG_REGEXP = Pattern.compile("<[^>]*>"); private static final Splitter COMMA_SPLITTER = Splitter .on(",") @@ -186,4 +188,22 @@ public class Text return toString; } + + /** + * Checks if all the search terms in the given list matches at least one keyword. + * + * @return true if all search terms matches at least one keyword, or false if otherwise. + */ + public static boolean matchesSearchTerms(String[] searchTerms, final Collection keywords) + { + for (String term : searchTerms) + { + if (keywords.stream().noneMatch((t) -> t.contains(term) || + DISTANCE.apply(t, term) > 0.9)) + { + return false; + } + } + return true; + } } From fdd75b1296df120848c39cccd7b6bcf635fde852 Mon Sep 17 00:00:00 2001 From: loldudester Date: Thu, 27 Feb 2020 04:08:39 +0000 Subject: [PATCH 13/27] Plugin Hub: Sort plugins by display name --- .../java/net/runelite/client/plugins/config/PluginHubPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java index 169f061d17..a94c94a592 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java @@ -543,7 +543,7 @@ class PluginHubPanel extends PluginPanel else { stream = stream - .sorted(Comparator.comparing(PluginItem::isInstalled)); + .sorted(Comparator.comparing(PluginItem::isInstalled).thenComparing(p -> p.manifest.getDisplayName())); } stream.forEach(mainPanel::add); From dcc2c577bdf61c9b87a9ea815eefe57f13afbd16 Mon Sep 17 00:00:00 2001 From: loldudester Date: Thu, 27 Feb 2020 01:49:17 +0000 Subject: [PATCH 14/27] Plugin Hub: Rework search to something remotely useful --- .../client/plugins/config/PluginHubPanel.java | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java index a94c94a592..269cfe574f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginHubPanel.java @@ -37,7 +37,9 @@ import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.image.BufferedImage; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; @@ -45,7 +47,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import java.util.function.Function; -import java.util.function.ToDoubleFunction; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -85,8 +86,8 @@ import net.runelite.client.ui.components.IconTextField; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.SwingUtil; +import net.runelite.client.util.Text; import net.runelite.client.util.VerificationException; -import org.apache.commons.text.similarity.JaroWinklerDistance; @Slf4j @Singleton @@ -98,7 +99,6 @@ class PluginHubPanel extends PluginPanel private static final ImageIcon CONFIGURE_ICON; private static final ImageIcon CONFIGURE_ICON_HOVER; private static final Pattern SPACES = Pattern.compile(" +"); - private static final JaroWinklerDistance DISTANCE = new JaroWinklerDistance(); static { @@ -119,16 +119,13 @@ class PluginHubPanel extends PluginPanel private static final int HEIGHT = 70; private static final int ICON_WIDTH = 48; private static final int BOTTOM_LINE_HEIGHT = 16; - static final float MIN_FILTER_SCORE = .8f; private final ExternalPluginManifest manifest; + private final List keywords = new ArrayList<>(); @Getter private final boolean installed; - @Getter - private float filter; - PluginItem(ExternalPluginManifest newManifest, Collection loadedPlugins, boolean installed) { ExternalPluginManifest loaded = null; @@ -140,6 +137,23 @@ class PluginHubPanel extends PluginPanel manifest = newManifest == null ? loaded : newManifest; this.installed = installed; + if (manifest != null) + { + Collections.addAll(keywords, SPACES.split(manifest.getDisplayName().toLowerCase())); + + if (manifest.getDescription() != null) + { + Collections.addAll(keywords, SPACES.split(manifest.getDescription().toLowerCase())); + } + + Collections.addAll(keywords, manifest.getAuthor().toLowerCase()); + + if (manifest.getTags() != null) + { + Collections.addAll(keywords, manifest.getTags()); + } + } + setBackground(ColorScheme.DARKER_GRAY_COLOR); setOpaque(true); @@ -302,23 +316,6 @@ class PluginHubPanel extends PluginPanel .addComponent(addrm, BOTTOM_LINE_HEIGHT, BOTTOM_LINE_HEIGHT, BOTTOM_LINE_HEIGHT)) .addGap(5))); } - - float setFilter(String[] filter) - { - ToDoubleFunction match = r -> Stream.of(filter) - .mapToDouble(l -> Math.pow(DISTANCE.apply(l, r), 2)) - .max() - .orElse(0.D); - - double sim = SPACES.splitAsStream(manifest.getDisplayName()).collect(Collectors.averagingDouble(match)) * 2; - - if (manifest.getTags() != null) - { - sim += Stream.of(manifest.getTags()).mapToDouble(match).sum(); - } - - return this.filter = (float) sim; - } } private final PluginListPanel pluginListPanel; @@ -537,8 +534,8 @@ class PluginHubPanel extends PluginPanel { String[] searchArray = SPACES.split(search.toLowerCase()); stream = stream - .filter(p -> p.setFilter(searchArray) > PluginItem.MIN_FILTER_SCORE) - .sorted(Comparator.comparing(PluginItem::getFilter)); + .filter(p -> Text.matchesSearchTerms(searchArray, p.keywords)) + .sorted(Comparator.comparing(p -> p.manifest.getDisplayName())); } else { From f0679af91a844f1be08f9fee85ef3b276d0d2746 Mon Sep 17 00:00:00 2001 From: jsnellings1 Date: Fri, 28 Feb 2020 14:57:27 -0500 Subject: [PATCH 15/27] slayer: cancel task when leaving the Inferno --- .../java/net/runelite/client/plugins/slayer/SlayerPlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java index 864659842b..8ac2601931 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/slayer/SlayerPlugin.java @@ -95,6 +95,7 @@ public class SlayerPlugin extends Plugin private static final Pattern CHAT_COMPLETE_MESSAGE = Pattern.compile("(?:\\d+,)*\\d+"); private static final String CHAT_CANCEL_MESSAGE = "Your task has been cancelled."; private static final String CHAT_CANCEL_MESSAGE_JAD = "You no longer have a slayer task as you left the fight cave."; + private static final String CHAT_CANCEL_MESSAGE_ZUK = "You no longer have a slayer task as you left the Inferno."; private static final String CHAT_SUPERIOR_MESSAGE = "A superior foe has appeared..."; private static final String CHAT_BRACELET_SLAUGHTER = "Your bracelet of slaughter prevents your slayer"; private static final Pattern CHAT_BRACELET_SLAUGHTER_REGEX = Pattern.compile("Your bracelet of slaughter prevents your slayer count decreasing. It has (\\d{1,2}) charge[s]? left."); @@ -483,7 +484,7 @@ public class SlayerPlugin extends Plugin return; } - if (chatMsg.equals(CHAT_GEM_COMPLETE_MESSAGE) || chatMsg.equals(CHAT_CANCEL_MESSAGE) || chatMsg.equals(CHAT_CANCEL_MESSAGE_JAD)) + if (chatMsg.equals(CHAT_GEM_COMPLETE_MESSAGE) || chatMsg.equals(CHAT_CANCEL_MESSAGE) || chatMsg.equals(CHAT_CANCEL_MESSAGE_JAD) || chatMsg.equals(CHAT_CANCEL_MESSAGE_ZUK)) { setTask("", 0, 0); return; From 78164374c3b358c2d948740e7a54d51a45b42f4f Mon Sep 17 00:00:00 2001 From: DeliciousLunch55 Date: Fri, 28 Feb 2020 16:15:16 -0600 Subject: [PATCH 16/27] clues: Update "Slay a nechryael" clue text --- .../client/plugins/cluescrolls/clues/SkillChallengeClue.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java index eb5d246e43..be50cbd31c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/SkillChallengeClue.java @@ -150,7 +150,7 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll new SkillChallengeClue("Smith a runite med helm.", item(ItemID.HAMMER), item(ItemID.RUNITE_BAR)), new SkillChallengeClue("Teleport to a spirit tree you planted yourself."), new SkillChallengeClue("Create a Barrows teleport tablet.", item(ItemID.DARK_ESSENCE_BLOCK), xOfItem(ItemID.BLOOD_RUNE, 1), xOfItem(ItemID.LAW_RUNE, 2), xOfItem(ItemID.SOUL_RUNE, 2)), - new SkillChallengeClue("Kill a Nechryael.", "slay a nechryael"), + new SkillChallengeClue("Kill a Nechryael.", "slay a nechryael in the slayer tower."), new SkillChallengeClue("Kill a Spiritual Mage while wearing something from their god.", "kill the spiritual, magic and godly whilst representing their own god."), new SkillChallengeClue("Create an unstrung dragonstone amulet at a furnace.", item(ItemID.GOLD_BAR), item(ItemID.DRAGONSTONE), item(ItemID.AMULET_MOULD)), new SkillChallengeClue("Burn a magic log.", item(ItemID.MAGIC_LOGS), item(ItemID.TINDERBOX)), From 3452129dabe4dad6e944dcf1fd1dc2c30b4344a8 Mon Sep 17 00:00:00 2001 From: jsnellings1 Date: Fri, 28 Feb 2020 17:25:20 -0500 Subject: [PATCH 17/27] herblore skill calc: add guthix rest --- .../client/plugins/skillcalculator/skill_herblore.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_herblore.json b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_herblore.json index e52d0fd6b6..93e0ed258c 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_herblore.json +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/skillcalculator/skill_herblore.json @@ -48,6 +48,12 @@ "name": "Serum 207 (3)", "xp": 50 }, + { + "level": 18, + "icon": 4419, + "name": "Guthix Rest (3)", + "xp": 59 + }, { "level": 19, "icon": 10142, From 78597125dae34bf3764aa160e6956631b375680f Mon Sep 17 00:00:00 2001 From: Alexsuperfly Date: Tue, 10 Dec 2019 11:46:26 -0500 Subject: [PATCH 18/27] chat commands: Refactor repeated test code into setup method This commit moves each test's client `getUsername()` mock returning "Adam" to a `before()` method. --- .../chatcommands/ChatCommandsPluginTest.java | 49 ++----------------- 1 file changed, 4 insertions(+), 45 deletions(-) diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java index ab7daaff99..a7ff4ea8e1 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java @@ -52,6 +52,8 @@ import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ChatCommandsPluginTest { + private static final String PLAYER_NAME = "Adam"; + @Mock @Bind Client client; @@ -79,13 +81,13 @@ public class ChatCommandsPluginTest public void before() { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + when(client.getUsername()).thenReturn(PLAYER_NAME); } @Test public void testCorporealBeastKill() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your Corporeal Beast kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); @@ -95,8 +97,6 @@ public class ChatCommandsPluginTest @Test public void testTheatreOfBlood() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your completed Theatre of Blood count is: 73.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); @@ -106,8 +106,6 @@ public class ChatCommandsPluginTest @Test public void testWintertodt() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your subdued Wintertodt count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); @@ -117,8 +115,6 @@ public class ChatCommandsPluginTest @Test public void testKreearra() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your Kree'arra kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); @@ -128,8 +124,6 @@ public class ChatCommandsPluginTest @Test public void testBarrows() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your Barrows chest count is: 277.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); @@ -139,8 +133,6 @@ public class ChatCommandsPluginTest @Test public void testHerbiboar() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(null, GAMEMESSAGE, "", "Your herbiboar harvest count is: 4091.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); @@ -150,8 +142,6 @@ public class ChatCommandsPluginTest @Test public void testGauntlet() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage gauntletMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Gauntlet completion count is: 123.", null, 0); chatCommandsPlugin.onChatMessage(gauntletMessage); @@ -161,8 +151,6 @@ public class ChatCommandsPluginTest @Test public void testCorruptedGauntlet() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage corruptedGauntletMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Corrupted Gauntlet completion count is: 4729.", null, 0); chatCommandsPlugin.onChatMessage(corruptedGauntletMessage); @@ -174,8 +162,6 @@ public class ChatCommandsPluginTest { final String FIGHT_DURATION = "Fight duration: 2:06. Personal best: 1:19."; - when(client.getUsername()).thenReturn("Adam"); - // This sets lastBoss ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Kree'arra kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -191,8 +177,6 @@ public class ChatCommandsPluginTest { final String FIGHT_DURATION = "Fight duration: 0:59. Personal best: 0:55"; - when(client.getUsername()).thenReturn("Adam"); - // This sets lastBoss ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Zulrah kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -208,8 +192,6 @@ public class ChatCommandsPluginTest { final String NEW_PB = "Fight duration: 3:01 (new personal best)."; - when(client.getUsername()).thenReturn("Adam"); - // This sets lastBoss ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Kree'arra kill count is: 4.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -223,8 +205,6 @@ public class ChatCommandsPluginTest @Test public void testDuelArenaWin() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(null, TRADE, "", "You won! You have now won 27 duels.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); @@ -235,8 +215,6 @@ public class ChatCommandsPluginTest @Test public void testDuelArenaWin2() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(null, TRADE, "", "You were defeated! You have won 22 duels.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); @@ -246,8 +224,6 @@ public class ChatCommandsPluginTest @Test public void testDuelArenaLose() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessageEvent = new ChatMessage(null, TRADE, "", "You have now lost 999 duels.", null, 0); chatCommandsPlugin.onChatMessage(chatMessageEvent); @@ -259,8 +235,6 @@ public class ChatCommandsPluginTest { final String NEW_PB = "Lap duration: 1:01 (new personal best)."; - when(client.getUsername()).thenReturn("Adam"); - // This sets lastBoss ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your Prifddinas Agility Course lap count is: 2.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -275,8 +249,6 @@ public class ChatCommandsPluginTest @Test public void testZukNewPb() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: 2.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -290,8 +262,6 @@ public class ChatCommandsPluginTest @Test public void testZukKill() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Your TzKal-Zuk kill count is: 3.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -305,8 +275,6 @@ public class ChatCommandsPluginTest @Test public void testGgNewPb() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: 1:36 (new personal best)", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -320,8 +288,6 @@ public class ChatCommandsPluginTest @Test public void testGgKill() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Fight duration: 2:41. Personal best: 2:14", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -335,8 +301,6 @@ public class ChatCommandsPluginTest @Test public void testGuantletPersonalBest() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: 10:24. Personal best: 7:59.", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -350,8 +314,6 @@ public class ChatCommandsPluginTest @Test public void testGuantletNewPersonalBest() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessage = new ChatMessage(null, GAMEMESSAGE, "", "Challenge duration: 10:24 (new personal best).", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -365,8 +327,6 @@ public class ChatCommandsPluginTest @Test public void testCoXKill() { - when(client.getUsername()).thenReturn("Adam"); - ChatMessage chatMessage = new ChatMessage(null, FRIENDSCHATNOTIFICATION, "", "Congratulations - your raid is complete! Duration: 37:04", null, 0); chatCommandsPlugin.onChatMessage(chatMessage); @@ -380,7 +340,6 @@ public class ChatCommandsPluginTest @Test public void testCoXKillNoPb() { - when(client.getUsername()).thenReturn("Adam"); when(configManager.getConfiguration(anyString(), anyString(), any())).thenReturn(2224); ChatMessage chatMessage = new ChatMessage(null, FRIENDSCHATNOTIFICATION, "", "Congratulations - your raid is complete! Duration: 1:45:04", null, 0); From 651277c4fa654434cb58c990dff25386379515d2 Mon Sep 17 00:00:00 2001 From: Alexsuperfly Date: Tue, 10 Dec 2019 11:21:02 -0500 Subject: [PATCH 19/27] chat commands: Add KC reading from POH adventurer's log --- .../net/runelite/api/widgets/WidgetID.java | 6 ++ .../net/runelite/api/widgets/WidgetInfo.java | 2 + .../chatcommands/ChatCommandsPlugin.java | 97 +++++++++++++------ 3 files changed, 76 insertions(+), 29 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index 8cda386cd5..b1eb61e5c2 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -150,6 +150,7 @@ public class WidgetID public static final int GWD_KC_GROUP_ID = 406; public static final int LMS_GROUP_ID = 333; public static final int LMS_INGAME_GROUP_ID = 328; + public static final int ADVENTURE_LOG_ID = 187; static class WorldMap { @@ -872,4 +873,9 @@ public class WidgetID { static final int INFO = 4; } + + static class AdventureLog + { + static final int CONTAINER = 0; + } } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index 2e7017e15e..ca21604055 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -454,6 +454,8 @@ public enum WidgetInfo KILL_LOG_KILLS(WidgetID.KILL_LOGS_GROUP_ID, WidgetID.KillLog.KILLS), KILL_LOG_STREAK(WidgetID.KILL_LOGS_GROUP_ID, WidgetID.KillLog.STREAK), + ADVENTURE_LOG(WidgetID.ADVENTURE_LOG_ID, WidgetID.AdventureLog.CONTAINER), + WORLD_SWITCHER_LIST(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.WORLD_LIST), FOSSIL_ISLAND_OXYGENBAR(WidgetID.FOSSIL_ISLAND_OXYGENBAR_ID, WidgetID.FossilOxygen.FOSSIL_ISLAND_OXYGEN_BAR), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 10f6da6f98..20d6073957 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -25,6 +25,7 @@ */ package net.runelite.client.plugins.chatcommands; +import com.google.common.annotations.VisibleForTesting; import com.google.inject.Provides; import java.io.IOException; import java.util.EnumSet; @@ -47,11 +48,13 @@ import net.runelite.api.VarPlayer; import net.runelite.api.Varbits; import net.runelite.api.WorldType; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameStateChanged; import net.runelite.api.events.GameTick; import net.runelite.api.events.VarbitChanged; import net.runelite.api.events.WidgetLoaded; import net.runelite.api.vars.AccountType; import net.runelite.api.widgets.Widget; +import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID; import static net.runelite.api.widgets.WidgetID.KILL_LOGS_GROUP_ID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.chat.ChatColorType; @@ -95,6 +98,7 @@ public class ChatCommandsPlugin extends Plugin private static final Pattern NEW_PB_PATTERN = Pattern.compile("(?i)^(?:Fight |Lap |Challenge |Corrupted challenge )?duration: ([0-9:]+) \\(new personal best\\)"); private static final Pattern DUEL_ARENA_WINS_PATTERN = Pattern.compile("You (were defeated|won)! You have(?: now)? won (\\d+) duels?"); private static final Pattern DUEL_ARENA_LOSSES_PATTERN = Pattern.compile("You have(?: now)? lost (\\d+) duels?"); + private static final Pattern ADVENTURE_LOG_TITLE_PATTERN = Pattern.compile("The Exploits of (.+)"); private static final String TOTAL_LEVEL_COMMAND_STRING = "!total"; private static final String PRICE_COMMAND_STRING = "!price"; @@ -110,10 +114,15 @@ public class ChatCommandsPlugin extends Plugin private static final String GC_COMMAND_STRING = "!gc"; private static final String DUEL_ARENA_COMMAND = "!duels"; + @VisibleForTesting + static final int ADV_LOG_EXPLOITS_TEXT_INDEX = 1; + private final HiscoreClient hiscoreClient = new HiscoreClient(); private final ChatClient chatClient = new ChatClient(); - private boolean logKills; + private boolean bossLogLoaded; + private boolean advLogLoaded; + private String pohOwner; private HiscoreEndpoint hiscoreEndpoint; // hiscore endpoint for current player private String lastBossKill; private int lastPb = -1; @@ -380,36 +389,51 @@ public class ChatCommandsPlugin extends Plugin @Subscribe public void onGameTick(GameTick event) { - if (!logKills) + if (client.getLocalPlayer() == null) { return; } - logKills = false; - - Widget title = client.getWidget(WidgetInfo.KILL_LOG_TITLE); - Widget bossMonster = client.getWidget(WidgetInfo.KILL_LOG_MONSTER); - Widget bossKills = client.getWidget(WidgetInfo.KILL_LOG_KILLS); - - if (title == null || bossMonster == null || bossKills == null - || !"Boss Kill Log".equals(title.getText())) + if (advLogLoaded) { - return; - } + advLogLoaded = false; - Widget[] bossChildren = bossMonster.getChildren(); - Widget[] killsChildren = bossKills.getChildren(); - - for (int i = 0; i < bossChildren.length; ++i) - { - Widget boss = bossChildren[i]; - Widget kill = killsChildren[i]; - - String bossName = boss.getText().replace(":", ""); - int kc = Integer.parseInt(kill.getText().replace(",", "")); - if (kc != getKc(bossName)) + Widget adventureLog = client.getWidget(WidgetInfo.ADVENTURE_LOG); + Matcher advLogExploitsText = ADVENTURE_LOG_TITLE_PATTERN.matcher(adventureLog.getChild(ADV_LOG_EXPLOITS_TEXT_INDEX).getText()); + if (advLogExploitsText.find()) { - setKc(bossName, kc); + pohOwner = advLogExploitsText.group(1); + } + } + + if (bossLogLoaded && (pohOwner == null || pohOwner.equals(client.getLocalPlayer().getName()))) + { + bossLogLoaded = false; + + Widget title = client.getWidget(WidgetInfo.KILL_LOG_TITLE); + Widget bossMonster = client.getWidget(WidgetInfo.KILL_LOG_MONSTER); + Widget bossKills = client.getWidget(WidgetInfo.KILL_LOG_KILLS); + + if (title == null || bossMonster == null || bossKills == null + || !"Boss Kill Log".equals(title.getText())) + { + return; + } + + Widget[] bossChildren = bossMonster.getChildren(); + Widget[] killsChildren = bossKills.getChildren(); + + for (int i = 0; i < bossChildren.length; ++i) + { + Widget boss = bossChildren[i]; + Widget kill = killsChildren[i]; + + String bossName = boss.getText().replace(":", ""); + int kc = Integer.parseInt(kill.getText().replace(",", "")); + if (kc != getKc(longBossName(bossName))) + { + setKc(longBossName(bossName), kc); + } } } } @@ -417,14 +441,26 @@ public class ChatCommandsPlugin extends Plugin @Subscribe public void onWidgetLoaded(WidgetLoaded widget) { - // don't load kc if in an instance, if the player is in another players poh - // and reading their boss log - if (widget.getGroupId() != KILL_LOGS_GROUP_ID || client.isInInstancedRegion()) + switch (widget.getGroupId()) { - return; + case ADVENTURE_LOG_ID: + advLogLoaded = true; + break; + case KILL_LOGS_GROUP_ID: + bossLogLoaded = true; + break; } + } - logKills = true; + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + switch (event.getGameState()) + { + case LOADING: + case HOPPING: + pohOwner = null; + } } @Subscribe @@ -1516,6 +1552,9 @@ public class ChatCommandsPlugin extends Plugin case "cgauntlet": return "Corrupted Gauntlet"; + case "the nightmare": + return "Nightmare"; + default: return WordUtils.capitalize(boss); } From c7d89860ab34f2b1157543af12b25ad51239ac87 Mon Sep 17 00:00:00 2001 From: Alexsuperfly Date: Tue, 10 Dec 2019 11:43:43 -0500 Subject: [PATCH 20/27] chat commands: Add PB reading from POH adventurer's log --- .../net/runelite/api/widgets/WidgetID.java | 7 + .../net/runelite/api/widgets/WidgetInfo.java | 2 + .../chatcommands/ChatCommandsPlugin.java | 39 ++++- .../chatcommands/ChatCommandsPluginTest.java | 139 ++++++++++++++++++ 4 files changed, 179 insertions(+), 8 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java index b1eb61e5c2..cdc14ad925 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetID.java @@ -151,6 +151,7 @@ public class WidgetID public static final int LMS_GROUP_ID = 333; public static final int LMS_INGAME_GROUP_ID = 328; public static final int ADVENTURE_LOG_ID = 187; + public static final int COUNTERS_LOG_GROUP_ID = 625; static class WorldMap { @@ -878,4 +879,10 @@ public class WidgetID { static final int CONTAINER = 0; } + + static class CountersLog + { + static final int OWNER = 4; + static final int TEXT = 6; + } } diff --git a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java index ca21604055..5d54ded21d 100644 --- a/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java +++ b/runelite-api/src/main/java/net/runelite/api/widgets/WidgetInfo.java @@ -456,6 +456,8 @@ public enum WidgetInfo ADVENTURE_LOG(WidgetID.ADVENTURE_LOG_ID, WidgetID.AdventureLog.CONTAINER), + COUNTERS_LOG_TEXT(WidgetID.COUNTERS_LOG_GROUP_ID, WidgetID.CountersLog.TEXT), + WORLD_SWITCHER_LIST(WidgetID.WORLD_SWITCHER_GROUP_ID, WidgetID.WorldSwitcher.WORLD_LIST), FOSSIL_ISLAND_OXYGENBAR(WidgetID.FOSSIL_ISLAND_OXYGENBAR_ID, WidgetID.FossilOxygen.FOSSIL_ISLAND_OXYGEN_BAR), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java index 20d6073957..ae704913b7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatcommands/ChatCommandsPlugin.java @@ -56,6 +56,7 @@ import net.runelite.api.vars.AccountType; import net.runelite.api.widgets.Widget; import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID; import static net.runelite.api.widgets.WidgetID.KILL_LOGS_GROUP_ID; +import static net.runelite.api.widgets.WidgetID.COUNTERS_LOG_GROUP_ID; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.chat.ChatColorType; import net.runelite.client.chat.ChatCommandManager; @@ -69,7 +70,7 @@ import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.util.QuantityFormatter; -import static net.runelite.client.util.Text.sanitize; +import net.runelite.client.util.Text; import net.runelite.http.api.chat.ChatClient; import net.runelite.http.api.chat.Duels; import net.runelite.http.api.hiscore.HiscoreClient; @@ -99,6 +100,7 @@ public class ChatCommandsPlugin extends Plugin private static final Pattern DUEL_ARENA_WINS_PATTERN = Pattern.compile("You (were defeated|won)! You have(?: now)? won (\\d+) duels?"); private static final Pattern DUEL_ARENA_LOSSES_PATTERN = Pattern.compile("You have(?: now)? lost (\\d+) duels?"); private static final Pattern ADVENTURE_LOG_TITLE_PATTERN = Pattern.compile("The Exploits of (.+)"); + private static final Pattern ADVENTURE_LOG_PB_PATTERN = Pattern.compile("([a-zA-Z]+(?: [a-zA-Z]+)*) Fastest (?:kill|run): ([0-9:]+)"); private static final String TOTAL_LEVEL_COMMAND_STRING = "!total"; private static final String PRICE_COMMAND_STRING = "!price"; @@ -122,6 +124,7 @@ public class ChatCommandsPlugin extends Plugin private boolean bossLogLoaded; private boolean advLogLoaded; + private boolean countersLogLoaded; private String pohOwner; private HiscoreEndpoint hiscoreEndpoint; // hiscore endpoint for current player private String lastBossKill; @@ -436,6 +439,20 @@ public class ChatCommandsPlugin extends Plugin } } } + + if (countersLogLoaded && pohOwner.equals(client.getLocalPlayer().getName())) + { + countersLogLoaded = false; + + String counterText = Text.sanitizeMultilineText(client.getWidget(WidgetInfo.COUNTERS_LOG_TEXT).getText()); + Matcher mCounterText = ADVENTURE_LOG_PB_PATTERN.matcher(counterText); + while (mCounterText.find()) + { + String bossName = mCounterText.group(1); + String pbTime = mCounterText.group(2); + setPb(longBossName(bossName), timeStringToSeconds(pbTime)); + } + } } @Subscribe @@ -449,6 +466,9 @@ public class ChatCommandsPlugin extends Plugin case KILL_LOGS_GROUP_ID: bossLogLoaded = true; break; + case COUNTERS_LOG_GROUP_ID: + countersLogLoaded = true; + break; } } @@ -523,7 +543,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(chatMessage.getName()); + player = Text.sanitize(chatMessage.getName()); } search = longBossName(search); @@ -604,7 +624,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(chatMessage.getName()); + player = Text.sanitize(chatMessage.getName()); } Duels duels; @@ -661,7 +681,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(chatMessage.getName()); + player = Text.sanitize(chatMessage.getName()); } int qp; @@ -735,7 +755,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(chatMessage.getName()); + player = Text.sanitize(chatMessage.getName()); } search = longBossName(search); @@ -818,7 +838,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(chatMessage.getName()); + player = Text.sanitize(chatMessage.getName()); } int gc; @@ -1028,7 +1048,7 @@ public class ChatCommandsPlugin extends Plugin } else { - player = sanitize(chatMessage.getName()); + player = Text.sanitize(chatMessage.getName()); } try @@ -1296,7 +1316,7 @@ public class ChatCommandsPlugin extends Plugin private HiscoreLookup getCorrectLookupFor(final ChatMessage chatMessage) { Player localPlayer = client.getLocalPlayer(); - final String player = sanitize(chatMessage.getName()); + final String player = Text.sanitize(chatMessage.getName()); // If we are sending the message then just use the local hiscore endpoint for the world if (chatMessage.getType().equals(ChatMessageType.PRIVATECHATOUT) @@ -1426,6 +1446,7 @@ public class ChatCommandsPlugin extends Plugin return "Corporeal Beast"; case "jad": + case "tzhaar fight cave": return "TzTok-Jad"; case "kq": @@ -1545,11 +1566,13 @@ public class ChatCommandsPlugin extends Plugin // The Gauntlet case "gaunt": case "gauntlet": + case "the gauntlet": return "Gauntlet"; // Corrupted Gauntlet case "cgaunt": case "cgauntlet": + case "the corrupted gauntlet": return "Corrupted Gauntlet"; case "the nightmare": diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java index a7ff4ea8e1..27de559692 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatcommands/ChatCommandsPluginTest.java @@ -33,9 +33,16 @@ import static net.runelite.api.ChatMessageType.FRIENDSCHATNOTIFICATION; import static net.runelite.api.ChatMessageType.GAMEMESSAGE; import static net.runelite.api.ChatMessageType.TRADE; import net.runelite.api.Client; +import net.runelite.api.Player; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.GameTick; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.config.ChatColorConfig; import net.runelite.client.config.ConfigManager; +import static net.runelite.api.widgets.WidgetID.ADVENTURE_LOG_ID; +import static net.runelite.api.widgets.WidgetID.COUNTERS_LOG_GROUP_ID; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,7 +52,9 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -351,4 +360,134 @@ public class ChatCommandsPluginTest verify(configManager).setConfiguration(eq("killcount.adam"), eq("chambers of xeric"), eq(52)); verify(configManager, never()).setConfiguration(eq("personalbest.adam"), eq("chambers of xeric"), anyInt()); } + + @Test + public void testAdventureLogCountersPage() + { + Player player = mock(Player.class); + when(player.getName()).thenReturn(PLAYER_NAME); + when(client.getLocalPlayer()).thenReturn(player); + + Widget advLogWidget = mock(Widget.class); + Widget advLogExploitsTextWidget = mock(Widget.class); + when(advLogWidget.getChild(ChatCommandsPlugin.ADV_LOG_EXPLOITS_TEXT_INDEX)).thenReturn(advLogExploitsTextWidget); + when(advLogExploitsTextWidget.getText()).thenReturn("The Exploits of " + PLAYER_NAME); + when(client.getWidget(WidgetInfo.ADVENTURE_LOG)).thenReturn(advLogWidget); + + WidgetLoaded advLogEvent = new WidgetLoaded(); + advLogEvent.setGroupId(ADVENTURE_LOG_ID); + chatCommandsPlugin.onWidgetLoaded(advLogEvent); + chatCommandsPlugin.onGameTick(new GameTick()); + + String COUNTER_TEXT = "Duel Arena
Wins: 4
Losses: 2" + + "

Last Man Standing
Rank: 0" + + "

Treasure Trails
Beginner: 0
Easy: 7" + + "
Medium: 28
Hard: 108
Elite: 15" + + "
Master: 27
Rank: Novice" + + "

Chompy Hunting
Kills: 1,000
Rank: Ogre Expert" + + "

Order of the White Knights
Rank: Master
with a kill score of 1,300" + + "

TzHaar Fight Cave
Fastest run: 38:10" + + "

Inferno
Fastest run: -

Zulrah
" + + "Fastest kill: 5:48

Vorkath
Fastest kill: 1:21" + + "

Galvek
Fastest kill: -

Grotesque Guardians
" + + "Fastest kill: 2:49

Alchemical Hydra
Fastest kill: -" + + "

Hespori
Fastest kill: 0:57

Nightmare
" + + "Fastest kill: 3:30

The Gauntlet
Fastest run: -" + + "

The Corrupted Gauntlet
Fastest run: -

Fragment of Seren
" + + "Fastest kill: -

Barbarian Assault
High-level gambles: " + + "15

Fremennik spirits rested: 0"; + + Widget countersPage = mock(Widget.class); + when(countersPage.getText()).thenReturn(COUNTER_TEXT); + when(client.getWidget(WidgetInfo.COUNTERS_LOG_TEXT)).thenReturn(countersPage); + + WidgetLoaded countersLogEvent = new WidgetLoaded(); + countersLogEvent.setGroupId(COUNTERS_LOG_GROUP_ID); + chatCommandsPlugin.onWidgetLoaded(countersLogEvent); + chatCommandsPlugin.onGameTick(new GameTick()); + + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("tztok-jad"), eq(38 * 60 + 10)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("zulrah"), eq(5 * 60 + 48)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("vorkath"), eq(1 * 60 + 21)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("grotesque guardians"), eq(2 * 60 + 49)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("hespori"), eq(57)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("nightmare"), eq( 3 * 60 + 30)); + } + + @Test + public void testAdventurerLogCountersPage2() + { + Player player = mock(Player.class); + when(player.getName()).thenReturn(PLAYER_NAME); + when(client.getLocalPlayer()).thenReturn(player); + + Widget advLogWidget = mock(Widget.class); + Widget advLogExploitsTextWidget = mock(Widget.class); + when(advLogWidget.getChild(ChatCommandsPlugin.ADV_LOG_EXPLOITS_TEXT_INDEX)).thenReturn(advLogExploitsTextWidget); + when(advLogExploitsTextWidget.getText()).thenReturn("The Exploits of " + PLAYER_NAME); + when(client.getWidget(WidgetInfo.ADVENTURE_LOG)).thenReturn(advLogWidget); + + WidgetLoaded advLogEvent = new WidgetLoaded(); + advLogEvent.setGroupId(ADVENTURE_LOG_ID); + chatCommandsPlugin.onWidgetLoaded(advLogEvent); + chatCommandsPlugin.onGameTick(new GameTick()); + + String COUNTER_TEXT = "Duel Arena
Wins: 12
Losses: 20" + + "

Last Man Standing
Rank: 0" + + "

Treasure Trails
Beginner: 1
Easy: 4" + + "
Medium: 35
Hard: 66
Elite: 2" + + "
Master: 0
Rank: Novice" + + "

Chompy Hunting
Kills: 300
Rank: Ogre Forester" + + "

Order of the White Knights
Rank: Unrated
with a kill score of 99" + + "

TzHaar Fight Cave
Fastest run: 65:12" + + "

Inferno
Fastest run: -

Zulrah
" + + "Fastest kill: 2:55

Vorkath
Fastest kill: 1:37" + + "

Galvek
Fastest kill: -

Grotesque Guardians
" + + "Fastest kill: -

Alchemical Hydra
Fastest kill: -" + + "

Hespori
Fastest kill: 1:42

Nightmare
" + + "Fastest kill: -

The Gauntlet
Fastest run: -" + + "

The Corrupted Gauntlet
Fastest run: -

Fragment of Seren
" + + "Fastest kill: -

Barbarian Assault
High-level gambles: " + + "0

Fremennik spirits rested: 0"; + + Widget countersPage = mock(Widget.class); + when(countersPage.getText()).thenReturn(COUNTER_TEXT); + when(client.getWidget(WidgetInfo.COUNTERS_LOG_TEXT)).thenReturn(countersPage); + + WidgetLoaded countersLogEvent = new WidgetLoaded(); + countersLogEvent.setGroupId(COUNTERS_LOG_GROUP_ID); + chatCommandsPlugin.onWidgetLoaded(countersLogEvent); + chatCommandsPlugin.onGameTick(new GameTick()); + + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("tztok-jad"), eq(65 * 60 + 12)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("zulrah"), eq(2 * 60 + 55)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("vorkath"), eq(1 * 60 + 37)); + verify(configManager).setConfiguration(eq("personalbest.adam"), eq("hespori"), eq(1 * 60 + 42)); + } + + @Test + public void testNotYourAdventureLogCountersPage() + { + Player player = mock(Player.class); + when(player.getName()).thenReturn(PLAYER_NAME); + when(client.getLocalPlayer()).thenReturn(player); + + Widget advLogWidget = mock(Widget.class); + Widget advLogExploitsTextWidget = mock(Widget.class); + when(advLogWidget.getChild(ChatCommandsPlugin.ADV_LOG_EXPLOITS_TEXT_INDEX)).thenReturn(advLogExploitsTextWidget); + when(advLogExploitsTextWidget.getText()).thenReturn("The Exploits of " + "not the player"); + when(client.getWidget(WidgetInfo.ADVENTURE_LOG)).thenReturn(advLogWidget); + + WidgetLoaded advLogEvent = new WidgetLoaded(); + advLogEvent.setGroupId(ADVENTURE_LOG_ID); + chatCommandsPlugin.onWidgetLoaded(advLogEvent); + chatCommandsPlugin.onGameTick(new GameTick()); + + WidgetLoaded countersLogEvent = new WidgetLoaded(); + countersLogEvent.setGroupId(COUNTERS_LOG_GROUP_ID); + chatCommandsPlugin.onWidgetLoaded(countersLogEvent); + chatCommandsPlugin.onGameTick(new GameTick()); + + verifyNoMoreInteractions(configManager); + } } From ef6e53ccae42ea362d34b75301b10b70df0a1b5e Mon Sep 17 00:00:00 2001 From: loldudester Date: Tue, 21 Jan 2020 19:48:39 +0000 Subject: [PATCH 21/27] wintertodt plugin: separate notifications into separate options --- .../plugins/wintertodt/WintertodtConfig.java | 82 ++++++++++++++++--- .../plugins/wintertodt/WintertodtPlugin.java | 39 +++++---- ...yMode.java => WintertodtNotifyDamage.java} | 14 ++-- 3 files changed, 98 insertions(+), 37 deletions(-) rename runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/config/{WintertodtNotifyMode.java => WintertodtNotifyDamage.java} (86%) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtConfig.java index 65a26893bc..907d1c6d95 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtConfig.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, terminatusx * Copyright (c) 2018, Adam + * Copyright (c) 2020, loldudester * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,24 +32,13 @@ import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; import net.runelite.client.config.Range; import net.runelite.client.config.Units; -import net.runelite.client.plugins.wintertodt.config.WintertodtNotifyMode; +import net.runelite.client.plugins.wintertodt.config.WintertodtNotifyDamage; @ConfigGroup("wintertodt") public interface WintertodtConfig extends Config { @ConfigItem( position = 1, - keyName = "notifyCondition", - name = "Notify When", - description = "Configures when to send notifications" - ) - default WintertodtNotifyMode notifyCondition() - { - return WintertodtNotifyMode.ONLY_WHEN_INTERRUPTED; - } - - @ConfigItem( - position = 2, keyName = "damageNotificationColor", name = "Damage Notification Color", description = "Color of damage notification text in chat" @@ -59,7 +49,7 @@ public interface WintertodtConfig extends Config } @ConfigItem( - position = 3, + position = 2, keyName = "roundNotification", name = "Wintertodt round notification", description = "Notifies you before the round starts (in seconds)" @@ -72,4 +62,70 @@ public interface WintertodtConfig extends Config { return 5; } + + @ConfigItem( + position = 3, + keyName = "notifyCold", + name = "Ambient Damage Notification", + description = "Notifies when hit by the Wintertodt's ambient cold damage" + ) + default WintertodtNotifyDamage notifyCold() + { + return WintertodtNotifyDamage.INTERRUPT; + } + + @ConfigItem( + position = 4, + keyName = "notifySnowfall", + name = "Snowfall Damage Notification", + description = "Notifies when hit by the Wintertodt's snowfall attack" + ) + default WintertodtNotifyDamage notifySnowfall() + { + return WintertodtNotifyDamage.INTERRUPT; + } + + @ConfigItem( + position = 5, + keyName = "notifyBrazierDamage", + name = "Brazier Damage Notification", + description = "Notifies when hit by the brazier breaking" + ) + default WintertodtNotifyDamage notifyBrazierDamage() + { + return WintertodtNotifyDamage.INTERRUPT; + } + + @ConfigItem( + position = 6, + keyName = "notifyFullInv", + name = "Full Inventory Notification", + description = "Notifies when your inventory fills up with bruma roots" + ) + default boolean notifyFullInv() + { + return true; + } + + @ConfigItem( + position = 7, + keyName = "notifyEmptyInv", + name = "Empty Inventory Notification", + description = "Notifies when you run out of bruma roots" + ) + default boolean notifyEmptyInv() + { + return true; + } + + @ConfigItem( + position = 8, + keyName = "notifyBrazierOut", + name = "Brazier Extinguish Notification", + description = "Notifies when the brazier goes out" + ) + default boolean notifyBrazierOut() + { + return true; + } } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java index b89ef609aa..40dfeff441 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java @@ -1,6 +1,7 @@ /* * Copyright (c) 2018, terminatusx * Copyright (c) 2018, Adam + * Copyright (c) 2020, loldudester * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -69,6 +70,9 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.wintertodt.config.WintertodtNotifyDamage; +import static net.runelite.client.plugins.wintertodt.config.WintertodtNotifyDamage.ALWAYS; +import static net.runelite.client.plugins.wintertodt.config.WintertodtNotifyDamage.INTERRUPT; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.ColorUtil; @@ -290,7 +294,6 @@ public class WintertodtPlugin extends Plugin } boolean wasInterrupted = false; - boolean wasDamaged = false; boolean neverNotify = false; switch (interruptType) @@ -298,7 +301,6 @@ public class WintertodtPlugin extends Plugin case COLD: case BRAZIER: case SNOWFALL: - wasDamaged = true; // Recolor message for damage notification messageNode.setRuneLiteFormatMessage(ColorUtil.wrapWithColorTag(messageNode.getValue(), config.damageNotificationColor())); @@ -327,23 +329,28 @@ public class WintertodtPlugin extends Plugin if (!neverNotify) { boolean shouldNotify = false; - - switch (config.notifyCondition()) + switch (interruptType) { - case ONLY_WHEN_INTERRUPTED: - if (wasInterrupted) - { - shouldNotify = true; - } + case COLD: + WintertodtNotifyDamage notify = config.notifyCold(); + shouldNotify = notify == ALWAYS || (notify == INTERRUPT && wasInterrupted); break; - case WHEN_DAMAGED: - if (wasDamaged) - { - shouldNotify = true; - } + case SNOWFALL: + notify = config.notifySnowfall(); + shouldNotify = notify == ALWAYS || (notify == INTERRUPT && wasInterrupted); break; - case EITHER: - shouldNotify = true; + case BRAZIER: + notify = config.notifyBrazierDamage(); + shouldNotify = notify == ALWAYS || (notify == INTERRUPT && wasInterrupted); + break; + case INVENTORY_FULL: + shouldNotify = config.notifyFullInv(); + break; + case OUT_OF_ROOTS: + shouldNotify = config.notifyEmptyInv(); + break; + case BRAZIER_WENT_OUT: + shouldNotify = config.notifyBrazierOut(); break; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/config/WintertodtNotifyMode.java b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/config/WintertodtNotifyDamage.java similarity index 86% rename from runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/config/WintertodtNotifyMode.java rename to runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/config/WintertodtNotifyDamage.java index c5a3b114fd..dd52cee647 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/config/WintertodtNotifyMode.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/config/WintertodtNotifyDamage.java @@ -1,6 +1,5 @@ /* - * Copyright (c) 2018, terminatusx - * Copyright (c) 2018, Adam + * Copyright (c) 2020, loldudester * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,12 +29,11 @@ import lombok.RequiredArgsConstructor; @Getter @RequiredArgsConstructor -public enum WintertodtNotifyMode +public enum WintertodtNotifyDamage { - NONE("None"), - WHEN_DAMAGED("Damage Taken"), - ONLY_WHEN_INTERRUPTED("Action Interrupted"), - EITHER("Either"); + OFF("Off"), + INTERRUPT("On Interrupt"), + ALWAYS("Always"); private final String name; @@ -44,4 +42,4 @@ public enum WintertodtNotifyMode { return name; } -} +} \ No newline at end of file From 38ed9eb5ca99857048965b673525f56ebbe162d7 Mon Sep 17 00:00:00 2001 From: gregg1494 Date: Sat, 22 Feb 2020 22:18:18 -0800 Subject: [PATCH 22/27] screenshot plugin: Capture screenshots to subdirectories Closes #8711 Co-authored-by: Jordan Atwood --- .../plugins/screenshot/ScreenshotPlugin.java | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java index e5bdce4414..7c3a38a254 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/screenshot/ScreenshotPlugin.java @@ -160,7 +160,7 @@ public class ScreenshotPlugin extends Plugin @Override public void hotkeyPressed() { - takeScreenshot(""); + manualScreenshot(); } }; @@ -183,7 +183,7 @@ public class ScreenshotPlugin extends Plugin .tab(false) .tooltip("Take screenshot") .icon(iconImage) - .onClick(() -> takeScreenshot("")) + .onClick(this::manualScreenshot) .popup(ImmutableMap .builder() .put("Open screenshot folder...", () -> @@ -222,26 +222,30 @@ public class ScreenshotPlugin extends Plugin } shouldTakeScreenshot = false; + String screenshotSubDir = null; String fileName = null; if (client.getWidget(WidgetInfo.LEVEL_UP_LEVEL) != null) { fileName = parseLevelUpWidget(WidgetInfo.LEVEL_UP_LEVEL); + screenshotSubDir = "Levels"; } else if (client.getWidget(WidgetInfo.DIALOG_SPRITE_TEXT) != null) { fileName = parseLevelUpWidget(WidgetInfo.DIALOG_SPRITE_TEXT); + screenshotSubDir = "Levels"; } else if (client.getWidget(WidgetInfo.QUEST_COMPLETED_NAME_TEXT) != null) { // "You have completed The Corsair Curse!" String text = client.getWidget(WidgetInfo.QUEST_COMPLETED_NAME_TEXT).getText(); fileName = "Quest(" + text.substring(19, text.length() - 1) + ")"; + screenshotSubDir = "Quests"; } if (fileName != null) { - takeScreenshot(fileName); + takeScreenshot(fileName, screenshotSubDir); } } @@ -251,11 +255,11 @@ public class ScreenshotPlugin extends Plugin Player player = playerDeath.getPlayer(); if (player == client.getLocalPlayer() && config.screenshotPlayerDeath()) { - takeScreenshot("Death"); + takeScreenshot("Death", "Deaths"); } else if ((player.isClanMember() || player.isFriend()) && config.screenshotFriendDeath() && player.getCanvasTilePoly() != null) { - takeScreenshot("Death " + player.getName()); + takeScreenshot("Death " + player.getName(), "Deaths"); } } @@ -267,7 +271,7 @@ public class ScreenshotPlugin extends Plugin final Player player = playerLootReceived.getPlayer(); final String name = player.getName(); String fileName = "Kill " + name; - takeScreenshot(fileName); + takeScreenshot(fileName, "PvP Kills"); } } @@ -335,7 +339,7 @@ public class ScreenshotPlugin extends Plugin if (config.screenshotPet() && PET_MESSAGES.stream().anyMatch(chatMessage::contains)) { String fileName = "Pet"; - takeScreenshot(fileName); + takeScreenshot(fileName, "Pets"); } if (config.screenshotBossKills() ) @@ -346,7 +350,7 @@ public class ScreenshotPlugin extends Plugin String bossName = m.group(1); String bossKillcount = m.group(2); String fileName = bossName + "(" + bossKillcount + ")"; - takeScreenshot(fileName); + takeScreenshot(fileName, "Boss Kills"); } } @@ -357,7 +361,7 @@ public class ScreenshotPlugin extends Plugin { String valuableDropName = m.group(1); String fileName = "Valuable drop " + valuableDropName; - takeScreenshot(fileName); + takeScreenshot(fileName, "Valuable Drops"); } } @@ -368,7 +372,7 @@ public class ScreenshotPlugin extends Plugin { String untradeableDropName = m.group(1); String fileName = "Untradeable drop " + untradeableDropName; - takeScreenshot(fileName); + takeScreenshot(fileName, "Untradeable Drops"); } } @@ -380,7 +384,7 @@ public class ScreenshotPlugin extends Plugin String result = m.group(1); String count = m.group(2); String fileName = "Duel " + result + " (" + count + ")"; - takeScreenshot(fileName); + takeScreenshot(fileName, "Duels"); } } } @@ -389,6 +393,7 @@ public class ScreenshotPlugin extends Plugin public void onWidgetLoaded(WidgetLoaded event) { String fileName; + String screenshotSubDir; int groupId = event.getGroupId(); switch (groupId) @@ -423,6 +428,7 @@ public class ScreenshotPlugin extends Plugin case KINGDOM_GROUP_ID: { fileName = "Kingdom " + LocalDate.now(); + screenshotSubDir = "Kingdom Rewards"; break; } case CHAMBERS_OF_XERIC_REWARD_GROUP_ID: @@ -430,12 +436,14 @@ public class ScreenshotPlugin extends Plugin if (chambersOfXericNumber != null) { fileName = "Chambers of Xeric(" + chambersOfXericNumber + ")"; + screenshotSubDir = "Boss Kills"; chambersOfXericNumber = null; break; } else if (chambersOfXericChallengeNumber != null) { fileName = "Chambers of Xeric Challenge Mode(" + chambersOfXericChallengeNumber + ")"; + screenshotSubDir = "Boss Kills"; chambersOfXericChallengeNumber = null; break; } @@ -452,6 +460,7 @@ public class ScreenshotPlugin extends Plugin } fileName = "Theatre of Blood(" + theatreOfBloodNumber + ")"; + screenshotSubDir = "Boss Kills"; theatreOfBloodNumber = null; break; } @@ -463,6 +472,7 @@ public class ScreenshotPlugin extends Plugin } fileName = "Barrows(" + barrowsNumber + ")"; + screenshotSubDir = "Boss Kills"; barrowsNumber = null; break; } @@ -482,6 +492,7 @@ public class ScreenshotPlugin extends Plugin } fileName = Character.toUpperCase(clueType.charAt(0)) + clueType.substring(1) + "(" + clueNumber + ")"; + screenshotSubDir = "Clue Scroll Rewards"; clueType = null; clueNumber = null; break; @@ -490,7 +501,12 @@ public class ScreenshotPlugin extends Plugin return; } - takeScreenshot(fileName); + takeScreenshot(fileName, screenshotSubDir); + } + + private void manualScreenshot() + { + takeScreenshot("", null); } /** @@ -525,8 +541,9 @@ public class ScreenshotPlugin extends Plugin * and optionally uploads it to an image-hosting service. * * @param fileName Filename to use, without file extension. + * @param subDir Subdirectory to store the captured screenshot in. */ - private void takeScreenshot(String fileName) + private void takeScreenshot(String fileName, String subDir) { if (client.getGameState() == GameState.LOGIN_SCREEN) { @@ -538,7 +555,7 @@ public class ScreenshotPlugin extends Plugin Consumer imageCallback = (img) -> { // This callback is on the game thread, move to executor thread - executor.submit(() -> takeScreenshot(fileName, img)); + executor.submit(() -> takeScreenshot(fileName, subDir, img)); }; if (config.displayDate()) @@ -551,7 +568,7 @@ public class ScreenshotPlugin extends Plugin } } - private void takeScreenshot(String fileName, Image image) + private void takeScreenshot(String fileName, String subDir, Image image) { BufferedImage screenshot = config.includeFrame() ? new BufferedImage(clientUi.getWidth(), clientUi.getHeight(), BufferedImage.TYPE_INT_ARGB) @@ -582,7 +599,7 @@ public class ScreenshotPlugin extends Plugin // Draw the game onto the screenshot graphics.drawImage(image, gameOffsetX, gameOffsetY, null); - imageCapture.takeScreenshot(screenshot, fileName, config.notifyWhenTaken(), config.uploadScreenshot()); + imageCapture.takeScreenshot(screenshot, fileName, subDir, config.notifyWhenTaken(), config.uploadScreenshot()); } @VisibleForTesting From 5935365c5971edcf97ca3ccb871358d6e205de15 Mon Sep 17 00:00:00 2001 From: Hydrox6 Date: Tue, 18 Feb 2020 22:43:00 +0000 Subject: [PATCH 23/27] config: fix entering values directly into options with units not working --- .../client/plugins/config/ConfigPanel.java | 7 +- .../client/plugins/config/UnitFormatter.java | 86 +++++++++++++++++++ 2 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/config/UnitFormatter.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 6e6b49a774..20c04f79fd 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -36,7 +36,6 @@ import java.awt.event.ItemEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; -import java.text.DecimalFormat; import javax.inject.Inject; import javax.swing.BorderFactory; import javax.swing.ImageIcon; @@ -262,11 +261,7 @@ class ConfigPanel extends PluginPanel Units units = cid.getUnits(); if (units != null) { - DecimalFormat df = ((JSpinner.NumberEditor) spinner.getEditor()).getFormat(); - df.setPositiveSuffix(units.value()); - df.setNegativeSuffix(units.value()); - // Force update the spinner to have it add the units initially - spinnerTextField.setValue(value); + spinnerTextField.setFormatterFactory(new UnitFormatterFactory(units)); } item.add(spinner, BorderLayout.EAST); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/UnitFormatter.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/UnitFormatter.java new file mode 100644 index 0000000000..4945a4a65e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/UnitFormatter.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020, Hydrox6 + * 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.config; + +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; +import javax.swing.JFormattedTextField; +import lombok.RequiredArgsConstructor; +import net.runelite.client.config.Units; + +final class UnitFormatter extends JFormattedTextField.AbstractFormatter +{ + private final String units; + + UnitFormatter(Units units) + { + this.units = units.value(); + } + + @Override + public Object stringToValue(final String text) throws ParseException + { + final String trimmedText; + + // Using the spinner controls causes the value to have the unit on the end, so remove it + if (text.endsWith(units)) + { + trimmedText = text.substring(0, text.length() - units.length()); + } + else + { + trimmedText = text; + } + + try + { + return Integer.valueOf(trimmedText); + } + catch (NumberFormatException e) + { + throw new ParseException(trimmedText + " is not an integer.", 0); + } + } + + @Override + public String valueToString(final Object value) + { + return value + units; + } +} + +@RequiredArgsConstructor +final class UnitFormatterFactory extends JFormattedTextField.AbstractFormatterFactory +{ + private final Units units; + private final Map formatters = new HashMap<>(); + + @Override + public JFormattedTextField.AbstractFormatter getFormatter(final JFormattedTextField tf) + { + return formatters.computeIfAbsent(tf, (key) -> new UnitFormatter(units)); + } +} \ No newline at end of file From f6eeaf33c8371c7ce073857a1a7dcee4c23e1500 Mon Sep 17 00:00:00 2001 From: Zachary Waller Date: Sun, 1 Mar 2020 10:43:14 -0800 Subject: [PATCH 24/27] ground items: change highlight value to take priority over other value thresholds --- .../client/plugins/grounditems/GroundItemsPlugin.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java index 17f73286dc..cf278ac654 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/grounditems/GroundItemsPlugin.java @@ -431,6 +431,11 @@ public class GroundItemsPlugin extends Plugin // Cache colors priceChecks.clear(); + if (config.getHighlightOverValue() > 0) + { + priceChecks.put(config.getHighlightOverValue(), config.highlightedColor()); + } + if (config.insaneValuePrice() > 0) { priceChecks.put(config.insaneValuePrice(), config.insaneValueColor()); @@ -450,11 +455,6 @@ public class GroundItemsPlugin extends Plugin { priceChecks.put(config.lowValuePrice(), config.lowValueColor()); } - - if (config.getHighlightOverValue() > 0) - { - priceChecks.put(config.getHighlightOverValue(), config.highlightedColor()); - } } @Subscribe From a5e5e8aa6f5b60b76740e768db501c38864c47ba Mon Sep 17 00:00:00 2001 From: Ron Young Date: Mon, 27 Jan 2020 13:24:11 -0600 Subject: [PATCH 25/27] tag tabs: respect bank rearrange mode for reordering --- .../main/java/net/runelite/api/Varbits.java | 1 + .../plugins/banktags/tabs/TabInterface.java | 27 ++++++++++++++----- .../plugins/banktags/tabs/TabManager.java | 13 ++++++++- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index 2921c5ed2c..c221891fa0 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -470,6 +470,7 @@ public enum Varbits SUPERIOR_ENABLED(5362), FOSSIL_ISLAND_WYVERN_DISABLE(6251), + BANK_REARRANGE_MODE(3959), CURRENT_BANK_TAB(4150), WORLDHOPPER_FAVROITE_1(4597), diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java index 2800f4657d..45d71fb94c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java @@ -690,12 +690,7 @@ public class TabInterface else if (parent.getId() == draggedOn.getId() && parent.getId() == draggedWidget.getId()) { // Reorder tag tabs - if (!Strings.isNullOrEmpty(draggedOn.getName())) - { - tabManager.move(draggedWidget.getName(), draggedOn.getName()); - tabManager.save(); - updateTabs(); - } + moveTagTab(draggedWidget, draggedOn); } } else if (draggedWidget.getItemId() > 0) @@ -725,6 +720,26 @@ public class TabInterface } } + private void moveTagTab(final Widget source, final Widget dest) + { + if (Strings.isNullOrEmpty(dest.getName())) + { + return; + } + + if (client.getVar(Varbits.BANK_REARRANGE_MODE) == 0) + { + tabManager.swap(source.getName(), dest.getName()); + } + else + { + tabManager.insert(source.getName(), dest.getName()); + } + + tabManager.save(); + updateTabs(); + } + private boolean isHidden() { Widget widget = client.getWidget(WidgetInfo.BANK_CONTAINER); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabManager.java index a3f2b06948..f3feed8511 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabManager.java @@ -95,7 +95,7 @@ class TabManager return tagTab; } - void move(String tagToMove, String tagDestination) + void swap(String tagToMove, String tagDestination) { tagToMove = Text.standardize(tagToMove); tagDestination = Text.standardize(tagDestination); @@ -106,6 +106,17 @@ class TabManager } } + void insert(String tagToMove, String tagDestination) + { + tagToMove = Text.standardize(tagToMove); + tagDestination = Text.standardize(tagDestination); + + if (contains(tagToMove) && contains(tagDestination)) + { + tabs.add(indexOf(tagDestination), tabs.remove(indexOf(tagToMove))); + } + } + void remove(String tag) { TagTab tagTab = find(tag); From 51a0a6e9b7d798767f4e7990f846cfe9a787ec14 Mon Sep 17 00:00:00 2001 From: Ron Young Date: Mon, 27 Jan 2020 13:30:07 -0600 Subject: [PATCH 26/27] banktags: support viewing all Tag Tabs in the bank screen --- .../plugins/banktags/BankTagsPlugin.java | 2 + .../plugins/banktags/tabs/MenuIndexes.java | 1 + .../plugins/banktags/tabs/TabInterface.java | 170 ++++++++++++++++-- .../client/plugins/banktags/tabs/TagTab.java | 6 + .../src/main/scripts/BankSearchLayout.rs2asm | 46 +++-- 5 files changed, 196 insertions(+), 29 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java index 26e2612955..8f2dbfc23e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/BankTagsPlugin.java @@ -292,6 +292,8 @@ public class BankTagsPlugin extends Plugin implements MouseWheelListener, KeyLis int intStackSize = client.getIntStackSize(); int stringStackSize = client.getStringStackSize(); + tabInterface.handleScriptEvent(event); + switch (eventName) { case "setSearchBankInputText": diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/MenuIndexes.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/MenuIndexes.java index 51e179b143..bcf03fd585 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/MenuIndexes.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/MenuIndexes.java @@ -31,6 +31,7 @@ class MenuIndexes { static final int NEW_TAB = 2; static final int IMPORT_TAB = 3; + static final int OPEN_TAB_MENU = 4; } static class Tab diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java index 45d71fb94c..82a19b4f3d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TabInterface.java @@ -68,6 +68,7 @@ import net.runelite.api.VarClientStr; import net.runelite.api.Varbits; import net.runelite.api.events.MenuEntryAdded; import net.runelite.api.events.MenuOptionClicked; +import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.api.vars.InputType; import net.runelite.api.widgets.ItemQuantityMode; import net.runelite.api.widgets.JavaScriptCallback; @@ -110,6 +111,9 @@ public class TabInterface private static final String REMOVE_TAG = "Remove-tag"; private static final String TAG_GEAR = "Tag-equipment"; private static final String TAG_INVENTORY = "Tag-inventory"; + private static final String TAB_MENU_KEY = "tagtabs"; + private static final String TAB_MENU = TAG_SEARCH + TAB_MENU_KEY; + private static final String OPEN_TAB_MENU = "View tag tabs"; private static final int TAB_HEIGHT = 40; private static final int TAB_WIDTH = 39; private static final int BUTTON_HEIGHT = 20; @@ -117,6 +121,13 @@ public class TabInterface private static final int SCROLL_TICK = 500; private static final int INCINERATOR_WIDTH = 48; private static final int INCINERATOR_HEIGHT = 39; + private static final int BANK_ITEM_WIDTH = 36; + private static final int BANK_ITEM_HEIGHT = 32; + private static final int BANK_ITEM_X_PADDING = 12; + private static final int BANK_ITEM_Y_PADDING = 4; + private static final int BANK_ITEMS_PER_ROW = 8; + private static final int BANK_ITEM_START_X = 51; + private static final int BANK_ITEM_START_Y = 0; private final Client client; private final ClientThread clientThread; @@ -209,6 +220,7 @@ public class TabInterface newTab = createGraphic("", TabSprites.NEW_TAB.getSpriteId(), -1, TAB_WIDTH, 39, bounds.x, 0, true); newTab.setAction(1, NEW_TAB); newTab.setAction(2, IMPORT_TAB); + newTab.setAction(3, OPEN_TAB_MENU); newTab.setOnOpListener((JavaScriptCallback) this::handleNewTab); tabManager.clear(); @@ -342,6 +354,11 @@ public class TabInterface { notifier.notify("Failed to import tag tab from clipboard, invalid format."); } + break; + case NewTab.OPEN_TAB_MENU: + client.setVarbit(Varbits.CURRENT_BANK_TAB, 0); + openTag(TAB_MENU_KEY); + break; } } @@ -379,6 +396,7 @@ public class TabInterface { iconToSet.setIconItemId(itemId); iconToSet.getIcon().setItemId(itemId); + iconToSet.getMenu().setItemId(itemId); tabManager.setIcon(iconToSet.getTag(), itemId + ""); } }) @@ -528,6 +546,60 @@ public class TabInterface scrollTab(0); } + private void setTabMenuVisible(boolean visible) + { + for (TagTab t : tabManager.getTabs()) + { + t.getMenu().setHidden(!visible); + } + } + + private boolean isTabMenuActive() + { + return TAB_MENU.equals(client.getVar(VarClientStr.INPUT_TEXT)); + } + + public void handleScriptEvent(final ScriptCallbackEvent event) + { + String eventName = event.getEventName(); + + int[] intStack = client.getIntStack(); + int intStackSize = client.getIntStackSize(); + + switch (eventName) + { + case "setBankScroll": + if (!isTabMenuActive()) + { + setTabMenuVisible(false); + return; + } + + setTabMenuVisible(true); + + // scroll height + intStack[intStackSize - 3] = (((tabManager.getTabs().size() - 1) / BANK_ITEMS_PER_ROW) + 1) * (BANK_ITEM_HEIGHT + BANK_ITEM_Y_PADDING); + + // skip normal bank layout + intStack[intStackSize - 2] = 1; + break; + case "beforeBankLayout": + setTabMenuVisible(false); + break; + case "isTabMenuActive": + if (!isTabMenuActive()) + { + intStack[intStackSize - 1] = 0; + return; + } + + // Must set the bank title because we are skipping it in scripts + client.getWidget(WidgetInfo.BANK_TITLE_BAR).setText("Showing items: " + ColorUtil.wrapWithColorTag(TAB_MENU, Color.red)); + intStack[intStackSize - 1] = 1; + break; + } + } + public void handleWheel(final MouseWheelEvent event) { if (parent == null || !canvasBounds.contains(event.getPoint())) @@ -556,7 +628,6 @@ public class TabInterface } MenuEntry[] entries = client.getMenuEntries(); - MenuEntry entry = entries[entries.length - 1]; if (activeTab != null && event.getActionParam1() == WidgetInfo.BANK_ITEM_CONTAINER.getId() @@ -678,7 +749,7 @@ public class TabInterface // is dragging widget and mouse button released if (client.getMouseCurrentButton() == 0) { - if (draggedWidget.getItemId() > 0 && draggedWidget.getId() != parent.getId()) + if (!isTabMenuActive() && draggedWidget.getItemId() > 0 && draggedWidget.getId() != parent.getId()) { // Tag an item dragged on a tag tab if (draggedOn.getId() == parent.getId()) @@ -687,7 +758,8 @@ public class TabInterface updateTabIfActive(Lists.newArrayList(Text.standardize(draggedOn.getName()))); } } - else if (parent.getId() == draggedOn.getId() && parent.getId() == draggedWidget.getId()) + else if ((isTabMenuActive() && draggedWidget.getId() == draggedOn.getId() && draggedOn.getId() != parent.getId()) + || (parent.getId() == draggedOn.getId() && parent.getId() == draggedWidget.getId())) { // Reorder tag tabs moveTagTab(draggedWidget, draggedOn); @@ -746,6 +818,28 @@ public class TabInterface return !config.tabs() || widget == null || widget.isHidden(); } + private void addTabActions(Widget w) + { + w.setAction(1, VIEW_TAB); + w.setAction(2, CHANGE_ICON); + w.setAction(3, REMOVE_TAB); + w.setAction(4, EXPORT_TAB); + w.setAction(5, RENAME_TAB); + w.setOnOpListener((JavaScriptCallback) this::handleTagTab); + } + + private void addTabOptions(Widget w) + { + int clickmask = w.getClickMask(); + clickmask |= WidgetConfig.DRAG; + clickmask |= WidgetConfig.DRAG_ON; + w.setClickMask(clickmask); + w.setDragDeadTime(5); + w.setDragDeadZone(5); + w.setItemQuantity(10000); + w.setItemQuantityMode(ItemQuantityMode.NEVER); + } + private void loadTab(String tag) { TagTab tagTab = tabManager.load(tag); @@ -753,12 +847,7 @@ public class TabInterface if (tagTab.getBackground() == null) { Widget btn = createGraphic(ColorUtil.wrapWithColorTag(tagTab.getTag(), HILIGHT_COLOR), TabSprites.TAB_BACKGROUND.getSpriteId(), -1, TAB_WIDTH, TAB_HEIGHT, bounds.x, 1, true); - btn.setAction(1, VIEW_TAB); - btn.setAction(2, CHANGE_ICON); - btn.setAction(3, REMOVE_TAB); - btn.setAction(4, EXPORT_TAB); - btn.setAction(5, RENAME_TAB); - btn.setOnOpListener((JavaScriptCallback) this::handleTagTab); + addTabActions(btn); tagTab.setBackground(btn); } @@ -771,17 +860,33 @@ public class TabInterface Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT, bounds.x + 3, 1, false); - int clickmask = icon.getClickMask(); - clickmask |= WidgetConfig.DRAG; - clickmask |= WidgetConfig.DRAG_ON; - icon.setClickMask(clickmask); - icon.setDragDeadTime(5); - icon.setDragDeadZone(5); - icon.setItemQuantity(10000); - icon.setItemQuantityMode(ItemQuantityMode.NEVER); + addTabOptions(icon); tagTab.setIcon(icon); } + if (tagTab.getMenu() == null) + { + Widget menu = createGraphic( + client.getWidget(WidgetInfo.BANK_ITEM_CONTAINER), + ColorUtil.wrapWithColorTag(tagTab.getTag(), HILIGHT_COLOR), + -1, + tagTab.getIconItemId(), + BANK_ITEM_WIDTH, BANK_ITEM_HEIGHT, + BANK_ITEM_START_X, BANK_ITEM_START_Y, + true); + addTabActions(menu); + addTabOptions(menu); + if (activeTab != null && activeTab.getTag().equals(TAB_MENU_KEY)) + { + menu.setHidden(false); + } + else + { + menu.setHidden(true); + } + tagTab.setMenu(menu); + } + tabManager.add(tagTab); } @@ -815,6 +920,7 @@ public class TabInterface final String coloredName = ColorUtil.wrapWithColorTag(newTag, HILIGHT_COLOR); tagTab.getIcon().setName(coloredName); tagTab.getBackground().setName(coloredName); + tagTab.getMenu().setName(coloredName); tabManager.removeIcon(oldTag); tabManager.setIcon(newTag, tagTab.getIconItemId() + ""); @@ -978,6 +1084,10 @@ public class TabInterface y -= (currentTabIndex * TAB_HEIGHT + currentTabIndex * MARGIN); } + int itemX = BANK_ITEM_START_X; + int itemY = BANK_ITEM_START_Y; + int rowIndex = 0; + for (TagTab tab : tabManager.getTabs()) { updateWidget(tab.getBackground(), y); @@ -993,6 +1103,23 @@ public class TabInterface } y += TAB_HEIGHT + MARGIN; + + Widget item = tab.getMenu(); + item.setOriginalX(itemX); + item.setOriginalY(itemY); + item.revalidate(); + + rowIndex++; + if (rowIndex == BANK_ITEMS_PER_ROW) + { + itemX = BANK_ITEM_START_X; + itemY += BANK_ITEM_Y_PADDING + BANK_ITEM_HEIGHT; + rowIndex = 0; + } + else + { + itemX += BANK_ITEM_X_PADDING + BANK_ITEM_WIDTH; + } } updateWidget(newTab, y); @@ -1008,9 +1135,9 @@ public class TabInterface downButton.revalidate(); } - private Widget createGraphic(String name, int spriteId, int itemId, int width, int height, int x, int y, boolean hasListener) + private Widget createGraphic(Widget container, String name, int spriteId, int itemId, int width, int height, int x, int y, boolean hasListener) { - Widget widget = parent.createChild(-1, WidgetType.GRAPHIC); + Widget widget = container.createChild(-1, WidgetType.GRAPHIC); widget.setOriginalWidth(width); widget.setOriginalHeight(height); widget.setOriginalX(x); @@ -1037,6 +1164,11 @@ public class TabInterface return widget; } + private Widget createGraphic(String name, int spriteId, int itemId, int width, int height, int x, int y, boolean hasListener) + { + return createGraphic(parent, name, spriteId, itemId, width, height, x, y, hasListener); + } + private void updateWidget(Widget t, int y) { t.setOriginalY(y); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TagTab.java b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TagTab.java index 004e5f45ed..403fc9dddf 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TagTab.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/banktags/tabs/TagTab.java @@ -37,6 +37,7 @@ class TagTab private int iconItemId; private Widget background; private Widget icon; + private Widget menu; TagTab(int iconItemId, String tag) { @@ -55,5 +56,10 @@ class TagTab { icon.setHidden(hide); } + + if (menu != null) + { + menu.setHidden(hide); + } } } diff --git a/runelite-client/src/main/scripts/BankSearchLayout.rs2asm b/runelite-client/src/main/scripts/BankSearchLayout.rs2asm index c6a34565ba..067e8fcbe1 100644 --- a/runelite-client/src/main/scripts/BankSearchLayout.rs2asm +++ b/runelite-client/src/main/scripts/BankSearchLayout.rs2asm @@ -3,6 +3,18 @@ .string_stack_count 0 .int_var_count 35 .string_var_count 1 +; callback "beforeBankLayout" +; Fired before the bank starts its layout +; Used by the TabInterface to hide fake bank items for tag tabs +; +; callback "setBankScroll" +; Fired before bank is calculated +; Used by the TabInterface to show fake bank items for tag tabs +; +; callback "isTabMenuActive" +; Used by the TabInterface to skip setting the bank title + sconst "beforeBankLayout" + runelite_callback get_varbit 5102 iconst 1 if_icmpeq LABEL4 @@ -385,6 +397,15 @@ LABEL339: sub istore 29 LABEL343: + iconst 0 ; Scroll height variable + iconst 0 ; Compare variable + iconst 0 ; + sconst "setBankScroll" ; Show fake bank items for tag tabs + runelite_callback ; If tag tab menu search isn't active + if_icmpeq CONTINUE_SEARCH ; continue to normal bank search + istore 27 ; Load scroll height into variable + jump GetTabRange ; Skip normal bank layout +CONTINUE_SEARCH: iload 30 iload 29 iconst 1 @@ -822,12 +843,12 @@ LABEL740: invoke 514 iconst 1 if_icmpeq LABEL744 - jump LABEL747 + jump GetTabRange LABEL744: iconst 1 iconst 1 invoke 299 -LABEL747: +GetTabRange: iconst -1 istore 31 iconst -1 @@ -844,7 +865,7 @@ LABEL759: iload 19 iconst 816 if_icmplt LABEL763 - jump LABEL843 + jump SetTitle LABEL763: iload 2 iload 19 @@ -936,12 +957,17 @@ LABEL838: add istore 19 jump LABEL759 -LABEL843: +SetTitle: + iconst 0 ; Compare variable + iconst 0 ; + sconst "isTabMenuActive" ; Check if tag tab menu + runelite_callback ; is active and skip setting + if_icmpne FinishBuilding ; the bank title if it is get_varbit 4170 iconst 2 - if_icmpeq LABEL847 - jump LABEL857 -LABEL847: + if_icmpeq SetTitleRomanNumeral + jump SetTitleNumber +SetTitleRomanNumeral: sconst "Tab " iconst 105 iconst 115 @@ -953,8 +979,8 @@ LABEL847: runelite_callback ; iload 5 if_settext - jump LABEL863 -LABEL857: + jump FinishBuilding +SetTitleNumber: sconst "Tab " get_varbit 4150 tostring @@ -963,7 +989,7 @@ LABEL857: runelite_callback ; iload 5 if_settext -LABEL863: +FinishBuilding: iload 0 iload 1 iload 2 From 4c316b477e6d398c12a651146dc38f2f57b9beac Mon Sep 17 00:00:00 2001 From: mlvzk Date: Sun, 1 Mar 2020 21:08:14 +0100 Subject: [PATCH 27/27] reportbutton: add Game Ticks option --- .../reportbutton/ReportButtonPlugin.java | 22 +++++++++++++++++++ .../plugins/reportbutton/TimeStyle.java | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/ReportButtonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/ReportButtonPlugin.java index b633a89b10..d1ec6d6828 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/ReportButtonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/ReportButtonPlugin.java @@ -39,6 +39,7 @@ import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.callback.ClientThread; @@ -62,6 +63,7 @@ public class ReportButtonPlugin extends Plugin private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MMM. dd, yyyy"); private Instant loginTime; + private int ticksSinceLogin; private boolean ready; @Inject @@ -114,12 +116,24 @@ public class ReportButtonPlugin extends Plugin if (ready) { loginTime = Instant.now(); + ticksSinceLogin = 0; ready = false; } break; } } + @Subscribe + public void onGameTick(GameTick tick) + { + ticksSinceLogin++; + + if (config.time() == TimeStyle.GAME_TICKS) + { + updateReportButtonTime(); + } + } + @Schedule( period = 500, unit = ChronoUnit.MILLIS @@ -159,6 +173,9 @@ public class ReportButtonPlugin extends Plugin case DATE: reportButton.setText(getDate()); break; + case GAME_TICKS: + reportButton.setText(getGameTicks()); + break; case OFF: reportButton.setText("Report"); break; @@ -177,6 +194,11 @@ public class ReportButtonPlugin extends Plugin return time.format(DateTimeFormatter.ofPattern("HH:mm:ss")); } + private String getGameTicks() + { + return Integer.toString(ticksSinceLogin); + } + private static String getLocalTime() { return LocalTime.now().format(DATE_TIME_FORMAT); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/TimeStyle.java b/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/TimeStyle.java index 40095b9a4f..a6a0a9a617 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/TimeStyle.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/reportbutton/TimeStyle.java @@ -31,7 +31,8 @@ public enum TimeStyle LOGIN_TIME("Login Timer"), UTC("UTC Time"), JAGEX("Jagex HQ Time"), - LOCAL_TIME("Local Time"); + LOCAL_TIME("Local Time"), + GAME_TICKS("Game Ticks"); private final String name;