From 6e8a29452cbe66fdc89f7f9410eb2e1a11e41ce2 Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 30 Apr 2019 21:48:29 +0200 Subject: [PATCH] Magic Spellbook --- .../main/java/net/runelite/api/EnumID.java | 13 + .../main/java/net/runelite/api/Varbits.java | 1238 +++++++++-------- .../net/runelite/api/widgets/WidgetID.java | 21 +- .../net/runelite/api/widgets/WidgetInfo.java | 78 +- .../client/plugins/spellbook/Spell.java | 14 + .../client/plugins/spellbook/Spellbook.java | 36 + .../plugins/spellbook/SpellbookConfig.java | 116 ++ .../spellbook/SpellbookDragOverlay.java | 57 + .../spellbook/SpellbookMouseListener.java | 55 + .../plugins/spellbook/SpellbookPlugin.java | 449 ++++++ .../main/scripts/MagicSpellBookRedraw.rs2asm | 33 +- 11 files changed, 1441 insertions(+), 669 deletions(-) create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spell.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spellbook.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookDragOverlay.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookMouseListener.java create mode 100644 runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java diff --git a/runelite-api/src/main/java/net/runelite/api/EnumID.java b/runelite-api/src/main/java/net/runelite/api/EnumID.java index 0b2d477a84..bb4ec6fa7b 100644 --- a/runelite-api/src/main/java/net/runelite/api/EnumID.java +++ b/runelite-api/src/main/java/net/runelite/api/EnumID.java @@ -33,4 +33,17 @@ public final class EnumID { public static final int MUSIC_TRACK_NAMES = 812; public static final int MUSIC_TRACK_IDS = 819; + + /** + * Translates spellbook varbit into enum ID + */ + public static final int SPELLBOOKS = 1981; + + /** + * key: index in spellbook, value: NullItemID corresponding to spell + */ + public static final int STANDARD_SPELLBOOK = 1982; + public static final int ANCIENT_SPELLBOOK = 1983; + public static final int LUNAR_SPELLBOOK = 1984; + public static final int ARCEUUS_SPELLBOOK = 1985; } 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 378c92def1..8bf97e3988 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -1,614 +1,624 @@ -/* - * Copyright (c) 2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.runelite.api; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * An enumeration of local client variables. - */ -@AllArgsConstructor -@Getter -public enum Varbits -{ - /* - * If chatbox is transparent or not - */ - TRANSPARENT_CHATBOX(4608), - - /* - * If the player has an active stamina potion effect or not - */ - RUN_SLOWED_DEPLETION_ACTIVE(25), - - /** - * If scrollbar in resizable mode chat is on the left - */ - CHAT_SCROLLBAR_ON_LEFT(6374), - - /** - * Runepouch - */ - RUNE_POUCH_RUNE1(29), - RUNE_POUCH_RUNE2(1622), - RUNE_POUCH_RUNE3(1623), - RUNE_POUCH_AMOUNT1(1624), - RUNE_POUCH_AMOUNT2(1625), - RUNE_POUCH_AMOUNT3(1626), - - /** - * Prayers - */ - QUICK_PRAYER(4103), - PRAYER_THICK_SKIN(4104), - PRAYER_BURST_OF_STRENGTH(4105), - PRAYER_CLARITY_OF_THOUGHT(4106), - PRAYER_SHARP_EYE(4122), - PRAYER_MYSTIC_WILL(4123), - PRAYER_ROCK_SKIN(4107), - PRAYER_SUPERHUMAN_STRENGTH(4108), - PRAYER_IMPROVED_REFLEXES(4109), - PRAYER_RAPID_RESTORE(4110), - PRAYER_RAPID_HEAL(4111), - PRAYER_PROTECT_ITEM(4112), - PRAYER_HAWK_EYE(4124), - PRAYER_MYSTIC_LORE(4125), - PRAYER_STEEL_SKIN(4113), - PRAYER_ULTIMATE_STRENGTH(4114), - PRAYER_INCREDIBLE_REFLEXES(4115), - PRAYER_PROTECT_FROM_MAGIC(4116), - PRAYER_PROTECT_FROM_MISSILES(4117), - PRAYER_PROTECT_FROM_MELEE(4118), - PRAYER_EAGLE_EYE(4126), - PRAYER_MYSTIC_MIGHT(4127), - PRAYER_RETRIBUTION(4119), - PRAYER_REDEMPTION(4120), - PRAYER_SMITE(4121), - PRAYER_CHIVALRY(4128), - PRAYER_PIETY(4129), - PRAYER_PRESERVE(5466), - PRAYER_RIGOUR(5464), - PRAYER_AUGURY(5465), - - /** - * Diary Entries - */ - DIARY_ARDOUGNE_EASY(4458), - DIARY_ARDOUGNE_MEDIUM(4459), - DIARY_ARDOUGNE_HARD(4460), - DIARY_ARDOUGNE_ELITE(4461), - - DIARY_DESERT_EASY(4483), - DIARY_DESERT_MEDIUM(4484), - DIARY_DESERT_HARD(4485), - DIARY_DESERT_ELITE(4486), - - DIARY_FALADOR_EASY(4462), - DIARY_FALADOR_MEDIUM(4463), - DIARY_FALADOR_HARD(4464), - DIARY_FALADOR_ELITE(4465), - - DIARY_FREMENNIK_EASY(4491), - DIARY_FREMENNIK_MEDIUM(4492), - DIARY_FREMENNIK_HARD(4493), - DIARY_FREMENNIK_ELITE(4494), - - DIARY_KANDARIN_EASY(4475), - DIARY_KANDARIN_MEDIUM(4476), - DIARY_KANDARIN_HARD(4477), - DIARY_KANDARIN_ELITE(4478), - - DIARY_KARAMJA_EASY(3578), - DIARY_KARAMJA_MEDIUM(3599), - DIARY_KARAMJA_HARD(3611), - DIARY_KARAMJA_ELITE(4566), - - DIARY_LUMBRIDGE_EASY(4495), - DIARY_LUMBRIDGE_MEDIUM(4496), - DIARY_LUMBRIDGE_HARD(4497), - DIARY_LUMBRIDGE_ELITE(4498), - - DIARY_MORYTANIA_EASY(4487), - DIARY_MORYTANIA_MEDIUM(4488), - DIARY_MORYTANIA_HARD(4489), - DIARY_MORYTANIA_ELITE(4490), - - DIARY_VARROCK_EASY(4479), - DIARY_VARROCK_MEDIUM(4480), - DIARY_VARROCK_HARD(4481), - DIARY_VARROCK_ELITE(4482), - - DIARY_WESTERN_EASY(4471), - DIARY_WESTERN_MEDIUM(4472), - DIARY_WESTERN_HARD(4473), - DIARY_WESTERN_ELITE(4474), - - DIARY_WILDERNESS_EASY(4466), - DIARY_WILDERNESS_MEDIUM(4467), - DIARY_WILDERNESS_HARD(4468), - DIARY_WILDERNESS_ELITE(4469), - - /** - * Kourend house favours - */ - KOUREND_FAVOR_ARCEUUS(4896), - KOUREND_FAVOR_HOSIDIUS(4895), - KOUREND_FAVOR_LOVAKENGJ(4898), - KOUREND_FAVOR_PISCARILIUS(4899), - KOUREND_FAVOR_SHAYZIEN(4894), - - /** - * Equipped weapon type - */ - EQUIPPED_WEAPON_TYPE(357), - - /** - * Defensive casting mode - */ - DEFENSIVE_CASTING_MODE(2668), - - /** - * Options - */ - SIDE_PANELS(4607), - - /** - * Herbiboar Trails - */ - HB_TRAIL_31303(5737), - HB_TRAIL_31306(5738), - HB_TRAIL_31309(5739), - HB_TRAIL_31312(5740), - HB_TRAIL_31315(5741), - HB_TRAIL_31318(5742), - HB_TRAIL_31321(5743), - HB_TRAIL_31324(5744), - HB_TRAIL_31327(5745), - HB_TRAIL_31330(5746), - - HB_TRAIL_31333(5768), - HB_TRAIL_31336(5769), - HB_TRAIL_31339(5770), - HB_TRAIL_31342(5771), - HB_TRAIL_31345(5772), - HB_TRAIL_31348(5773), - HB_TRAIL_31351(5774), - HB_TRAIL_31354(5775), - HB_TRAIL_31357(5776), - HB_TRAIL_31360(5777), - - HB_TRAIL_31363(5747), - HB_TRAIL_31366(5748), - HB_TRAIL_31369(5749), - HB_TRAIL_31372(5750), - - HB_FINISH(5766), - HB_STARTED(5767), //not working - - /** - * Barbarian Assault - */ - IN_GAME_BA(3923), - - /** - * 0 = Outside wilderness - * 1 = In wilderness - */ - IN_WILDERNESS(5963), - - /** - * Fishing Trawler - * FISHING_TRAWLER_ACTIVITY Expected values: 0-255 - */ - FISHING_TRAWLER_ACTIVITY(3377), - - /** - * Blast Furnace Bar Dispenser - *

- * These are the expected values: - * 0 = No bars being processed - * 1 = Ores are being processed on the conveyor belt, bar dispenser cannot be checked - * 2 = Bars are cooling down - * 3 = Bars can be collected - */ - BAR_DISPENSER(936), - - /** - * Motherlode mine sack - */ - SACK_NUMBER(5558), - SACK_UPGRADED(5556), - - /** - * Experience tracker - *

- * EXPERIENCE_TRACKER_POSITION expected values: - * 0 = Right - * 1 = Middle - * 2 = Left - */ - EXPERIENCE_TRACKER_POSITION(4692), - EXPERIENCE_TRACKER_COUNTER(4697), - EXPERIENCE_TRACKER_PROGRESS_BAR(4698), - - /** - * Experience drop color - */ - EXPERIENCE_DROP_COLOR(4695), - - /** - * Tithe Farm - */ - TITHE_FARM_SACK_AMOUNT(4900), - TITHE_FARM_SACK_ICON(5370), - TITHE_FARM_POINTS(4893), - - /** - * Blast Mine - */ - BLAST_MINE_COAL(4924), - BLAST_MINE_GOLD(4925), - BLAST_MINE_MITHRIL(4926), - BLAST_MINE_ADAMANTITE(4921), - BLAST_MINE_RUNITE(4922), - - /** - * Raids - */ - IN_RAID(5432), - TOTAL_POINTS(5431), - PERSONAL_POINTS(5422), - RAID_PARTY_SIZE(5424), - - /** - * Theatre of Blood 1=In Party, 2=Inside/Spectator, 3=Dead Spectating - */ - THEATRE_OF_BLOOD(6440), - - /** - * Nightmare Zone - */ - NMZ_ABSORPTION(3956), - NMZ_POINTS(3949), - NMZ_OVERLOAD(3955), - - /** - * Blast Furnace - */ - BLAST_FURNACE_COPPER_ORE(959), - BLAST_FURNACE_TIN_ORE(950), - BLAST_FURNACE_IRON_ORE(951), - BLAST_FURNACE_COAL(949), - BLAST_FURNACE_MITHRIL_ORE(952), - BLAST_FURNACE_ADAMANTITE_ORE(953), - BLAST_FURNACE_RUNITE_ORE(954), - BLAST_FURNACE_SILVER_ORE(956), - BLAST_FURNACE_GOLD_ORE(955), - - BLAST_FURNACE_BRONZE_BAR(941), - BLAST_FURNACE_IRON_BAR(942), - BLAST_FURNACE_STEEL_BAR(943), - BLAST_FURNACE_MITHRIL_BAR(944), - BLAST_FURNACE_ADAMANTITE_BAR(945), - BLAST_FURNACE_RUNITE_BAR(946), - BLAST_FURNACE_SILVER_BAR(948), - BLAST_FURNACE_GOLD_BAR(947), - - BLAST_FURNACE_COFFER(5357), - - /** - * Pyramid plunder - */ - PYRAMID_PLUNDER_TIMER(2375), - PYRAMID_PLUNDER_ROOM(2377), - - /** - * Barrows - */ - BARROWS_KILLED_AHRIM(457), - BARROWS_KILLED_DHAROK(458), - BARROWS_KILLED_GUTHAN(459), - BARROWS_KILLED_KARIL(460), - BARROWS_KILLED_TORAG(461), - BARROWS_KILLED_VERAC(462), - BARROWS_REWARD_POTENTIAL(463), - BARROWS_NPCS_SLAIN(464), - - /** - * Spicy stew ingredients - */ - SPICY_STEW_RED_SPICES(1879), - SPICY_STEW_YELLOW_SPICES(1880), - SPICY_STEW_BROWN_SPICES(1881), - SPICY_STEW_ORANGE_SPICES(1882), - - /** - * Multicombat area - */ - MULTICOMBAT_AREA(4605), - - /** - * In the Wilderness - */ - IN_THE_WILDERNESS(5963), - - /** - * Kingdom Management - */ - KINGDOM_FAVOR(72), - KINGDOM_COFFER(74), - - /** - * The Hand in the Sand quest status - */ - QUEST_THE_HAND_IN_THE_SAND(1527), - - /** - * Daily Tasks (Collection availability) - */ - DAILY_HERB_BOXES_COLLECTED(3961), - DAILY_STAVES_COLLECTED(4539), - DAILY_ESSENCE_COLLECTED(4547), - DAILY_RUNES_COLLECTED(4540), - DAILY_SAND_COLLECTED(4549), - DAILY_ARROWS_STATE(4563), - DAILY_FLAX_STATE(4559), - /** - * This varbit tracks how much bonemeal has been redeemed from Robin - * The player gets 13 for each diary completed above and including Medium, for a maxiumum of 39 - */ - DAILY_BONEMEAL_STATE(4543), - - /** - * Fairy Ring - */ - FAIR_RING_LAST_DESTINATION(5374), - FAIRY_RING_DIAL_ADCB(3985), //Left dial - FAIRY_RIGH_DIAL_ILJK(3986), //Middle dial - FAIRY_RING_DIAL_PSRQ(3987), //Right dial - - /** - * Transmog controllers for farming - */ - FARMING_4771(4771), - FARMING_4772(4772), - FARMING_4773(4773), - FARMING_4774(4774), - FARMING_4775(4775), - FARMING_7904(7904), - FARMING_7905(7905), - FARMING_7906(7906), - FARMING_7907(7907), - FARMING_7908(7908), - FARMING_7909(7909), - FARMING_7910(7910), - FARMING_7911(7911), - - /** - * Transmog controllers for grapes - */ - GRAPES_4953(4953), - GRAPES_4954(4954), - GRAPES_4955(4955), - GRAPES_4956(4956), - GRAPES_4957(4957), - GRAPES_4958(4958), - GRAPES_4959(4959), - GRAPES_4960(4960), - GRAPES_4961(4961), - GRAPES_4962(4962), - GRAPES_4963(4963), - GRAPES_4964(4964), - - /** - * Automatically weed farming patches - */ - AUTOWEED(5557), - - /** - * The varbit that stores the players {@code AccountType}. - */ - ACCOUNT_TYPE(1777), - - /** - * The varbit that stores the oxygen percentage for player - */ - OXYGEN_LEVEL(5811), - - /** - * Corp beast damage - */ - CORP_DAMAGE(999), - - /** - * Toggleable slayer unlocks - */ - SUPERIOR_ENABLED(5362), - FOSSIL_ISLAND_WYVERN_DISABLE(6251), - - CURRENT_BANK_TAB(4150), - - WORLDHOPPER_FAVROITE_1(4597), - WORLDHOPPER_FAVROITE_2(4598), - - /** - * Vengeance is active - */ - VENGEANCE_ACTIVE(2450), - - /** - * Spell cooldowns - */ - VENGEANCE_COOLDOWN(2451), - - /** - * 0 = standard - * 1 = ancients - * 2 = lunars - * 3 = arrceus - **/ - SPELLBOOK_ID(4070), - - /** - * 0 = no - * 1 = yes - **/ - SPELLBOOK_HIDDEN(6718), - - /** - * Amount of items in each bank tab - */ - BANK_TAB_ONE_COUNT(4171), - BANK_TAB_TWO_COUNT(4172), - BANK_TAB_THREE_COUNT(4173), - BANK_TAB_FOUR_COUNT(4174), - BANK_TAB_FIVE_COUNT(4175), - BANK_TAB_SIX_COUNT(4176), - BANK_TAB_SEVEN_COUNT(4177), - BANK_TAB_EIGHT_COUNT(4178), - BANK_TAB_NINE_COUNT(4179), - - /** - * Type of GE offer currently being created - * 0 = buy - * 1 = sell - */ - GE_OFFER_CREATION_TYPE(4397), - - - /** - * Spells being auto-casted - */ - AUTO_CAST_SPELL(276), - - - /** - * The active tab within the quest interface - */ - QUEST_TAB(8168), - - /** - * Temple Trekking - */ - TREK_POINTS(1955), - TREK_STARTED(1956), - TREK_EVENT(1958), - TREK_STATUS(6719), - BLOAT_ENTERED_ROOM(6447), - - /** - * f2p Quest varbits, these don't hold the completion value. - */ - QUEST_DEMON_SLAYER(2561), - QUEST_GOBLIN_DIPLOMACY(2378), - QUEST_MISTHALIN_MYSTERY(3468), - QUEST_THE_CORSAIR_CURSE(6071), - QUEST_X_MARKS_THE_SPOT(8063), - - /** - * member Quest varbits, these don't hold the completion value. - */ - QUEST_ANIMAL_MAGNETISM(3185), - QUEST_BETWEEN_A_ROCK(299), - QUEST_CONTACT(3274), - QUEST_ZOGRE_FLESH_EATERS(487), - QUEST_DARKNESS_OF_HALLOWVALE(2573), - QUEST_DEATH_TO_THE_DORGESHUUN(2258), - QUEST_DESERT_TREASURE(358), - QUEST_DEVIOUS_MINDS(1465), - QUEST_EAGLES_PEAK(2780), - QUEST_ELEMENTAL_WORKSHOP_II(2639), - QUEST_ENAKHRAS_LAMENT(1560), - QUEST_ENLIGHTENED_JOURNEY(2866), - QUEST_THE_EYES_OF_GLOUPHRIE(2497), - QUEST_FAIRYTALE_I_GROWING_PAINS(1803), - QUEST_FAIRYTALE_II_CURE_A_QUEEN(2326), - QUEST_THE_FEUD(334), - QUEST_FORGETTABLE_TALE(822), - QUEST_GARDEN_OF_TRANQUILLITY(961), - QUEST_GHOSTS_AHOY(217), - QUEST_THE_GIANT_DWARF(571), - QUEST_THE_GOLEM(346), - QUEST_HORROR_FROM_THE_DEEP(34), - QUEST_ICTHLARINS_LITTLE_HELPER(418), - QUEST_IN_AID_OF_THE_MYREQUE(1990), - QUEST_THE_LOST_TRIBE(532), - QUEST_LUNAR_DIPLOMACY(2448), - QUEST_MAKING_HISTORY(1383), - QUEST_MOUNTAIN_DAUGHTER(260), - QUEST_MOURNINGS_ENDS_PART_II(1103), - QUEST_MY_ARMS_BIG_ADVENTURE(2790), - QUEST_RATCATCHERS(1404), - QUEST_RECIPE_FOR_DISASTER(1850), - QUEST_RECRUITMENT_DRIVE(657), - QUEST_ROYAL_TROUBLE(2140), - QUEST_THE_SLUG_MENACE(2610), - QUEST_SHADOW_OF_THE_STORM(1372), - QUEST_A_SOULS_BANE(2011), - QUEST_SPIRITS_OF_THE_ELID(1444), - QUEST_SWAN_SONG(2098), - QUEST_A_TAIL_OF_TWO_CATS(1028), - QUEST_TEARS_OF_GUTHIX(451), - QUEST_WANTED(1051), - QUEST_COLD_WAR(3293), - QUEST_THE_FREMENNIK_ISLES(3311), - QUEST_TOWER_OF_LIFE(3337), - QUEST_WHAT_LIES_BELOW(3523), - QUEST_OLAFS_QUEST(3534), - QUEST_ANOTHER_SLICE_OF_HAM(3550), - QUEST_DREAM_MENTOR(3618), - QUEST_GRIM_TALES(2783), - QUEST_KINGS_RANSOM(3888), - QUEST_MONKEY_MADNESS_II(5027), - QUEST_CLIENT_OF_KOUREND(5619), - QUEST_BONE_VOYAGE(5795), - QUEST_THE_QUEEN_OF_THIEVES(6037), - QUEST_THE_DEPTHS_OF_DESPAIR(6027), - QUEST_DRAGON_SLAYER_II(6104), - QUEST_TALE_OF_THE_RIGHTEOUS(6358), - QUEST_A_TASTE_OF_HOPE(6396), - QUEST_MAKING_FRIENDS_WITH_MY_ARM(6528), - QUEST_THE_ASCENT_OF_ARCEUUS(7856), - QUEST_THE_FORSAKEN_TOWER(7796), - - /** - * mini-quest varbits, these don't hold the completion value. - */ - QUEST_ARCHITECTURAL_ALLIANCE(4982), - QUEST_BEAR_YOUR_SOUL(5078), - QUEST_CURSE_OF_THE_EMPTY_LORD(821), - QUEST_ENCHANTED_KEY(1391), - QUEST_THE_GENERALS_SHADOW(3330), - QUEST_SKIPPY_AND_THE_MOGRES(1344), - QUEST_LAIR_OF_TARN_RAZORLOR(3290), - QUEST_FAMILY_PEST(5347), - QUEST_THE_MAGE_ARENA_II(6067); - - /** - * The raw varbit ID. - */ - private final int id; -} +/* + * Copyright (c) 2017, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * An enumeration of local client variables. + */ +@AllArgsConstructor +@Getter +public enum Varbits +{ + /* + * If chatbox is transparent or not + */ + TRANSPARENT_CHATBOX(4608), + + /* + * If the player has an active stamina potion effect or not + */ + RUN_SLOWED_DEPLETION_ACTIVE(25), + + /** + * If scrollbar in resizable mode chat is on the left + */ + CHAT_SCROLLBAR_ON_LEFT(6374), + + /** + * Runepouch + */ + RUNE_POUCH_RUNE1(29), + RUNE_POUCH_RUNE2(1622), + RUNE_POUCH_RUNE3(1623), + RUNE_POUCH_AMOUNT1(1624), + RUNE_POUCH_AMOUNT2(1625), + RUNE_POUCH_AMOUNT3(1626), + + /** + * Prayers + */ + QUICK_PRAYER(4103), + PRAYER_THICK_SKIN(4104), + PRAYER_BURST_OF_STRENGTH(4105), + PRAYER_CLARITY_OF_THOUGHT(4106), + PRAYER_SHARP_EYE(4122), + PRAYER_MYSTIC_WILL(4123), + PRAYER_ROCK_SKIN(4107), + PRAYER_SUPERHUMAN_STRENGTH(4108), + PRAYER_IMPROVED_REFLEXES(4109), + PRAYER_RAPID_RESTORE(4110), + PRAYER_RAPID_HEAL(4111), + PRAYER_PROTECT_ITEM(4112), + PRAYER_HAWK_EYE(4124), + PRAYER_MYSTIC_LORE(4125), + PRAYER_STEEL_SKIN(4113), + PRAYER_ULTIMATE_STRENGTH(4114), + PRAYER_INCREDIBLE_REFLEXES(4115), + PRAYER_PROTECT_FROM_MAGIC(4116), + PRAYER_PROTECT_FROM_MISSILES(4117), + PRAYER_PROTECT_FROM_MELEE(4118), + PRAYER_EAGLE_EYE(4126), + PRAYER_MYSTIC_MIGHT(4127), + PRAYER_RETRIBUTION(4119), + PRAYER_REDEMPTION(4120), + PRAYER_SMITE(4121), + PRAYER_CHIVALRY(4128), + PRAYER_PIETY(4129), + PRAYER_PRESERVE(5466), + PRAYER_RIGOUR(5464), + PRAYER_AUGURY(5465), + + /** + * Diary Entries + */ + DIARY_ARDOUGNE_EASY(4458), + DIARY_ARDOUGNE_MEDIUM(4459), + DIARY_ARDOUGNE_HARD(4460), + DIARY_ARDOUGNE_ELITE(4461), + + DIARY_DESERT_EASY(4483), + DIARY_DESERT_MEDIUM(4484), + DIARY_DESERT_HARD(4485), + DIARY_DESERT_ELITE(4486), + + DIARY_FALADOR_EASY(4462), + DIARY_FALADOR_MEDIUM(4463), + DIARY_FALADOR_HARD(4464), + DIARY_FALADOR_ELITE(4465), + + DIARY_FREMENNIK_EASY(4491), + DIARY_FREMENNIK_MEDIUM(4492), + DIARY_FREMENNIK_HARD(4493), + DIARY_FREMENNIK_ELITE(4494), + + DIARY_KANDARIN_EASY(4475), + DIARY_KANDARIN_MEDIUM(4476), + DIARY_KANDARIN_HARD(4477), + DIARY_KANDARIN_ELITE(4478), + + DIARY_KARAMJA_EASY(3578), + DIARY_KARAMJA_MEDIUM(3599), + DIARY_KARAMJA_HARD(3611), + DIARY_KARAMJA_ELITE(4566), + + DIARY_LUMBRIDGE_EASY(4495), + DIARY_LUMBRIDGE_MEDIUM(4496), + DIARY_LUMBRIDGE_HARD(4497), + DIARY_LUMBRIDGE_ELITE(4498), + + DIARY_MORYTANIA_EASY(4487), + DIARY_MORYTANIA_MEDIUM(4488), + DIARY_MORYTANIA_HARD(4489), + DIARY_MORYTANIA_ELITE(4490), + + DIARY_VARROCK_EASY(4479), + DIARY_VARROCK_MEDIUM(4480), + DIARY_VARROCK_HARD(4481), + DIARY_VARROCK_ELITE(4482), + + DIARY_WESTERN_EASY(4471), + DIARY_WESTERN_MEDIUM(4472), + DIARY_WESTERN_HARD(4473), + DIARY_WESTERN_ELITE(4474), + + DIARY_WILDERNESS_EASY(4466), + DIARY_WILDERNESS_MEDIUM(4467), + DIARY_WILDERNESS_HARD(4468), + DIARY_WILDERNESS_ELITE(4469), + + /** + * Kourend house favours + */ + KOUREND_FAVOR_ARCEUUS(4896), + KOUREND_FAVOR_HOSIDIUS(4895), + KOUREND_FAVOR_LOVAKENGJ(4898), + KOUREND_FAVOR_PISCARILIUS(4899), + KOUREND_FAVOR_SHAYZIEN(4894), + + /** + * Equipped weapon type + */ + EQUIPPED_WEAPON_TYPE(357), + + /** + * Defensive casting mode + */ + DEFENSIVE_CASTING_MODE(2668), + + /** + * Options + */ + SIDE_PANELS(4607), + + /** + * Herbiboar Trails + */ + HB_TRAIL_31303(5737), + HB_TRAIL_31306(5738), + HB_TRAIL_31309(5739), + HB_TRAIL_31312(5740), + HB_TRAIL_31315(5741), + HB_TRAIL_31318(5742), + HB_TRAIL_31321(5743), + HB_TRAIL_31324(5744), + HB_TRAIL_31327(5745), + HB_TRAIL_31330(5746), + + HB_TRAIL_31333(5768), + HB_TRAIL_31336(5769), + HB_TRAIL_31339(5770), + HB_TRAIL_31342(5771), + HB_TRAIL_31345(5772), + HB_TRAIL_31348(5773), + HB_TRAIL_31351(5774), + HB_TRAIL_31354(5775), + HB_TRAIL_31357(5776), + HB_TRAIL_31360(5777), + + HB_TRAIL_31363(5747), + HB_TRAIL_31366(5748), + HB_TRAIL_31369(5749), + HB_TRAIL_31372(5750), + + HB_FINISH(5766), + HB_STARTED(5767), //not working + + /** + * Barbarian Assault + */ + IN_GAME_BA(3923), + + /** + * 0 = Outside wilderness + * 1 = In wilderness + */ + IN_WILDERNESS(5963), + + /** + * Fishing Trawler + * FISHING_TRAWLER_ACTIVITY Expected values: 0-255 + */ + FISHING_TRAWLER_ACTIVITY(3377), + + /** + * Blast Furnace Bar Dispenser + *

+ * These are the expected values: + * 0 = No bars being processed + * 1 = Ores are being processed on the conveyor belt, bar dispenser cannot be checked + * 2 = Bars are cooling down + * 3 = Bars can be collected + */ + BAR_DISPENSER(936), + + /** + * Motherlode mine sack + */ + SACK_NUMBER(5558), + SACK_UPGRADED(5556), + + /** + * Experience tracker + *

+ * EXPERIENCE_TRACKER_POSITION expected values: + * 0 = Right + * 1 = Middle + * 2 = Left + */ + EXPERIENCE_TRACKER_POSITION(4692), + EXPERIENCE_TRACKER_COUNTER(4697), + EXPERIENCE_TRACKER_PROGRESS_BAR(4698), + + /** + * Experience drop color + */ + EXPERIENCE_DROP_COLOR(4695), + + /** + * Tithe Farm + */ + TITHE_FARM_SACK_AMOUNT(4900), + TITHE_FARM_SACK_ICON(5370), + TITHE_FARM_POINTS(4893), + + /** + * Blast Mine + */ + BLAST_MINE_COAL(4924), + BLAST_MINE_GOLD(4925), + BLAST_MINE_MITHRIL(4926), + BLAST_MINE_ADAMANTITE(4921), + BLAST_MINE_RUNITE(4922), + + /** + * Raids + */ + IN_RAID(5432), + TOTAL_POINTS(5431), + PERSONAL_POINTS(5422), + RAID_PARTY_SIZE(5424), + + /** + * Theatre of Blood 1=In Party, 2=Inside/Spectator, 3=Dead Spectating + */ + THEATRE_OF_BLOOD(6440), + + /** + * Nightmare Zone + */ + NMZ_ABSORPTION(3956), + NMZ_POINTS(3949), + NMZ_OVERLOAD(3955), + + /** + * Blast Furnace + */ + BLAST_FURNACE_COPPER_ORE(959), + BLAST_FURNACE_TIN_ORE(950), + BLAST_FURNACE_IRON_ORE(951), + BLAST_FURNACE_COAL(949), + BLAST_FURNACE_MITHRIL_ORE(952), + BLAST_FURNACE_ADAMANTITE_ORE(953), + BLAST_FURNACE_RUNITE_ORE(954), + BLAST_FURNACE_SILVER_ORE(956), + BLAST_FURNACE_GOLD_ORE(955), + + BLAST_FURNACE_BRONZE_BAR(941), + BLAST_FURNACE_IRON_BAR(942), + BLAST_FURNACE_STEEL_BAR(943), + BLAST_FURNACE_MITHRIL_BAR(944), + BLAST_FURNACE_ADAMANTITE_BAR(945), + BLAST_FURNACE_RUNITE_BAR(946), + BLAST_FURNACE_SILVER_BAR(948), + BLAST_FURNACE_GOLD_BAR(947), + + BLAST_FURNACE_COFFER(5357), + + /** + * Pyramid plunder + */ + PYRAMID_PLUNDER_TIMER(2375), + PYRAMID_PLUNDER_ROOM(2377), + + /** + * Barrows + */ + BARROWS_KILLED_AHRIM(457), + BARROWS_KILLED_DHAROK(458), + BARROWS_KILLED_GUTHAN(459), + BARROWS_KILLED_KARIL(460), + BARROWS_KILLED_TORAG(461), + BARROWS_KILLED_VERAC(462), + BARROWS_REWARD_POTENTIAL(463), + BARROWS_NPCS_SLAIN(464), + + /** + * Spicy stew ingredients + */ + SPICY_STEW_RED_SPICES(1879), + SPICY_STEW_YELLOW_SPICES(1880), + SPICY_STEW_BROWN_SPICES(1881), + SPICY_STEW_ORANGE_SPICES(1882), + + /** + * Multicombat area + */ + MULTICOMBAT_AREA(4605), + + /** + * In the Wilderness + */ + IN_THE_WILDERNESS(5963), + + /** + * Kingdom Management + */ + KINGDOM_FAVOR(72), + KINGDOM_COFFER(74), + + /** + * The Hand in the Sand quest status + */ + QUEST_THE_HAND_IN_THE_SAND(1527), + + /** + * Daily Tasks (Collection availability) + */ + DAILY_HERB_BOXES_COLLECTED(3961), + DAILY_STAVES_COLLECTED(4539), + DAILY_ESSENCE_COLLECTED(4547), + DAILY_RUNES_COLLECTED(4540), + DAILY_SAND_COLLECTED(4549), + DAILY_ARROWS_STATE(4563), + DAILY_FLAX_STATE(4559), + /** + * This varbit tracks how much bonemeal has been redeemed from Robin + * The player gets 13 for each diary completed above and including Medium, for a maxiumum of 39 + */ + DAILY_BONEMEAL_STATE(4543), + + /** + * Fairy Ring + */ + FAIR_RING_LAST_DESTINATION(5374), + FAIRY_RING_DIAL_ADCB(3985), //Left dial + FAIRY_RIGH_DIAL_ILJK(3986), //Middle dial + FAIRY_RING_DIAL_PSRQ(3987), //Right dial + + /** + * Transmog controllers for farming + */ + FARMING_4771(4771), + FARMING_4772(4772), + FARMING_4773(4773), + FARMING_4774(4774), + FARMING_4775(4775), + FARMING_7904(7904), + FARMING_7905(7905), + FARMING_7906(7906), + FARMING_7907(7907), + FARMING_7908(7908), + FARMING_7909(7909), + FARMING_7910(7910), + FARMING_7911(7911), + + /** + * Transmog controllers for grapes + */ + GRAPES_4953(4953), + GRAPES_4954(4954), + GRAPES_4955(4955), + GRAPES_4956(4956), + GRAPES_4957(4957), + GRAPES_4958(4958), + GRAPES_4959(4959), + GRAPES_4960(4960), + GRAPES_4961(4961), + GRAPES_4962(4962), + GRAPES_4963(4963), + GRAPES_4964(4964), + + /** + * Automatically weed farming patches + */ + AUTOWEED(5557), + + /** + * The varbit that stores the players {@code AccountType}. + */ + ACCOUNT_TYPE(1777), + + /** + * The varbit that stores the oxygen percentage for player + */ + OXYGEN_LEVEL(5811), + + /** + * Corp beast damage + */ + CORP_DAMAGE(999), + + /** + * Toggleable slayer unlocks + */ + SUPERIOR_ENABLED(5362), + FOSSIL_ISLAND_WYVERN_DISABLE(6251), + + CURRENT_BANK_TAB(4150), + + WORLDHOPPER_FAVROITE_1(4597), + WORLDHOPPER_FAVROITE_2(4598), + + /** + * Vengeance is active + */ + VENGEANCE_ACTIVE(2450), + + /** + * Spell cooldowns + */ + VENGEANCE_COOLDOWN(2451), + + /** + * 0 = standard + * 1 = ancients + * 2 = lunars + * 3 = arrceus + **/ + SPELLBOOK_ID(4070), + + /** + * 0 = no + * 1 = yes + **/ + SPELLBOOK_HIDDEN(6718), + + /** + * Amount of items in each bank tab + */ + BANK_TAB_ONE_COUNT(4171), + BANK_TAB_TWO_COUNT(4172), + BANK_TAB_THREE_COUNT(4173), + BANK_TAB_FOUR_COUNT(4174), + BANK_TAB_FIVE_COUNT(4175), + BANK_TAB_SIX_COUNT(4176), + BANK_TAB_SEVEN_COUNT(4177), + BANK_TAB_EIGHT_COUNT(4178), + BANK_TAB_NINE_COUNT(4179), + + /** + * Type of GE offer currently being created + * 0 = buy + * 1 = sell + */ + GE_OFFER_CREATION_TYPE(4397), + + + /** + * Spells being auto-casted + */ + AUTO_CAST_SPELL(276), + + + /** + * The active tab within the quest interface + */ + QUEST_TAB(8168), + + /** + * Temple Trekking + */ + TREK_POINTS(1955), + TREK_STARTED(1956), + TREK_EVENT(1958), + TREK_STATUS(6719), + BLOAT_ENTERED_ROOM(6447), + + /** + * f2p Quest varbits, these don't hold the completion value. + */ + QUEST_DEMON_SLAYER(2561), + QUEST_GOBLIN_DIPLOMACY(2378), + QUEST_MISTHALIN_MYSTERY(3468), + QUEST_THE_CORSAIR_CURSE(6071), + QUEST_X_MARKS_THE_SPOT(8063), + + /** + * member Quest varbits, these don't hold the completion value. + */ + QUEST_ANIMAL_MAGNETISM(3185), + QUEST_BETWEEN_A_ROCK(299), + QUEST_CONTACT(3274), + QUEST_ZOGRE_FLESH_EATERS(487), + QUEST_DARKNESS_OF_HALLOWVALE(2573), + QUEST_DEATH_TO_THE_DORGESHUUN(2258), + QUEST_DESERT_TREASURE(358), + QUEST_DEVIOUS_MINDS(1465), + QUEST_EAGLES_PEAK(2780), + QUEST_ELEMENTAL_WORKSHOP_II(2639), + QUEST_ENAKHRAS_LAMENT(1560), + QUEST_ENLIGHTENED_JOURNEY(2866), + QUEST_THE_EYES_OF_GLOUPHRIE(2497), + QUEST_FAIRYTALE_I_GROWING_PAINS(1803), + QUEST_FAIRYTALE_II_CURE_A_QUEEN(2326), + QUEST_THE_FEUD(334), + QUEST_FORGETTABLE_TALE(822), + QUEST_GARDEN_OF_TRANQUILLITY(961), + QUEST_GHOSTS_AHOY(217), + QUEST_THE_GIANT_DWARF(571), + QUEST_THE_GOLEM(346), + QUEST_HORROR_FROM_THE_DEEP(34), + QUEST_ICTHLARINS_LITTLE_HELPER(418), + QUEST_IN_AID_OF_THE_MYREQUE(1990), + QUEST_THE_LOST_TRIBE(532), + QUEST_LUNAR_DIPLOMACY(2448), + QUEST_MAKING_HISTORY(1383), + QUEST_MOUNTAIN_DAUGHTER(260), + QUEST_MOURNINGS_ENDS_PART_II(1103), + QUEST_MY_ARMS_BIG_ADVENTURE(2790), + QUEST_RATCATCHERS(1404), + QUEST_RECIPE_FOR_DISASTER(1850), + QUEST_RECRUITMENT_DRIVE(657), + QUEST_ROYAL_TROUBLE(2140), + QUEST_THE_SLUG_MENACE(2610), + QUEST_SHADOW_OF_THE_STORM(1372), + QUEST_A_SOULS_BANE(2011), + QUEST_SPIRITS_OF_THE_ELID(1444), + QUEST_SWAN_SONG(2098), + QUEST_A_TAIL_OF_TWO_CATS(1028), + QUEST_TEARS_OF_GUTHIX(451), + QUEST_WANTED(1051), + QUEST_COLD_WAR(3293), + QUEST_THE_FREMENNIK_ISLES(3311), + QUEST_TOWER_OF_LIFE(3337), + QUEST_WHAT_LIES_BELOW(3523), + QUEST_OLAFS_QUEST(3534), + QUEST_ANOTHER_SLICE_OF_HAM(3550), + QUEST_DREAM_MENTOR(3618), + QUEST_GRIM_TALES(2783), + QUEST_KINGS_RANSOM(3888), + QUEST_MONKEY_MADNESS_II(5027), + QUEST_CLIENT_OF_KOUREND(5619), + QUEST_BONE_VOYAGE(5795), + QUEST_THE_QUEEN_OF_THIEVES(6037), + QUEST_THE_DEPTHS_OF_DESPAIR(6027), + QUEST_DRAGON_SLAYER_II(6104), + QUEST_TALE_OF_THE_RIGHTEOUS(6358), + QUEST_A_TASTE_OF_HOPE(6396), + QUEST_MAKING_FRIENDS_WITH_MY_ARM(6528), + QUEST_THE_ASCENT_OF_ARCEUUS(7856), + QUEST_THE_FORSAKEN_TOWER(7796), + + /** + * mini-quest varbits, these don't hold the completion value. + */ + QUEST_ARCHITECTURAL_ALLIANCE(4982), + QUEST_BEAR_YOUR_SOUL(5078), + QUEST_CURSE_OF_THE_EMPTY_LORD(821), + QUEST_ENCHANTED_KEY(1391), + QUEST_THE_GENERALS_SHADOW(3330), + QUEST_SKIPPY_AND_THE_MOGRES(1344), + QUEST_LAIR_OF_TARN_RAZORLOR(3290), + QUEST_FAMILY_PEST(5347), + QUEST_THE_MAGE_ARENA_II(6067), + + /** + * Active spellbook (see enumID) + */ + SPELLBOOK(4070), + + /** + * Spellbook filtering (1 = unfiltered, 0 = filtered) + */ + FILTER_SPELLBOOK(6718); + + /** + * The raw varbit ID. + */ + private final int id; +} 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 b90f1f7499..b3878756bc 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 @@ -432,7 +432,7 @@ public class WidgetID static final int EQUIP_ICON = 61; static final int PRAYER_TAB = 55; static final int PRAYER_ICON = 62; - static final int SPELL_TAB = 56; + static final int MAGIC_TAB = 56; static final int SPELL_ICON = 53; static final int FC_TAB = 35; static final int FC_ICON = 41; @@ -763,10 +763,13 @@ public class WidgetID static final int TELEPORT_BUTTON = 26; } - static class StandardSpellBook + static class SpellBook { + static final int FILTERED_SPELLS_BOUNDS = 3; + + // NORMAL SPELLS static final int LUMBRIDGE_HOME_TELEPORT = 4; -static final int WIND_STRIKE = 5; + static final int WIND_STRIKE = 5; static final int CONFUSE = 6; static final int ENCHANT_CROSSBOW_BOLT = 7; static final int WATER_STRIKE = 8; @@ -835,10 +838,8 @@ static final int WIND_STRIKE = 5; static final int EARTH_SURGE = 71; static final int LVL_7_ENCHANT = 72; static final int FIRE_SURGE = 73; - } - static class AncientSpellBook { - static final int BOUNTY_TARGET_TELEPORT = 68; + // ANCIENT SPELLS static final int ICE_RUSH = 74; static final int ICE_BLITZ = 75; static final int ICE_BURST = 76; @@ -864,10 +865,8 @@ static final int WIND_STRIKE = 5; static final int ANNAKARL_TELEPORT = 96; static final int GHORROCK_TELEPORT = 97; static final int EDGEVILLE_HOME_TELEPORT = 98; - } - static class LunarSpellBook { - static final int BOUNTY_TARGET_TELEPORT = 68; + // LUNAR SPELLS static final int LUNAR_HOME_TELEPORT = 99; static final int BAKE_PIE = 100; static final int CURE_PLANT = 101; @@ -912,10 +911,8 @@ static final int WIND_STRIKE = 5; static final int GEOMANCY = 140; static final int SPIN_FLAX = 141; static final int OURANIA_TELEPORT = 142; - } - static class ArceuusSpellBook - { + // ARCEUUS SPELLS static final int ARCEUUS_HOME_TELEPORT = 143; } 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 5c4edd1ca4..eecfeb5404 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 @@ -263,6 +263,7 @@ public enum WidgetInfo RESIZABLE_VIEWPORT_BOTTOM_LINE_EQUIPMENT_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.EQUIP_ICON), RESIZABLE_VIEWPORT_BOTTOM_LINE_COMBAT_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.CMB_ICON), RESIZABLE_VIEWPORT_BOTTOM_LINE_STATS_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.SKILLS_ICON), + RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_TAB(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.MAGIC_TAB), RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.MAGIC_ICON), RESIZABLE_VIEWPORT_BOTTOM_LINE_FRIEND_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.FRIEND_ICON), RESIZABLE_VIEWPORT_BOTTOM_LINE_FRIEND_CHAT_ICON(WidgetID.RESIZABLE_VIEWPORT_BOTTOM_LINE_GROUP_ID, WidgetID.ResizableViewportBottomLine.FC_ICON), @@ -485,54 +486,55 @@ public enum WidgetInfo PVP_BOUNTY_HUNTER_INFO(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.BOUNTY_HUNTER_INFO), PVP_KILLDEATH_COUNTER(WidgetID.PVP_GROUP_ID, WidgetID.Pvp.KILLDEATH_RATIO), + SPELLBOOK_FILTERED_BOUNDS(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FILTERED_SPELLS_BOUNDS), /* STANDARD SPELL BOOK WIDGETS*/ - SPELL_LUMBRIDGE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.LUMBRIDGE_HOME_TELEPORT), - SPELL_BIND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.BIND), - SPELL_SNARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.SNARE), - SPELL_ENTANGLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.ENTANGLE), - SPELL_TELE_BLOCK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.TELE_BLOCK), - SPELL_FIRE_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.FIRE_SURGE), - SPELL_BOUNTY_TARGET_TELEPORT2(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.StandardSpellBook.BOUNTY_TARGET_TELEPORT), + SPELL_LUMBRIDGE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LUMBRIDGE_HOME_TELEPORT), + SPELL_BIND(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BIND), + SPELL_SNARE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SNARE), + SPELL_ENTANGLE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ENTANGLE), + SPELL_TELE_BLOCK(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.TELE_BLOCK), + SPELL_FIRE_SURGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.FIRE_SURGE), + SPELL_BOUNTY_TARGET_TELEPORT2(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), /* END OF STANDARD SPELL BOOK WIDGETS*/ /* LUNAR SPELL BOOK WIDGETS*/ - SPELL_LUNAR_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.LUNAR_HOME_TELEPORT), - SPELL_VENGEANCE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.VENGEANCE_OTHER), - SPELL_VENGEANCE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.VENGEANCE), - SPELL_BOUNTY_TARGET_TELEPORT3(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.LunarSpellBook.BOUNTY_TARGET_TELEPORT), + SPELL_LUNAR_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LUNAR_HOME_TELEPORT), + SPELL_VENGEANCE_OTHER(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VENGEANCE_OTHER), + SPELL_VENGEANCE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.VENGEANCE), + SPELL_BOUNTY_TARGET_TELEPORT3(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), /* LUNA SPELL BOOK WIDGETS*/ /* ARCEUUS SPELL BOOK WIDGETS*/ - SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.ArceuusSpellBook.ARCEUUS_HOME_TELEPORT), + SPELL_ARCEUUS_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ARCEUUS_HOME_TELEPORT), /* END OF ARCEUUS SPELL BOOK WIDGETS*/ /* ANCIENT SPELL BOOK WIDGETS*/ - SPELL_ICE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_RUSH), - SPELL_ICE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BLITZ), - SPELL_ICE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BURST), - SPELL_ICE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ICE_BARRAGE), - SPELL_BLOOD_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_RUSH), - SPELL_BLOOD_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BLITZ), - SPELL_BLOOD_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BURST), - SPELL_BLOOD_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BLOOD_BARRAGE), - SPELL_SMOKE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_RUSH), - SPELL_SMOKE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BLITZ), - SPELL_SMOKE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BURST), - SPELL_SMOKE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SMOKE_BARRAGE), - SPELL_SHADOW_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_RUSH), - SPELL_SHADOW_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BLITZ), - SPELL_SHADOW_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BURST), - SPELL_SHADOW_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SHADOW_BARRAGE), - SPELL_PADDEWWA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.PADDEWWA_TELEPORT), - SPELL_SENNTISTEN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.SENNTISTEN_TELEPORT), - SPELL_KHARYRLL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.KHARYRLL_TELEPORT), - SPELL_LASSAR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.LASSAR_TELEPORT), - SPELL_DAREEYAK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.DAREEYAK_TELEPORT), - SPELL_CARRALLANGER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.CARRALLANGER_TELEPORT), - SPELL_ANNAKARL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.ANNAKARL_TELEPORT), - SPELL_GHORROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.GHORROCK_TELEPORT), - SPELL_EDGEVILLE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.EDGEVILLE_HOME_TELEPORT), - SPELL_BOUNTY_TARGET_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.AncientSpellBook.BOUNTY_TARGET_TELEPORT), + SPELL_ICE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_RUSH), + SPELL_ICE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BLITZ), + SPELL_ICE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BURST), + SPELL_ICE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ICE_BARRAGE), + SPELL_BLOOD_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_RUSH), + SPELL_BLOOD_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BLITZ), + SPELL_BLOOD_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BURST), + SPELL_BLOOD_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BLOOD_BARRAGE), + SPELL_SMOKE_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_RUSH), + SPELL_SMOKE_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BLITZ), + SPELL_SMOKE_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BURST), + SPELL_SMOKE_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SMOKE_BARRAGE), + SPELL_SHADOW_RUSH(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_RUSH), + SPELL_SHADOW_BLITZ(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BLITZ), + SPELL_SHADOW_BURST(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BURST), + SPELL_SHADOW_BARRAGE(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SHADOW_BARRAGE), + SPELL_PADDEWWA_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.PADDEWWA_TELEPORT), + SPELL_SENNTISTEN_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.SENNTISTEN_TELEPORT), + SPELL_KHARYRLL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.KHARYRLL_TELEPORT), + SPELL_LASSAR_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.LASSAR_TELEPORT), + SPELL_DAREEYAK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.DAREEYAK_TELEPORT), + SPELL_CARRALLANGER_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.CARRALLANGER_TELEPORT), + SPELL_ANNAKARL_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.ANNAKARL_TELEPORT), + SPELL_GHORROCK_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.GHORROCK_TELEPORT), + SPELL_EDGEVILLE_HOME_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.EDGEVILLE_HOME_TELEPORT), + SPELL_BOUNTY_TARGET_TELEPORT(WidgetID.SPELLBOOK_GROUP_ID, WidgetID.SpellBook.BOUNTY_TARGET_TELEPORT), /* END OF ANCIENT SPELL BOOK WIDGETS*/ diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spell.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spell.java new file mode 100644 index 0000000000..753c64e0de --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spell.java @@ -0,0 +1,14 @@ +package net.runelite.client.plugins.spellbook; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode +class Spell +{ + private int widget; + private int x; + private int y; + private String name; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spellbook.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spellbook.java new file mode 100644 index 0000000000..6d29000f4b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/Spellbook.java @@ -0,0 +1,36 @@ +package net.runelite.client.plugins.spellbook; + +import java.util.HashMap; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum Spellbook +{ + STANDARD(0, "standard"), + ANCIENT(1, "ancient"), + LUNAR(2, "lunar"), + ARCEUUS(3, "arceuus"); + + @Getter + private final int id; + + @Getter + private final String configKey; + + private static final Map map = new HashMap<>(); + + static + { + for (Spellbook s : values()) + { + map.put(s.id, s); + } + } + + public static Spellbook getByID(int id) + { + return map.get(id); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java new file mode 100644 index 0000000000..4a767ea1e7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookConfig.java @@ -0,0 +1,116 @@ +package net.runelite.client.plugins.spellbook; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("spellbook") +public interface SpellbookConfig extends Config +{ + @ConfigItem( + keyName = "enableMobile", + name = "Mobile spellbook", + description = "Show the mobile spellbook with filtered spells enabled", + position = 1 + ) + default boolean enableMobile() + { + return true; + } + + @ConfigItem( + keyName = "dragSpells", + name = "Change spell location", + description = "Add menu entry to spellbook which toggles moving spells by dragging. Only works with spells filtered", + position = 2 + ) + default boolean dragSpells() + { + return true; + } + + @ConfigItem( + keyName = "size", + name = "Spell size", + description = "Size (in px) of spells. Normal mobile size is 40px, use common sense for this setting please", + position = 3 + ) + default int size() + { + return 40; + } + + @ConfigItem( + keyName = "filter", + name = "Unfiltered spells", + description = "Spells you don't want to filter, seperated with a comma" + ) + default String filter() + { + return ""; + } + + @ConfigItem( + keyName = "standard", + name = "", + description = "", + hidden = true + ) + default String standard() + { + return ""; + } + + + @ConfigItem( + keyName = "ancient", + name = "", + description = "", + hidden = true + ) + default String ancient() + { + return ""; + } + + @ConfigItem( + keyName = "lunar", + name = "", + description = "", + hidden = true + ) + default String lunar() + { + return ""; + } + + @ConfigItem( + keyName = "arceuus", + name = "", + description = "", + hidden = true + ) + default String arceuus() + { + return ""; + } + + @ConfigItem( + keyName = "canDrag", + name = "", + description = "", + hidden = true + ) + default boolean canDrag() + { + return false; + } + + @ConfigItem( + keyName = "canDrag", + name = "", + description = "", + hidden = true + ) + void canDrag(boolean canDrag); +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookDragOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookDragOverlay.java new file mode 100644 index 0000000000..bc94a815c1 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookDragOverlay.java @@ -0,0 +1,57 @@ +package net.runelite.client.plugins.spellbook; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import javax.inject.Inject; +import javax.inject.Singleton; +import net.runelite.api.Client; +import net.runelite.client.game.SpriteManager; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; + +@Singleton +public class SpellbookDragOverlay extends Overlay +{ + private SpellbookPlugin plugin; + private Client client; + private SpriteManager spriteManager; + + @Inject + private SpellbookDragOverlay(SpellbookPlugin plugin, Client client, SpriteManager spriteManager) + { + this.plugin = plugin; + this.client = client; + this.spriteManager = spriteManager; + setPosition(OverlayPosition.TOOLTIP); + setPriority(OverlayPriority.HIGHEST); + setLayer(OverlayLayer.ALWAYS_ON_TOP); + } + + @Override + public Dimension render(Graphics2D g) + { + if (!plugin.isDragging()) + { + return null; + } + + final net.runelite.api.Point mouseCanvasPosition = client.getMouseCanvasPosition(); + final net.runelite.api.Point draggingLocation = plugin.getDraggingLocation(); + + final int size = plugin.getDraggingWidget().getWidth(); + final int sprite = plugin.getDraggingWidget().getSpriteId(); + final BufferedImage image = spriteManager.getSprite(sprite, 0); + + final Point mousePosition = new Point(mouseCanvasPosition.getX() - draggingLocation.getX(), mouseCanvasPosition.getY() - draggingLocation.getY()); + final Rectangle bounds = new Rectangle(mousePosition.x, mousePosition.y, size, size); + + g.drawImage(image, mousePosition.x, mousePosition.y, size, size, null); + + return bounds.getSize(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookMouseListener.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookMouseListener.java new file mode 100644 index 0000000000..3d0c59a1f6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookMouseListener.java @@ -0,0 +1,55 @@ +package net.runelite.client.plugins.spellbook; + +import java.awt.event.MouseEvent; +import javax.swing.SwingUtilities; +import net.runelite.client.input.MouseAdapter; + +public class SpellbookMouseListener extends MouseAdapter +{ + private final SpellbookPlugin plugin; + + SpellbookMouseListener(SpellbookPlugin plugin) + { + this.plugin = plugin; + } + + @Override + public MouseEvent mouseClicked(MouseEvent event) + { + if (SwingUtilities.isMiddleMouseButton(event) || !plugin.isOnSpellWidget(event.getPoint())) + { + return event; + } + + event.consume(); + return event; + } + + @Override + public MouseEvent mousePressed(MouseEvent event) + { + if (!SwingUtilities.isLeftMouseButton(event) || !plugin.isOnSpellWidget(event.getPoint()) || plugin.isDragging()) + { + return event; + } + + plugin.startDragging(event.getPoint()); + + event.consume(); + return event; + } + + @Override + public MouseEvent mouseReleased(MouseEvent event) + { + if (!SwingUtilities.isLeftMouseButton(event) || !plugin.isDragging()) + { + return event; + } + + plugin.completeDragging(event.getPoint()); + + event.consume(); + return event; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java new file mode 100644 index 0000000000..17d4e14601 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/spellbook/SpellbookPlugin.java @@ -0,0 +1,449 @@ +package net.runelite.client.plugins.spellbook; + +import com.google.common.base.Strings; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.google.inject.Provides; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import javax.inject.Inject; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.api.Point; +import net.runelite.api.Varbits; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.ScriptCallbackEvent; +import net.runelite.api.events.VarbitChanged; +import net.runelite.api.events.WidgetMenuOptionClicked; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.input.MouseManager; +import net.runelite.client.menus.MenuManager; +import net.runelite.client.menus.WidgetMenuOption; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.Text; + +@PluginDescriptor( + name = "Spellbook", + description = "Modifications to the spellbook", + tags = {"resize", "spell", "mobile", "lowers", "pvp", "skill", "level"} +) +@Slf4j +public class SpellbookPlugin extends Plugin +{ + private static final int FULL_WIDTH = 184; + private static final int FULL_HEIGHT = 240; + private static final Gson GSON = new Gson(); + private static final String LOCK = "Disable"; + private static final String UNLOCK = "Enable"; + private static final String MENU_TARGET = "Reordering"; + private static final WidgetMenuOption FIXED_MAGIC_TAB_LOCK = new WidgetMenuOption(LOCK, MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_MAGIC_TAB); + private static final WidgetMenuOption FIXED_MAGIC_TAB_UNLOCK = new WidgetMenuOption(UNLOCK, MENU_TARGET, WidgetInfo.FIXED_VIEWPORT_MAGIC_TAB); + private static final WidgetMenuOption RESIZABLE_MAGIC_TAB_LOCK = new WidgetMenuOption(LOCK, MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_MAGIC_TAB); + private static final WidgetMenuOption RESIZABLE_MAGIC_TAB_UNLOCK = new WidgetMenuOption(UNLOCK, MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_MAGIC_TAB); + private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_MAGIC_TAB_LOCK = new WidgetMenuOption(LOCK, MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_TAB); + private static final WidgetMenuOption RESIZABLE_BOTTOM_LINE_MAGIC_TAB_UNLOCK = new WidgetMenuOption(UNLOCK, MENU_TARGET, WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_TAB); + + @Inject + private Client client; + + @Inject + private ClientThread clientThread; + + @Inject + private ConfigManager configManager; + + @Inject + private SpellbookConfig config; + + @Inject + private MenuManager menuManager; + + @Inject + private MouseManager mouseManager; + + @Inject + private OverlayManager overlayManager; + + @Inject + private SpellbookDragOverlay overlay; + + @Getter + private boolean dragging; + + @Getter + private Widget draggingWidget; + + @Getter + private Point draggingLocation; + + private Map spells = new HashMap<>(); + private List notFilteredSpells = new ArrayList<>(); + private Spellbook spellbook; + private SpellbookMouseListener mouseListener; + + + @Provides + SpellbookConfig getConfig(ConfigManager configManager) + { + return configManager.getConfig(SpellbookConfig.class); + } + + @Override + protected void startUp() + { + refreshMagicTabOption(); + loadFilter(); + mouseListener = new SpellbookMouseListener(this); + } + + @Override + protected void shutDown() + { + clearMagicTabMenus(); + saveSpells(); + config.canDrag(false); + mouseListener = null; + } + + @Subscribe + public void onGameStateChanged(GameStateChanged event) + { + if (event.getGameState() == GameState.LOGGED_IN) + { + refreshMagicTabOption(); + } + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (!"spellbook".equals(event.getGroup())) + { + return; + } + + String key = event.getKey(); + + if ("canDrag".equals(key)) + { + refreshMagicTabOption(); + } + else if ("filter".equals(key)) + { + loadFilter(); + } + + runRebuild(); + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + if (client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + if (config.canDrag()) + { + config.canDrag(client.getVar(Varbits.FILTER_SPELLBOOK) == 1); + } + } + + @Subscribe + public void onScriptCallbackEvent(ScriptCallbackEvent event) + { + if (client.getVar(Varbits.FILTER_SPELLBOOK) != 0 || !config.enableMobile() || !event.getEventName().toLowerCase().contains("spell")) + { + return; + } + + int[] iStack = client.getIntStack(); + int iStackSize = client.getIntStackSize(); + + String[] sStack = client.getStringStack(); + int sStackSize = client.getStringStackSize(); + + if ("shouldFilterSpell".equals(event.getEventName())) + { + String spell = sStack[sStackSize - 1].toLowerCase(); + int widget = iStack[iStackSize - 1]; + + spellbook = Spellbook.getByID(client.getVar(Varbits.SPELLBOOK)); + loadSpells(); + + // Add the spell to spells + if (!spells.containsKey(widget)) + { + Spell s = new Spell(); + s.setWidget(widget); + s.setX(-1); + s.setY(-1); + s.setName(spell); + + spells.put(widget, s); + } + + if (notFilteredSpells.isEmpty()) + { + return; + } + + iStack[iStackSize - 2] = notFilteredSpells.stream().anyMatch(spell::contains) ? 1 : 0; + } + else if ("isMobileSpellbookEnabled".equals(event.getEventName())) + { + iStack[iStackSize - 1] = 1; + } + else if ("resizeSpell".equals(event.getEventName())) + { + int size = config.size(); + int columns = Math.max(2, Math.min(FULL_WIDTH / size, 3)); + + iStack[iStackSize - 1] = columns; + iStack[iStackSize - 2] = size; + } + else if ("setSpellAreaSize".equals(event.getEventName())) + { + if (!config.dragSpells()) + { + return; + } + + iStack[iStackSize - 1] = FULL_HEIGHT; + iStack[iStackSize - 2] = FULL_WIDTH; + } + else if ("setSpellPosition".equals(event.getEventName())) + { + if (!config.dragSpells()) + { + return; + } + + int widget = iStack[iStackSize - 1]; + Spell s = spells.get(widget); + int x = s.getX(); + int y = s.getY(); + + if (x == -1) + { + return; + } + + iStack[iStackSize - 5] = x; + iStack[iStackSize - 4] = y; + } + } + + + @Subscribe + public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event) + { + if (event.getWidget() != WidgetInfo.FIXED_VIEWPORT_MAGIC_TAB + && event.getWidget() != WidgetInfo.RESIZABLE_VIEWPORT_MAGIC_TAB + && event.getWidget() != WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE_MAGIC_TAB) + { + return; + } + + if (event.getMenuOption().equals(UNLOCK)) + { + config.canDrag(true); + overlayManager.add(overlay); + mouseManager.registerMouseListener(mouseListener); + } + else if (event.getMenuOption().equals(LOCK)) + { + config.canDrag(false); + overlayManager.remove(overlay); + mouseManager.unregisterMouseListener(mouseListener); + } + } + + private void clearMagicTabMenus() + { + menuManager.removeManagedCustomMenu(FIXED_MAGIC_TAB_LOCK); + menuManager.removeManagedCustomMenu(RESIZABLE_MAGIC_TAB_LOCK); + menuManager.removeManagedCustomMenu(RESIZABLE_BOTTOM_LINE_MAGIC_TAB_LOCK); + menuManager.removeManagedCustomMenu(FIXED_MAGIC_TAB_UNLOCK); + menuManager.removeManagedCustomMenu(RESIZABLE_MAGIC_TAB_UNLOCK); + menuManager.removeManagedCustomMenu(RESIZABLE_BOTTOM_LINE_MAGIC_TAB_UNLOCK); + } + + private void refreshMagicTabOption() + { + clearMagicTabMenus(); + if (client.getGameState() != GameState.LOGGED_IN || !config.dragSpells()) + { + return; + } + + if (config.canDrag()) + { + menuManager.addManagedCustomMenu(FIXED_MAGIC_TAB_LOCK); + menuManager.addManagedCustomMenu(RESIZABLE_MAGIC_TAB_LOCK); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_MAGIC_TAB_LOCK); + } + else + { + menuManager.addManagedCustomMenu(FIXED_MAGIC_TAB_UNLOCK); + menuManager.addManagedCustomMenu(RESIZABLE_MAGIC_TAB_UNLOCK); + menuManager.addManagedCustomMenu(RESIZABLE_BOTTOM_LINE_MAGIC_TAB_UNLOCK); + } + } + + private void loadFilter() + { + notFilteredSpells.clear(); + notFilteredSpells.addAll(Text.fromCSV(config.filter().toLowerCase())); + } + + private void loadSpells() + { + if (client.getGameState() != GameState.LOGGED_IN || spellbook == null) + { + return; + } + spells.clear(); + String cfg = configManager.getConfiguration("spellbook", spellbook.getConfigKey()); + + if (Strings.isNullOrEmpty(cfg)) + { + return; + } + // CHECKSTYLE:OFF + Collection gson = GSON.fromJson(cfg, new TypeToken>(){}.getType()); + // CHECKSTYLE:ON + gson.stream().filter(Objects::nonNull).forEach(s -> spells.put(s.getWidget(), s)); + } + + private void saveSpells() + { + if (spells.isEmpty()) + { + return; + } + + String key = spellbook.getConfigKey(); + + configManager.setConfiguration("spellbook", key, GSON.toJson(spells.values())); + } + + private void runRebuild() + { + if (client.getGameState() != GameState.LOGGED_IN) + { + return; + } + + // Runs magic_spellbook_rebuild + clientThread.invoke(() -> + client.runScript(2611, 14286851, 14287027, 14287036, 14286849, 14287033, 14287034, 14287035, 14286850, 14287029, 14287032, "Info", "Filters", false) + ); + } + + boolean isOnSpellWidget(java.awt.Point point) + { + Widget boundsWidget = client.getWidget(WidgetInfo.SPELLBOOK_FILTERED_BOUNDS); + if (boundsWidget == null || !boundsWidget.getBounds().contains(point)) + { + return false; + } + + for (int id : spells.keySet()) + { + Widget w = client.getWidget(WidgetInfo.TO_GROUP(id), WidgetInfo.TO_CHILD(id)); // lol very useful + + if (w == null || notFilteredSpells.stream().noneMatch(spells.get(id).getName()::contains)) + { + continue; + } + + if (w.getBounds().contains(point)) + { + return true; + } + } + + return false; + } + + void startDragging(java.awt.Point point) + { + for (int id : spells.keySet()) + { + Widget w = client.getWidget(WidgetInfo.TO_GROUP(id), WidgetInfo.TO_CHILD(id)); // y tho let me just plop in id + + if (w == null || !w.getBounds().contains(point) || notFilteredSpells.stream().noneMatch(spells.get(id).getName()::contains)) + { + continue; + } + + draggingWidget = w; + break; + } + + Point widgetPos = draggingWidget.getCanvasLocation(); + + int x = point.x - widgetPos.getX(); + int y = point.y - widgetPos.getY(); + + draggingLocation = new Point(x, y); + draggingWidget.setHidden(true); + dragging = true; + } + + void completeDragging(java.awt.Point point) + { + Point parentPos = client.getWidget(WidgetInfo.SPELLBOOK_FILTERED_BOUNDS).getCanvasLocation(); + + int x = point.x - draggingLocation.getX() - parentPos.getX(); + int y = point.y - draggingLocation.getY() - parentPos.getY(); + int size = config.size(); + + if (x < 0) + { + x = 0; + } + else if (x > FULL_WIDTH - size) + { + x = FULL_WIDTH - size; + } + + if (y < 0) + { + y = 0; + } + else if (y > FULL_HEIGHT - size) + { + y = FULL_HEIGHT - size; + } + + int draggedID = draggingWidget.getId(); + + Spell n = spells.get(draggedID); + + n.setX(x); + n.setY(y); + + spells.replace(draggedID, n); + + draggingWidget.setHidden(false); + dragging = false; + + saveSpells(); + } +} diff --git a/runelite-client/src/main/scripts/MagicSpellBookRedraw.rs2asm b/runelite-client/src/main/scripts/MagicSpellBookRedraw.rs2asm index 3736e0ac73..c0068962db 100644 --- a/runelite-client/src/main/scripts/MagicSpellBookRedraw.rs2asm +++ b/runelite-client/src/main/scripts/MagicSpellBookRedraw.rs2asm @@ -272,6 +272,21 @@ LABEL239: iload 17 invoke 2619 iconst 1 + if_icmpeq FILTER_SPELL + jump LABEL263 +FILTER_SPELL: + iconst 1 ; boolean the callback modifies + iload 17 + iconst 596 ; widgetID, to populate config + oc_param + iload 17 + iconst 601 ; spell_name + oc_param ; look up from object composition + sconst "shouldFilterSpell" + runelite_callback + pop_string ; pop the name + pop_int ; and the widgetID + iconst 1 ; default true, so the script still functions without plugin on if_icmpeq LABEL250 jump LABEL263 LABEL250: @@ -360,7 +375,9 @@ LABEL316: istore 23 iload 12 istore 24 - iload 10 + iconst 0 + sconst "isMobileSpellbookEnabled" + runelite_callback iconst 1 if_icmpeq LABEL332 jump LABEL422 @@ -372,6 +389,8 @@ LABEL332: LABEL336: iconst 40 iconst 3 + sconst "resizeSpell" + runelite_callback istore 20 istore 19 jump LABEL360 @@ -640,9 +659,11 @@ LABEL577: iconst 1 sub iload 23 - multiply - add - iload 24 + multiply + add ; start of the label until here calcs total width + iload 24 ; total height + sconst "setSpellAreaSize" + runelite_callback iconst 0 iconst 0 iload 0 @@ -703,7 +724,9 @@ LABEL611: iconst 0 iconst 0 iload 25 - if_setposition + sconst "setSpellPosition" + runelite_callback + if_setposition iload 17 iload 25 invoke 2614