Merge branch 'master' of https://github.com/runelite/runelite into runelite-master

This commit is contained in:
zeruth
2019-06-21 03:32:14 -04:00
72 changed files with 2852 additions and 491 deletions
@@ -1503,14 +1503,6 @@ public interface Client extends GameShell
*/
NodeCache getWidgetSpriteCache();
/**
* Overrides health bar sprites with the sprites from the specified override.
* Pass in {@code null} to revert the health bars back to their default.
*
* @param override the health bar override
*/
void setHealthBarOverride(HealthBarOverride override);
/**
* Gets the current server tick count.
*
@@ -1663,4 +1655,6 @@ public interface Client extends GameShell
String getSelectedSpellName();
boolean getIsSpellSelected();
void resetHealthBarCaches();
}
@@ -102,4 +102,21 @@ public class Constants
* Used when getting High Alchemy value - multiplied by general store price.
*/
public static final float HIGH_ALCHEMY_CONSTANT = 0.6f;
/**
* Width of a standard item sprite
*/
public static final int ITEM_SPRITE_WIDTH = 36;
/**
* Height of a standard item sprite
*/
public static final int ITEM_SPRITE_HEIGHT = 32;
/**
* High alchemy = shop price * HIGH_ALCHEMY_MULTIPLIER
*
* @see ItemComposition#getPrice
*/
public static final float HIGH_ALCHEMY_MULTIPLIER = .6f;
}
@@ -30,5 +30,7 @@ public interface HealthBar
Sprite getHealthBarBackSprite();
int getHealthBarFrontSpriteId();
void setPadding(int padding);
}
@@ -1,37 +0,0 @@
/*
* Copyright (c) 2019, Lotto <https://github.com/devLotto>
* 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 HOLDER 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.Data;
@Data
public class HealthBarOverride
{
public final Sprite frontSprite;
public final Sprite backSprite;
public final Sprite frontSpriteLarge;
public final Sprite backSpriteLarge;
}
@@ -63,6 +63,8 @@ public interface ItemDefinition
* alchemy values, respectively.
*
* @return the general store value of the item
*
* @see Constants#HIGH_ALCHEMY_MULTIPLIER
*/
int getPrice();
@@ -10791,5 +10791,35 @@ public final class ItemID
public static final int TORMENTED_BRACELET_OR = 23444;
public static final int GIANT_EASTER_EGG = 23446;
public static final int BUNNYMAN_MASK = 23448;
public static final int ENCHANTED_LYREI = 23458;
public static final int ATTACKER_ICON_23460 = 23460;
public static final int ATTACKER_ICON_23461 = 23461;
public static final int ATTACKER_ICON_23462 = 23462;
public static final int ATTACKER_ICON_23463 = 23463;
public static final int ATTACKER_ICON_23464 = 23464;
public static final int ATTACKER_ICON_23465 = 23465;
public static final int DEFENDER_ICON_23466 = 23466;
public static final int DEFENDER_ICON_23467 = 23467;
public static final int DEFENDER_ICON_23468 = 23468;
public static final int DEFENDER_ICON_23469 = 23469;
public static final int DEFENDER_ICON_23470 = 23470;
public static final int COLLECTOR_ICON_23471 = 23471;
public static final int COLLECTOR_ICON_23472 = 23472;
public static final int COLLECTOR_ICON_23473 = 23473;
public static final int COLLECTOR_ICON_23474 = 23474;
public static final int COLLECTOR_ICON_23475 = 23475;
public static final int COLLECTOR_ICON_23476 = 23476;
public static final int COLLECTOR_ICON_23477 = 23477;
public static final int HEALER_ICON_23478 = 23478;
public static final int HEALER_ICON_23479 = 23479;
public static final int HEALER_ICON_23480 = 23480;
public static final int HEALER_ICON_23481 = 23481;
public static final int HEALER_ICON_23482 = 23482;
public static final int HEALER_ICON_23483 = 23483;
public static final int HEALER_ICON_23484 = 23484;
public static final int HEALER_ICON_23485 = 23485;
public static final int HEALER_ICON_23486 = 23486;
public static final int WINE_OF_ZAMORAK_23489 = 23489;
public static final int LARRANS_KEY = 23490;
/* This file is automatically generated. Do not edit. */
}
@@ -460,10 +460,9 @@ public final class NpcID
public static final int SKELETAL_WYVERN_468 = 468;
public static final int KILLERWATT = 469;
public static final int KILLERWATT_470 = 470;
public static final int FUNGI = 471;
public static final int FUNGI_472 = 472;
public static final int ZYGOMITE = 473;
public static final int ZYGOMITE_474 = 474;
public static final int DARK_WIZARD = 472;
public static final int INVRIGAR_THE_NECROMANCER = 473;
public static final int DARK_WIZARD_474 = 474;
public static final int HOLE_IN_THE_WALL = 475;
public static final int WALL_BEAST = 476;
public static final int GIANT_FROG = 477;
@@ -493,40 +492,37 @@ public final class NpcID
public static final int VANESSA = 502;
public static final int RICHARD = 503;
public static final int ALICE = 504;
public static final int BOB = 505;
public static final int SHOP_KEEPER = 506;
public static final int SHOP_ASSISTANT = 507;
public static final int SHOP_KEEPER_508 = 508;
public static final int SHOP_ASSISTANT_509 = 509;
public static final int SHOP_KEEPER_510 = 510;
public static final int SHOP_ASSISTANT_511 = 511;
public static final int SHOP_KEEPER_512 = 512;
public static final int SHOP_ASSISTANT_513 = 513;
public static final int SHOP_KEEPER_514 = 514;
public static final int SHOP_ASSISTANT_515 = 515;
public static final int SHOP_KEEPER_516 = 516;
public static final int SHOP_ASSISTANT_517 = 517;
public static final int SHOP_KEEPER_518 = 518;
public static final int SHOP_ASSISTANT_519 = 519;
public static final int FAIRY_SHOP_KEEPER = 520;
public static final int FAIRY_SHOP_ASSISTANT = 521;
public static final int VALAINE = 522;
public static final int SCAVVO = 523;
public static final int PEKSA = 524;
public static final int SILK_TRADER = 525;
public static final int GEM_TRADER = 526;
public static final int ZEKE = 527;
public static final int LOUIE_LEGS = 528;
public static final int KARIM = 529;
public static final int RANAEL = 530;
public static final int DOMMIK = 531;
public static final int ZAFF = 532;
public static final int BARAEK = 533;
public static final int MUGGER = 505;
public static final int WITCH = 506;
public static final int WITCH_507 = 507;
public static final int BLACK_KNIGHT = 508;
public static final int BLACK_KNIGHT_509 = 509;
public static final int HIGHWAYMAN = 510;
public static final int HIGHWAYMAN_511 = 511;
public static final int CHAOS_DRUID = 512;
public static final int PIRATE = 513;
public static final int PIRATE_514 = 514;
public static final int PIRATE_515 = 515;
public static final int PIRATE_516 = 516;
public static final int THUG = 517;
public static final int ROGUE = 518;
public static final int MONK_OF_ZAMORAK = 519;
public static final int MONK_OF_ZAMORAK_520 = 520;
public static final int MONK_OF_ZAMORAK_521 = 521;
public static final int TRIBESMAN = 522;
public static final int DARK_WARRIOR = 523;
public static final int CHAOS_DRUID_WARRIOR = 524;
public static final int NECROMANCER = 525;
public static final int BANDIT = 526;
public static final int GUARD_BANDIT = 527;
public static final int BARBARIAN_GUARD = 528;
public static final int PORTAL = 530;
public static final int PORTAL_532 = 532;
public static final int FUNGI = 533;
public static final int THESSALIA = 534;
public static final int HORVIK = 535;
public static final int LOWE = 536;
public static final int SHOP_KEEPER_537 = 537;
public static final int SHOP_ASSISTANT_538 = 538;
public static final int FUNGI_535 = 535;
public static final int ZYGOMITE = 537;
public static final int FUNGI_538 = 538;
public static final int ELFINLOCKS = 539;
public static final int CLOCKWORK_CAT = 540;
public static final int CLOCKWORK_CAT_541 = 541;
@@ -625,7 +621,7 @@ public final class NpcID
public static final int BREWER_634 = 634;
public static final int FISHING_SPOT = 635;
public static final int KARAMTHULHU = 636;
public static final int AUBURY = 637;
public static final int FUNGI_637 = 637;
public static final int ELF_TRACKER = 638;
public static final int TYRAS_GUARD = 639;
public static final int UG = 640;
@@ -678,7 +674,7 @@ public final class NpcID
public static final int BARTENDER = 687;
public static final int EBLIS = 688;
public static final int EBLIS_689 = 689;
public static final int BANDIT = 690;
public static final int BANDIT_690 = 690;
public static final int BANDIT_691 = 691;
public static final int BANDIT_692 = 692;
public static final int BANDIT_693 = 693;
@@ -992,37 +988,34 @@ public final class NpcID
public static final int RAT = 1020;
public static final int RAT_1021 = 1021;
public static final int RAT_1022 = 1022;
public static final int FANCY_DRESS_SHOP_OWNER = 1023;
public static final int SHOP_KEEPER_1024 = 1024;
public static final int GRUM = 1025;
public static final int WYDIN = 1026;
public static final int GERRANT = 1027;
public static final int BRIAN = 1028;
public static final int JIMINUA = 1029;
public static final int SHOP_KEEPER_1030 = 1030;
public static final int CANDLE_MAKER = 1031;
public static final int ARHEIN = 1032;
public static final int JUKAT = 1033;
public static final int LUNDERWIN = 1034;
public static final int IRKSOL = 1035;
public static final int FAIRY = 1036;
public static final int ZAMBO = 1037;
public static final int SILVER_MERCHANT = 1038;
public static final int GEM_MERCHANT = 1039;
public static final int BAKER = 1040;
public static final int SPICE_SELLER = 1041;
public static final int FUR_TRADER = 1042;
public static final int SILK_MERCHANT = 1043;
public static final int HICKTON = 1044;
public static final int HARRY = 1045;
public static final int CASSIE = 1046;
public static final int FRINCOS = 1047;
public static final int DROGO_DWARF = 1048;
public static final int FLYNN = 1049;
public static final int WAYNE = 1050;
public static final int DWARF_1051 = 1051;
public static final int BETTY = 1052;
public static final int HERQUIN = 1053;
public static final int ZYGOMITE_1024 = 1024;
public static final int BANKER_1027 = 1027;
public static final int BANKER_1028 = 1028;
public static final int BANKER_1029 = 1029;
public static final int BANKER_1030 = 1030;
public static final int BANKER_1031 = 1031;
public static final int BANKER_1032 = 1032;
public static final int BANKER_1033 = 1033;
public static final int BANKER_1034 = 1034;
public static final int BANKER_1035 = 1035;
public static final int BANKER_1036 = 1036;
public static final int SNAKE = 1037;
public static final int MONKEY_1038 = 1038;
public static final int ALBINO_BAT = 1039;
public static final int CRAB = 1040;
public static final int GIANT_MOSQUITO = 1041;
public static final int JUNGLE_HORROR = 1042;
public static final int JUNGLE_HORROR_1043 = 1043;
public static final int JUNGLE_HORROR_1044 = 1044;
public static final int JUNGLE_HORROR_1045 = 1045;
public static final int JUNGLE_HORROR_1046 = 1046;
public static final int CAVE_HORROR = 1047;
public static final int CAVE_HORROR_1048 = 1048;
public static final int CAVE_HORROR_1049 = 1049;
public static final int CAVE_HORROR_1050 = 1050;
public static final int CAVE_HORROR_1051 = 1051;
public static final int CAVEY_DAVEY = 1052;
public static final int PATCHY = 1053;
public static final int LAUNA = 1054;
public static final int LAUNA_1055 = 1055;
public static final int BRANA = 1056;
@@ -1134,13 +1127,12 @@ public final class NpcID
public static final int MONK_OF_ENTRANA_1169 = 1169;
public static final int MONK_OF_ENTRANA_1170 = 1170;
public static final int MONK_1171 = 1171;
public static final int ROMMIK = 1172;
public static final int GAIUS = 1173;
public static final int JATIX = 1174;
public static final int DAVON = 1175;
public static final int ZENESHA = 1176;
public static final int AEMAD = 1177;
public static final int KORTAN = 1178;
public static final int CHICKEN = 1173;
public static final int CHICKEN_1174 = 1174;
public static final int ROOSTER = 1175;
public static final int LIL_LAMB = 1176;
public static final int LAMB = 1177;
public static final int SHEEP_1178 = 1178;
public static final int LUMBRIDGE_GUIDE_1179 = 1179;
public static final int LUMBRIDGE_GUIDE_1181 = 1181;
public static final int ___ = 1182;
@@ -1252,17 +1244,17 @@ public final class NpcID
public static final int MORTTON_LOCAL_1296 = 1296;
public static final int AFFLICTED_1297 = 1297;
public static final int AFFLICTED_1298 = 1298;
public static final int ROACHEY = 1299;
public static final int FRENITA = 1300;
public static final int NURMOF = 1301;
public static final int TEA_SELLER = 1302;
public static final int FAT_TONY = 1303;
public static final int NOTERAZZO = 1304;
public static final int SHEEP_1299 = 1299;
public static final int SHEEP_1300 = 1300;
public static final int SHEEP_1301 = 1301;
public static final int SHEEP_1302 = 1302;
public static final int SHEEP_1303 = 1303;
public static final int SHEEP_1304 = 1304;
public static final int HAIRDRESSER = 1305;
public static final int MAKEOVER_MAGE = 1306;
public static final int MAKEOVER_MAGE_1307 = 1307;
public static final int DIANGO = 1308;
public static final int BRIAN_1309 = 1309;
public static final int SHEEP_1308 = 1308;
public static final int SHEEP_1309 = 1309;
public static final int BARTENDER_1310 = 1310;
public static final int BARTENDER_1311 = 1311;
public static final int BARTENDER_1312 = 1312;
@@ -1392,12 +1384,12 @@ public final class NpcID
public static final int DAERO = 1444;
public static final int DAERO_1445 = 1445;
public static final int WAYDAR = 1446;
public static final int PIRATE = 1447;
public static final int PIRATE_1447 = 1447;
public static final int THIEF = 1448;
public static final int LUMDO_1453 = 1453;
public static final int LUMDO_1454 = 1454;
public static final int GLO_CARANOCK = 1460;
public static final int MUGGER = 1461;
public static final int MUGGER_1461 = 1461;
public static final int SMALL_NINJA_MONKEY = 1462;
public static final int MEDIUM_NINJA_MONKEY = 1463;
public static final int GORILLA = 1464;
@@ -1478,7 +1470,7 @@ public final class NpcID
public static final int FISHING_SPOT_1542 = 1542;
public static final int GARGOYLE_1543 = 1543;
public static final int FISHING_SPOT_1544 = 1544;
public static final int BLACK_KNIGHT = 1545;
public static final int BLACK_KNIGHT_1545 = 1545;
public static final int GUARD_1546 = 1546;
public static final int GUARD_1547 = 1547;
public static final int GUARD_1548 = 1548;
@@ -1486,7 +1478,7 @@ public final class NpcID
public static final int GUARD_1550 = 1550;
public static final int GUARD_1551 = 1551;
public static final int GUARD_1552 = 1552;
public static final int CRAB = 1553;
public static final int CRAB_1553 = 1553;
public static final int SEAGULL_1554 = 1554;
public static final int SEAGULL_1555 = 1555;
public static final int FIRE_WIZARD = 1556;
@@ -1668,7 +1660,7 @@ public final class NpcID
public static final int BRAWLER_1736 = 1736;
public static final int BRAWLER_1737 = 1737;
public static final int BRAWLER_1738 = 1738;
public static final int PORTAL = 1739;
public static final int PORTAL_1739 = 1739;
public static final int PORTAL_1740 = 1740;
public static final int PORTAL_1741 = 1741;
public static final int PORTAL_1742 = 1742;
@@ -1716,10 +1708,10 @@ public final class NpcID
public static final int SKELETON_1785 = 1785;
public static final int GHOST_1786 = 1786;
public static final int SKELETON_MAGE_1787 = 1787;
public static final int BETTY_1788 = 1788;
public static final int GRUM_1789 = 1789;
public static final int GERRANT_1790 = 1790;
public static final int WYDIN_1791 = 1791;
public static final int BETTY = 1788;
public static final int GRUM = 1789;
public static final int GERRANT = 1790;
public static final int WYDIN = 1791;
public static final int GOAT = 1792;
public static final int GOAT_1793 = 1793;
public static final int BILLY_GOAT = 1794;
@@ -1767,7 +1759,7 @@ public final class NpcID
public static final int STAG = 1845;
public static final int WOOD_DRYAD = 1846;
public static final int FAIRY_VERY_WISE = 1847;
public static final int FAIRY_1848 = 1848;
public static final int FAIRY = 1848;
public static final int FAIRY_1849 = 1849;
public static final int FAIRY_1850 = 1850;
public static final int FAIRY_1851 = 1851;
@@ -1915,7 +1907,7 @@ public final class NpcID
public static final int FRITZ_THE_GLASSBLOWER = 2053;
public static final int CHAOS_ELEMENTAL = 2054;
public static final int CHAOS_ELEMENTAL_JR = 2055;
public static final int DARK_WIZARD = 2056;
public static final int DARK_WIZARD_2056 = 2056;
public static final int DARK_WIZARD_2057 = 2057;
public static final int DARK_WIZARD_2058 = 2058;
public static final int DARK_WIZARD_2059 = 2059;
@@ -2488,7 +2480,7 @@ public final class NpcID
public static final int LILIYA = 2632;
public static final int BANKER_2633 = 2633;
public static final int MYRE_BLAMISH_SNAIL = 2634;
public static final int BOB_2635 = 2635;
public static final int BOB = 2635;
public static final int BOB_2636 = 2636;
public static final int SPHINX = 2637;
public static final int NEITE = 2638;
@@ -2544,11 +2536,12 @@ public final class NpcID
public static final int IMIAGO = 2688;
public static final int LILIWEN = 2689;
public static final int COOL_MOM227 = 2690;
public static final int CHICKEN = 2692;
public static final int CHICKEN_2693 = 2693;
public static final int ROOSTER = 2694;
public static final int LIL_LAMB = 2695;
public static final int LAMB = 2696;
public static final int SHEEP_2691 = 2691;
public static final int SHEEP_2692 = 2692;
public static final int SHEEP_2693 = 2693;
public static final int SHEEP_2694 = 2694;
public static final int SHEEP_2695 = 2695;
public static final int SHEEP_2696 = 2696;
public static final int SHEEP_2697 = 2697;
public static final int SHEEP_2698 = 2698;
public static final int SHEEP_2699 = 2699;
@@ -2642,43 +2635,43 @@ public final class NpcID
public static final int SHEEP_2787 = 2787;
public static final int SHEEP_2788 = 2788;
public static final int SHEEP_2789 = 2789;
public static final int SHEEP_2790 = 2790;
public static final int SHEEP_2791 = 2791;
public static final int SHEEP_2792 = 2792;
public static final int SHEEP_2793 = 2793;
public static final int SHEEP_2794 = 2794;
public static final int SHEEP_2795 = 2795;
public static final int SHEEP_2796 = 2796;
public static final int SHEEP_2797 = 2797;
public static final int SHEEP_2798 = 2798;
public static final int SHEEP_2799 = 2799;
public static final int SHEEP_2800 = 2800;
public static final int SHEEP_2801 = 2801;
public static final int SHEEP_2802 = 2802;
public static final int SHEEP_2803 = 2803;
public static final int SHEEP_2804 = 2804;
public static final int COW = 2805;
public static final int COW_2806 = 2806;
public static final int COW_CALF = 2807;
public static final int COW_2808 = 2808;
public static final int COW_CALF_2809 = 2809;
public static final int COW_2810 = 2810;
public static final int PIG = 2811;
public static final int PIG_2812 = 2812;
public static final int PIGLET = 2813;
public static final int PIGLET_2814 = 2814;
public static final int PIGLET_2815 = 2815;
public static final int COW_CALF_2816 = 2816;
public static final int SHEEPDOG = 2817;
public static final int ROOSTER_2818 = 2818;
public static final int CHICKEN_2819 = 2819;
public static final int CHICKEN_2820 = 2820;
public static final int CHICKEN_2821 = 2821;
public static final int PIG_2822 = 2822;
public static final int PIG_2823 = 2823;
public static final int PIGLET_2824 = 2824;
public static final int PIGLET_2825 = 2825;
public static final int PIGLET_2826 = 2826;
public static final int COW = 2790;
public static final int COW_2791 = 2791;
public static final int COW_CALF = 2792;
public static final int COW_2793 = 2793;
public static final int COW_CALF_2794 = 2794;
public static final int COW_2795 = 2795;
public static final int PIG = 2796;
public static final int PIG_2797 = 2797;
public static final int PIGLET = 2798;
public static final int PIGLET_2799 = 2799;
public static final int PIGLET_2800 = 2800;
public static final int COW_CALF_2801 = 2801;
public static final int SHEEPDOG = 2802;
public static final int ROOSTER_2803 = 2803;
public static final int CHICKEN_2804 = 2804;
public static final int CHICKEN_2805 = 2805;
public static final int CHICKEN_2806 = 2806;
public static final int PIG_2807 = 2807;
public static final int PIG_2808 = 2808;
public static final int PIGLET_2809 = 2809;
public static final int PIGLET_2810 = 2810;
public static final int PIGLET_2811 = 2811;
public static final int BOB_2812 = 2812;
public static final int SHOP_KEEPER = 2813;
public static final int SHOP_ASSISTANT = 2814;
public static final int SHOP_KEEPER_2815 = 2815;
public static final int SHOP_ASSISTANT_2816 = 2816;
public static final int SHOP_KEEPER_2817 = 2817;
public static final int SHOP_ASSISTANT_2818 = 2818;
public static final int SHOP_KEEPER_2819 = 2819;
public static final int SHOP_ASSISTANT_2820 = 2820;
public static final int SHOP_KEEPER_2821 = 2821;
public static final int SHOP_ASSISTANT_2822 = 2822;
public static final int SHOP_KEEPER_2823 = 2823;
public static final int SHOP_ASSISTANT_2824 = 2824;
public static final int SHOP_KEEPER_2825 = 2825;
public static final int SHOP_ASSISTANT_2826 = 2826;
public static final int BAT = 2827;
public static final int DRYAD = 2828;
public static final int FAIRY_2829 = 2829;
@@ -2697,7 +2690,7 @@ public final class NpcID
public static final int ICE_WARRIOR_2842 = 2842;
public static final int OTHERWORLDLY_BEING = 2843;
public static final int MAGIC_AXE = 2844;
public static final int SNAKE = 2845;
public static final int SNAKE_2845 = 2845;
public static final int SKAVID = 2846;
public static final int YETI = 2847;
public static final int MONKEY_2848 = 2848;
@@ -2720,33 +2713,33 @@ public final class NpcID
public static final int DUNGEON_RAT = 2865;
public static final int DUNGEON_RAT_2866 = 2866;
public static final int DUNGEON_RAT_2867 = 2867;
public static final int DARK_WIZARD_2868 = 2868;
public static final int INVRIGAR_THE_NECROMANCER = 2869;
public static final int DARK_WIZARD_2870 = 2870;
public static final int MUGGER_2871 = 2871;
public static final int WITCH = 2872;
public static final int WITCH_2873 = 2873;
public static final int BLACK_KNIGHT_2874 = 2874;
public static final int BLACK_KNIGHT_2875 = 2875;
public static final int HIGHWAYMAN = 2876;
public static final int HIGHWAYMAN_2877 = 2877;
public static final int CHAOS_DRUID = 2878;
public static final int PIRATE_2879 = 2879;
public static final int PIRATE_2880 = 2880;
public static final int PIRATE_2881 = 2881;
public static final int PIRATE_2882 = 2882;
public static final int THUG = 2883;
public static final int ROGUE = 2884;
public static final int MONK_OF_ZAMORAK = 2885;
public static final int MONK_OF_ZAMORAK_2886 = 2886;
public static final int MONK_OF_ZAMORAK_2887 = 2887;
public static final int TRIBESMAN = 2888;
public static final int DARK_WARRIOR = 2889;
public static final int CHAOS_DRUID_WARRIOR = 2890;
public static final int NECROMANCER = 2891;
public static final int BANDIT_2892 = 2892;
public static final int GUARD_BANDIT = 2893;
public static final int BARBARIAN_GUARD = 2894;
public static final int FAIRY_SHOP_KEEPER = 2868;
public static final int FAIRY_SHOP_ASSISTANT = 2869;
public static final int VALAINE = 2870;
public static final int SCAVVO = 2871;
public static final int PEKSA = 2872;
public static final int SILK_TRADER = 2873;
public static final int GEM_TRADER = 2874;
public static final int ZEKE = 2875;
public static final int LOUIE_LEGS = 2876;
public static final int KARIM = 2877;
public static final int RANAEL = 2878;
public static final int DOMMIK = 2879;
public static final int ZAFF = 2880;
public static final int BARAEK = 2881;
public static final int HORVIK = 2882;
public static final int LOWE = 2883;
public static final int SHOP_KEEPER_2884 = 2884;
public static final int SHOP_ASSISTANT_2885 = 2885;
public static final int AUBURY = 2886;
public static final int FANCY_DRESS_SHOP_OWNER = 2887;
public static final int SHOP_KEEPER_2888 = 2888;
public static final int GRUM_2889 = 2889;
public static final int WYDIN_2890 = 2890;
public static final int GERRANT_2891 = 2891;
public static final int BRIAN = 2892;
public static final int JIMINUA = 2893;
public static final int SHOP_KEEPER_2894 = 2894;
public static final int COOK_2895 = 2895;
public static final int COOK_2896 = 2896;
public static final int BANKER_2897 = 2897;
@@ -3022,23 +3015,23 @@ public final class NpcID
public static final int EMERALD_BENEDICT = 3194;
public static final int SPIN_BLADES = 3195;
public static final int SPIN_BLADES_3196 = 3196;
public static final int SNAKE_3199 = 3199;
public static final int MONKEY_3200 = 3200;
public static final int ALBINO_BAT = 3201;
public static final int CRAB_3202 = 3202;
public static final int GIANT_MOSQUITO = 3203;
public static final int JUNGLE_HORROR = 3204;
public static final int JUNGLE_HORROR_3205 = 3205;
public static final int JUNGLE_HORROR_3206 = 3206;
public static final int JUNGLE_HORROR_3207 = 3207;
public static final int JUNGLE_HORROR_3208 = 3208;
public static final int CAVE_HORROR = 3209;
public static final int CAVE_HORROR_3210 = 3210;
public static final int CAVE_HORROR_3211 = 3211;
public static final int CAVE_HORROR_3212 = 3212;
public static final int CAVE_HORROR_3213 = 3213;
public static final int CAVEY_DAVEY = 3214;
public static final int PATCHY = 3215;
public static final int CANDLE_MAKER = 3199;
public static final int ARHEIN = 3200;
public static final int JUKAT = 3201;
public static final int LUNDERWIN = 3202;
public static final int IRKSOL = 3203;
public static final int FAIRY_3204 = 3204;
public static final int ZAMBO = 3205;
public static final int SILVER_MERCHANT = 3206;
public static final int GEM_MERCHANT = 3207;
public static final int BAKER = 3208;
public static final int SPICE_SELLER = 3209;
public static final int FUR_TRADER = 3210;
public static final int SILK_MERCHANT = 3211;
public static final int HICKTON = 3212;
public static final int HARRY = 3213;
public static final int CASSIE = 3214;
public static final int FRINCOS = 3215;
public static final int MELEE_COMBAT_TUTOR = 3216;
public static final int RANGED_COMBAT_TUTOR = 3217;
public static final int MAGIC_COMBAT_TUTOR = 3218;
@@ -4354,7 +4347,7 @@ public final class NpcID
public static final int GEM_MERCHANT_4581 = 4581;
public static final int SILVER_MERCHANT_4582 = 4582;
public static final int SILK_MERCHANT_4583 = 4583;
public static final int ZENESHA_4584 = 4584;
public static final int ZENESHA = 4584;
public static final int ALI_MORRISANE_4585 = 4585;
public static final int GRIMESQUIT = 4586;
public static final int PHINGSPET = 4587;
@@ -5591,11 +5584,11 @@ public final class NpcID
public static final int TZREKJAD = 5892;
public static final int TZREKJAD_5893 = 5893;
public static final int BAST = 5894;
public static final int BANKER_5895 = 5895;
public static final int BANKER_5896 = 5896;
public static final int BANKER_5897 = 5897;
public static final int BANKER_5904 = 5904;
public static final int BANKER_5905 = 5905;
public static final int DROGO_DWARF = 5895;
public static final int FLYNN = 5896;
public static final int WAYNE = 5897;
public static final int DWARF_5904 = 5904;
public static final int BETTY_5905 = 5905;
public static final int PROBITA = 5906;
public static final int CHAOS_ELEMENTAL_JR_5907 = 5907;
public static final int ABYSSAL_SIRE_5908 = 5908;
@@ -6021,8 +6014,8 @@ public final class NpcID
public static final int FIDELIO = 6525;
public static final int SBOTT = 6526;
public static final int ROAVAR = 6527;
public static final int BANKER_6529 = 6529;
public static final int BANKER_6530 = 6530;
public static final int HERQUIN = 6529;
public static final int ROMMIK = 6530;
public static final int BLURBERRY = 6531;
public static final int BARMAN_6532 = 6532;
public static final int ROMILY_WEAKLAX = 6533;
@@ -7135,7 +7128,7 @@ public final class NpcID
public static final int ANCIENT_WYVERN = 7795;
public static final int LOBSTROSITY = 7796;
public static final int ANCIENT_ZYGOMITE = 7797;
public static final int ANCIENT_FUNGI = 7798;
public static final int GAIUS = 7798;
public static final int AMMONITE_CRAB = 7799;
public static final int FOSSIL_ROCK = 7800;
public static final int TAR_BUBBLES = 7801;
@@ -7745,7 +7738,7 @@ public final class NpcID
public static final int TRAPPED_SOUL_HARD = 8529;
public static final int AMELIA_8530 = 8530;
public static final int ALLANNA = 8531;
public static final int LEKE_QUO_KERAN = 8532;
public static final int JATIX = 8532;
public static final int NIKKIE = 8533;
public static final int ROSIE = 8534;
public static final int ALAN = 8535;
@@ -7855,11 +7848,23 @@ public final class NpcID
public static final int ILFEEN_8677 = 8677;
public static final int FERAL_VAMPYRE_8678 = 8678;
public static final int ABIDOR_CRANK_8679 = 8679;
public static final int BANKER_8680 = 8680;
public static final int BANKER_8681 = 8681;
public static final int BANKER_8682 = 8682;
public static final int PORTAL_8684 = 8684;
public static final int PORTAL_8686 = 8686;
public static final int DAVON = 8680;
public static final int ZENESHA_8681 = 8681;
public static final int AEMAD = 8682;
public static final int KORTAN = 8683;
public static final int ROACHEY = 8684;
public static final int FRENITA = 8685;
public static final int NURMOF = 8686;
public static final int TEA_SELLER = 8687;
public static final int FAT_TONY = 8688;
public static final int ANCIENT_FUNGI = 8690;
public static final int ANCIENT_FUNGI_8691 = 8691;
public static final int NOTERAZZO = 8692;
public static final int DIANGO = 8693;
public static final int BRIAN_8694 = 8694;
public static final int MOSOL_REI_8696 = 8696;
public static final int LEKE_QUO_KERAN = 8697;
public static final int MONK_OF_ZAMORAK_8698 = 8698;
public static final int LARRAN = 8699;
/* This file is automatically generated. Do not edit. */
}
@@ -12456,5 +12456,12 @@ public final class NullItemID
public static final int NULL_23455 = 23455;
public static final int NULL_23456 = 23456;
public static final int NULL_23457 = 23457;
public static final int NULL_23459 = 23459;
public static final int NULL_23487 = 23487;
public static final int NULL_23488 = 23488;
public static final int NULL_23491 = 23491;
public static final int NULL_23492 = 23492;
public static final int NULL_23493 = 23493;
public static final int NULL_23494 = 23494;
/* This file is automatically generated. Do not edit. */
}
@@ -16209,5 +16209,7 @@ public final class NullObjectID
public static final int NULL_34823 = 34823;
public static final int NULL_34824 = 34824;
public static final int NULL_34825 = 34825;
public static final int NULL_34831 = 34831;
public static final int NULL_34832 = 34832;
/* This file is automatically generated. Do not edit. */
}
@@ -16133,7 +16133,7 @@ public final class ObjectID
public static final int GRAND_EXCHANGE_BOOTH_30390 = 30390;
public static final int IRON_LADDER_30391 = 30391;
public static final int IRON_LADDER_30392 = 30392;
public static final int JADFEST_PORTAL = 30395;
public static final int MYSTERIOUS_POOL = 30395;
public static final int SHIMMERING_BARRIER_30396 = 30396;
public static final int SHIMMERING_BARRIER_30397 = 30397;
public static final int SHIMMERING_BARRIER_30398 = 30398;
@@ -17528,7 +17528,7 @@ public final class ObjectID
public static final int FIRE_OF_DEHUMIDIFICATION = 33322;
public static final int PILE_OF_RUBBLE_33340 = 33340;
public static final int PILE_OF_RUBBLE_33341 = 33341;
public static final int HUB_PORTAL = 33343;
public static final int LARRANS_SMALL_CHEST = 33343;
public static final int BROKEN_WALL_33344 = 33344;
public static final int PORTAL_NEXUS_SPACE = 33346;
public static final int RUG_SPACE_33347 = 33347;
@@ -18605,5 +18605,10 @@ public final class ObjectID
public static final int RUBBLE_34803 = 34803;
public static final int RUBBLE_34804 = 34804;
public static final int RUBBLE_34805 = 34805;
public static final int JADFEST_PORTAL = 34826;
public static final int HUB_PORTAL = 34827;
public static final int LARRANS_SMALL_CHEST_34828 = 34828;
public static final int LARRANS_BIG_CHEST = 34829;
public static final int LARRANS_BIG_CHEST_34830 = 34830;
/* This file is automatically generated. Do not edit. */
}
@@ -110,6 +110,16 @@ public final class ScriptID
*/
public static final int KEPT_LOST_ITEM_EXAMINE = 1603;
/**
* Displays the game messages when clicking on an item inside the Items Kept on Death interface
* <ul>
* <li> int (boolean) Item kept on death </li>
* <li> int Item Quantity </li>
* <li> String Item Name </li>
* </ul>
*/
public static final int DEATH_KEEP_ITEM_EXAMINE = 1603;
/**
* Checks the state of the given stash unit.
* <ul>
@@ -1564,9 +1564,28 @@ public final class SpriteID
public static final int MOBILE_FUNCTION_MODE_DISABLED = 1624;
public static final int MOBILE_YELLOW_TOUCH_ANIMATION_1 = 1625;
public static final int MOBILE_YELLOW_TOUCH_ANIMATION_2 = 1626;
/* Unmapped: 1627~1707 */
public static final int TAB_MAGIC_SPELLBOOK_ARCEUUS_UNUSED = 1708;
/* Unmapped: 1709, 1710 */
public static final int TAB_MAGIC_SPELLBOOK_ARCEUUS = 1711;
public static final int BIG_ASS_GUTHIX_SPELL = 1774;
public static final int BIG_SUPERHEAT = 1800;
public static final int BIG_SPEC_TRANSFER = 1959;
/* Unmapped: 1712~2175 */
public static final int HEALTHBAR_DEFAULT_FRONT_30PX = 2176;
public static final int HEALTHBAR_DEFAULT_BACK_30PX = 2177;
public static final int HEALTHBAR_DEFAULT_FRONT_50PX = 2178;
public static final int HEALTHBAR_DEFAULT_BACK_50PX = 2179;
public static final int HEALTHBAR_DEFAULT_FRONT_60PX = 2180;
public static final int HEALTHBAR_DEFAULT_BACK_60PX = 2181;
public static final int HEALTHBAR_DEFAULT_FRONT_80PX = 2182;
public static final int HEALTHBAR_DEFAULT_BACK_80PX = 2183;
public static final int HEALTHBAR_DEFAULT_FRONT_100PX = 2184;
public static final int HEALTHBAR_DEFAULT_BACK_100PX = 2185;
public static final int HEALTHBAR_DEFAULT_FRONT_120PX = 2186;
public static final int HEALTHBAR_DEFAULT_BACK_120PX = 2187;
public static final int HEALTHBAR_DEFAULT_FRONT_140PX = 2188;
public static final int HEALTHBAR_DEFAULT_BACK_140PX = 2189;
public static final int HEALTHBAR_DEFAULT_FRONT_160PX = 2190;
public static final int HEALTHBAR_DEFAULT_BACK_160PX = 2191;
}
@@ -56,7 +56,7 @@ public enum SlayerUnlock
TZHARR_ENABLE(18),
BOSS_ENABLE(19),
BLOODVELD_EXTEND(20),
ABBERANT_SPECTRE_EXTEND(21),
ABERRANT_SPECTRE_EXTEND(21),
AVIANSIES_EXTEND(22),
MITHRIL_DRAGON_EXTEND(23),
CAVE_HORROR_EXTEND(24),
@@ -79,7 +79,7 @@ public enum SlayerUnlock
RUNE_DRAGON_EXTEND(41),
VORKATH_SLAYER_HELM(42),
FOSSIL_ISLAND_WYVERN_DISABLE(43, Varbits.FOSSIL_ISLAND_WYVERN_DISABLE),
GROTESQUE_GARDIAN_DOUBLE_COUNT(44);
GROTESQUE_GUARDIAN_DOUBLE_COUNT(44);
private Varbits toggleVarbit;
@@ -149,6 +149,7 @@ public class WidgetID
public static final int BEGINNER_CLUE_MAP_NORTH_OF_FALADOR = 351;
public static final int BEGINNER_CLUE_MAP_WIZARDS_TOWER = 356;
public static final int SEED_BOX_GROUP_ID = 128;
public static final int ITEMS_KEPT_ON_DEATH_GROUP_ID = 4;
static class WorldMap
{
@@ -962,9 +963,9 @@ public class WidgetID
static final int ATTACK_RANGE = 59; // OUTDATED?
static final int BOUNTY_HUNTER_INFO = 19;
static final int KILLDEATH_RATIO = 15;
static final int SKULL_CONTAINER = 62;
static final int SAFE_ZONE = 64;
static final int WILDERNESS_LEVEL = 67; // this can also be the Deadman Mode "Protection" text
static final int SKULL_CONTAINER = 61;
static final int SAFE_ZONE = 63;
static final int WILDERNESS_LEVEL = 66; // this can also be the Deadman Mode "Protection" text
}
static class KourendFavour
@@ -1047,12 +1048,13 @@ public class WidgetID
static class KeptOnDeath
{
static final int KEPT_ITEMS_CONTAINER = 18;
static final int KEPT_ITEMS_TEXT = 17;
static final int LOST_ITEMS_TEXT = 20;
static final int LOST_ITEMS_CONTAINER = 21;
static final int LOST_ITEMS_VALUE = 23;
static final int INFORMATION_CONTAINER = 29;
static final int MAX_ITEMS_KEPT_ON_DEATH = 30;
static final int SAFE_ZONE_CONTAINER = 31;
static final int CUSTOM_TEXT_CONTAINER = 33;
}
@@ -739,7 +739,10 @@ public enum WidgetInfo
XP_DROP_4(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_4),
XP_DROP_5(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_5),
XP_DROP_6(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_6),
XP_DROP_7(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_7);
XP_DROP_7(WidgetID.EXPERIENCE_DROP_GROUP_ID, WidgetID.ExperienceDrop.DROP_7),
ITEMS_KEPT_ON_DEATH_TEXT(WidgetID.ITEMS_KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.KEPT_ITEMS_TEXT),
ITEMS_LOST_ON_DEATH_TEXT(WidgetID.ITEMS_KEPT_ON_DEATH_GROUP_ID, WidgetID.KeptOnDeath.LOST_ITEMS_TEXT);
private final int groupId;
private final int childId;
@@ -46,11 +46,13 @@ import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.GameState;
import net.runelite.client.chat.ChatColorType;
import net.runelite.client.chat.ChatMessageBuilder;
import net.runelite.client.chat.ChatMessageManager;
import net.runelite.client.chat.QueuedMessage;
import net.runelite.client.config.FlashNotification;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.util.OSType;
@@ -68,7 +70,8 @@ public class Notifier
// Notifier properties
private static final Color FLASH_COLOR = new Color(255, 0, 0, 70);
private static final int FLASH_DURATION = 2000;
private static final int MINIMUM_FLASH_DURATION_MILLIS = 2000;
private static final int MINIMUM_FLASH_DURATION_TICKS = MINIMUM_FLASH_DURATION_MILLIS / Constants.CLIENT_TICK_LENGTH;
private final Client client;
private final String appName;
@@ -79,6 +82,7 @@ public class Notifier
private final Path notifyIconPath;
private final boolean terminalNotifierAvailable;
private Instant flashStart;
private long mouseLastPressedMillis;
@Inject
private Notifier(
@@ -146,9 +150,10 @@ public class Notifier
.build());
}
if (runeLiteConfig.enableFlashNotification())
if (runeLiteConfig.flashNotification() != FlashNotification.DISABLED)
{
flashStart = Instant.now();
mouseLastPressedMillis = client.getMouseLastPressedMillis();
}
log.debug(message);
@@ -156,24 +161,48 @@ public class Notifier
public void processFlash(final Graphics2D graphics)
{
if (flashStart == null || client.getGameCycle() % 40 >= 20)
{
return;
}
else if (client.getGameState() != GameState.LOGGED_IN)
if (flashStart == null || client.getGameState() != GameState.LOGGED_IN)
{
flashStart = null;
return;
}
FlashNotification flashNotification = runeLiteConfig.flashNotification();
if (client.getGameCycle() % 40 >= 20
// For solid colour, fall through every time.
&& (flashNotification == FlashNotification.FLASH_TWO_SECONDS
|| flashNotification == FlashNotification.FLASH_UNTIL_CANCELLED))
{
return;
}
final Color color = graphics.getColor();
graphics.setColor(FLASH_COLOR);
graphics.fill(new Rectangle(client.getCanvas().getSize()));
graphics.setColor(color);
if (Instant.now().minusMillis(FLASH_DURATION).isAfter(flashStart))
if (!Instant.now().minusMillis(MINIMUM_FLASH_DURATION_MILLIS).isAfter(flashStart))
{
flashStart = null;
return;
}
switch (flashNotification)
{
case FLASH_TWO_SECONDS:
case SOLID_TWO_SECONDS:
flashStart = null;
break;
case SOLID_UNTIL_CANCELLED:
case FLASH_UNTIL_CANCELLED:
// Any interaction with the client since the notification started will cancel it after the minimum duration
if (client.getMouseIdleTicks() < MINIMUM_FLASH_DURATION_TICKS
|| client.getKeyboardIdleTicks() < MINIMUM_FLASH_DURATION_TICKS
|| client.getMouseLastPressedMillis() > mouseLastPressedMillis)
{
flashStart = null;
}
break;
}
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2019, Twiglet1022 <https://github.com/Twiglet1022>
* 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.config;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum FlashNotification
{
DISABLED("Off"),
FLASH_TWO_SECONDS("Flash for 2 seconds"),
SOLID_TWO_SECONDS("Solid for 2 seconds"),
FLASH_UNTIL_CANCELLED("Flash until cancelled"),
SOLID_UNTIL_CANCELLED("Solid until cancelled");
private final String type;
@Override
public String toString()
{
return type;
}
}
@@ -191,9 +191,9 @@ public interface RuneLiteConfig extends Config
description = "Flashes the game frame as a notification",
position = 24
)
default boolean enableFlashNotification()
default FlashNotification flashNotification()
{
return false;
return FlashNotification.DISABLED;
}
@ConfigItem(
@@ -44,6 +44,7 @@ import javax.inject.Singleton;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import static net.runelite.api.Constants.CLIENT_DEFAULT_ZOOM;
import static net.runelite.api.Constants.HIGH_ALCHEMY_CONSTANT;
import net.runelite.api.GameState;
@@ -521,7 +522,7 @@ public class ItemManager
*/
private AsyncBufferedImage loadImage(int itemId, int quantity, boolean stackable)
{
AsyncBufferedImage img = new AsyncBufferedImage(36, 32, BufferedImage.TYPE_INT_ARGB);
AsyncBufferedImage img = new AsyncBufferedImage(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
clientThread.invoke(() ->
{
if (client.getGameState().ordinal() < GameState.LOGIN_SCREEN.ordinal())
@@ -144,10 +144,12 @@ public enum ItemMapping
// Bounty hunter
ITEM_GRANITE_MAUL(GRANITE_MAUL, GRANITE_MAUL_12848),
ITEM_MAGIC_SHORTBOW(MAGIC_SHORTBOW, MAGIC_SHORTBOW_I),
ITEM_MAGIC_SHORTBOW_SCROLL(MAGIC_SHORTBOW_SCROLL, MAGIC_SHORTBOW_I),
ITEM_SARADOMINS_BLESSED_SWORD(SARADOMINS_TEAR, SARADOMINS_BLESSED_SWORD),
// Jewellery with charges
ITEM_RING_OF_WEALTH(RING_OF_WEALTH, RING_OF_WEALTH_I, RING_OF_WEALTH_1, RING_OF_WEALTH_I1, RING_OF_WEALTH_2, RING_OF_WEALTH_I2, RING_OF_WEALTH_3, RING_OF_WEALTH_I3, RING_OF_WEALTH_4, RING_OF_WEALTH_I4, RING_OF_WEALTH_I5),
ITEM_RING_OF_WEALTH_SCROLL(RING_OF_WEALTH_SCROLL, RING_OF_WEALTH_I, RING_OF_WEALTH_I1, RING_OF_WEALTH_I2, RING_OF_WEALTH_I3, RING_OF_WEALTH_I4, RING_OF_WEALTH_I5),
ITEM_AMULET_OF_GLORY(AMULET_OF_GLORY, AMULET_OF_GLORY1, AMULET_OF_GLORY2, AMULET_OF_GLORY3, AMULET_OF_GLORY5),
ITEM_AMULET_OF_GLORY_T(AMULET_OF_GLORY_T, AMULET_OF_GLORY_T1, AMULET_OF_GLORY_T2, AMULET_OF_GLORY_T3, AMULET_OF_GLORY_T5),
ITEM_SKILLS_NECKLACE(SKILLS_NECKLACE, SKILLS_NECKLACE1, SKILLS_NECKLACE2, SKILLS_NECKLACE3, SKILLS_NECKLACE5),
@@ -109,7 +109,7 @@ public class LootManager
case NpcID.LIZARD:
case NpcID.ZYGOMITE:
case NpcID.ZYGOMITE_474:
case NpcID.ZYGOMITE_1024:
case NpcID.ANCIENT_ZYGOMITE:
// these monsters die with >0 hp, so we just look for coincident
@@ -34,6 +34,7 @@ import javax.inject.Inject;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemContainer;
@@ -50,6 +50,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.Getter;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemDefinition;
@@ -730,7 +731,13 @@ public class TabInterface
if (tagTab.getIcon() == null)
{
Widget icon = createGraphic(ColorUtil.wrapWithColorTag(tagTab.getTag(), HILIGHT_COLOR), -1, tagTab.getIconItemId(), 36, 32, bounds.x + 3, 1, false);
Widget icon = createGraphic(
ColorUtil.wrapWithColorTag(tagTab.getTag(), HILIGHT_COLOR),
-1,
tagTab.getIconItemId(),
Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT,
bounds.x + 3, 1,
false);
int clickmask = icon.getClickMask();
clickmask |= WidgetConfig.DRAG;
clickmask |= WidgetConfig.DRAG_ON;
@@ -35,7 +35,7 @@ public enum CannonSpots
BLOODVELDS(new WorldPoint(2439, 9821, 0), new WorldPoint(2448, 9821, 0), new WorldPoint(2472, 9833, 0), new WorldPoint(2453, 9817, 0)),
FIRE_GIANTS(new WorldPoint(2393, 9782, 0), new WorldPoint(2412, 9776, 0), new WorldPoint(2401, 9780, 0)),
ABBERANT_SPECTRES(new WorldPoint(2456, 9791, 0)),
ABERRANT_SPECTRES(new WorldPoint(2456, 9791, 0)),
HELLHOUNDS(new WorldPoint(2431, 9776, 0), new WorldPoint(2413, 9786, 0), new WorldPoint(2783, 9686, 0), new WorldPoint(3198, 10071, 0)),
BLACK_DEMONS(new WorldPoint(2859, 9778, 0), new WorldPoint(2841, 9791, 0)),
ELVES(new WorldPoint(2044, 4635, 0)),
@@ -37,6 +37,7 @@ import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.Experience;
import net.runelite.api.IconID;
import net.runelite.api.ItemDefinition;
@@ -129,9 +129,12 @@ public class ChatNotificationsPlugin extends Plugin
{
List<String> items = Text.fromCSV(config.highlightWordsString());
String joined = items.stream()
.map(Text::escapeJagex) // we compare these strings to the raw Jagex ones
.map(Pattern::quote)
.collect(Collectors.joining("|"));
highlightMatcher = Pattern.compile("\\b(" + joined + ")\\b", Pattern.CASE_INSENSITIVE);
// To match <word> \b doesn't work due to <> not being in \w,
// so match \b or \s
highlightMatcher = Pattern.compile("(?:\\b|(?<=\\s))(" + joined + ")(?:\\b|(?=\\s))", Pattern.CASE_INSENSITIVE);
}
}
@@ -139,7 +142,6 @@ public class ChatNotificationsPlugin extends Plugin
public void onChatMessage(ChatMessage chatMessage)
{
MessageNode messageNode = chatMessage.getMessageNode();
String nodeValue = Text.removeTags(messageNode.getValue());
boolean update = false;
switch (chatMessage.getType())
@@ -202,6 +204,7 @@ public class ChatNotificationsPlugin extends Plugin
if (highlightMatcher != null)
{
String nodeValue = messageNode.getValue();
Matcher matcher = highlightMatcher.matcher(nodeValue);
boolean found = false;
StringBuffer stringBuffer = new StringBuffer();
@@ -259,7 +259,7 @@ public class CrypticClue extends ClueScroll implements TextClueScroll, NpcClueSc
new CrypticClue("Search the drawers in Catherby's Archery shop.", DRAWERS_350, new WorldPoint(2825, 3442, 0), "Hickton's Archery Emporium in Catherby."),
new CrypticClue("The hand ain't listening.", "The Face", new WorldPoint(3019, 3232, 0), "Talk to The Face located by the manhole just north of the Port Sarim fishing shop."),
new CrypticClue("Search the chest in the left-hand tower of Camelot Castle.", CLOSED_CHEST_25592, new WorldPoint(2748, 3495, 2), "Located on the second floor of the western tower of Camelot."),
new CrypticClue("Kill the spiritual, magic and godly whilst representing their own god", null, "Kill a spiritual mage while wearing a corresponding god item."),
new CrypticClue("Kill the spiritual, magic and godly whilst representing their own god.", null, "Kill a spiritual mage while wearing a corresponding god item."),
new CrypticClue("Anger those who adhere to Saradomin's edicts to prevent travel.", "Monk of Entrana", new WorldPoint(3042, 3236, 0), "Port Sarim Docks, try to charter a ship to Entrana with armour or weapons equipped."),
new CrypticClue("South of a river in a town surrounded by the undead, what lies beneath the furnace?", new WorldPoint(2857, 2966, 0), "Dig in front of the Shilo Village furnace."),
new CrypticClue("Talk to the Squire in the White Knights' castle in Falador.", "Squire", new WorldPoint(2977, 3343, 0), "The squire is located in the courtyard of the White Knights' Castle."),
@@ -87,11 +87,11 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl
new FaloTheBardClue("A shiny helmet of flight, to obtain this with melee, struggle you might.", item(ARMADYL_HELMET)),
// The wiki doesn't specify whether the trimmed dragon defender will work so I've assumed that it doesn't
new FaloTheBardClue("A sword held in the other hand, red its colour, Cyclops strength you must withstand.", item(DRAGON_DEFENDER)),
new FaloTheBardClue("A token used to kill mythical beasts, in hope of a blade or just for an xp feast.", item(WARRIOR_GUILD_TOKEN)),
new FaloTheBardClue("A token used to kill mythical beasts, in hopes of a blade or just for an xp feast.", item(WARRIOR_GUILD_TOKEN)),
new FaloTheBardClue("Green is my favorite, mature ale I do love, this takes your herblore above.", item(GREENMANS_ALEM)),
new FaloTheBardClue("It can hold down a boat or crush a goat, this object, you see, is quite heavy.", item(BARRELCHEST_ANCHOR)),
new FaloTheBardClue("It comes from the ground, underneath the snowy plain. Trolls aplenty, with what looks like a mane.", item(BASALT)),
new FaloTheBardClue("No attack to wield, only strength is required, made of obsidian but with no room for a shield.", item(TZHAARKETOM)),
new FaloTheBardClue("No attack to wield, only strength is required, made of obsidian, but with no room for a shield.", item(TZHAARKETOM)),
new FaloTheBardClue("Penance healers runners and more, obtaining this body often gives much deplore.", item(FIGHTER_TORSO)),
new FaloTheBardClue("Strangely found in a chest, many believe these gloves are the best.", item(BARROWS_GLOVES)),
new FaloTheBardClue("These gloves of white won't help you fight, but aid in cooking, they just might.", item(COOKING_GAUNTLETS)),
@@ -26,6 +26,8 @@ package net.runelite.client.plugins.emojis;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.inject.Inject;
import joptsimple.internal.Strings;
@@ -52,6 +54,8 @@ import net.runelite.client.util.ImageUtil;
@Slf4j
public class EmojiPlugin extends Plugin
{
private static final Pattern TAG_REGEXP = Pattern.compile("<[^>]*>");
@Inject
private Client client;
@@ -128,7 +132,8 @@ public class EmojiPlugin extends Plugin
return;
}
final String message = chatMessage.getMessage();
final MessageNode messageNode = chatMessage.getMessageNode();
final String message = messageNode.getValue();
final String updatedMessage = updateMessage(message);
if (updatedMessage == null)
@@ -136,7 +141,6 @@ public class EmojiPlugin extends Plugin
return;
}
final MessageNode messageNode = chatMessage.getMessageNode();
messageNode.setRuneLiteFormatMessage(updatedMessage);
chatMessageManager.update(messageNode);
client.refreshChat();
@@ -169,7 +173,9 @@ public class EmojiPlugin extends Plugin
boolean editedMessage = false;
for (int i = 0; i < messageWords.length; i++)
{
final Emoji emoji = Emoji.getEmoji(messageWords[i]);
// Remove tags except for <lt> and <gt>
final String trigger = removeTags(messageWords[i]);
final Emoji emoji = Emoji.getEmoji(trigger);
if (emoji == null)
{
@@ -178,7 +184,7 @@ public class EmojiPlugin extends Plugin
final int emojiId = modIconsStart + emoji.ordinal();
messageWords[i] = "<img=" + emojiId + ">";
messageWords[i] = messageWords[i].replace(trigger, "<img=" + emojiId + ">");
editedMessage = true;
}
@@ -190,4 +196,29 @@ public class EmojiPlugin extends Plugin
return Strings.join(messageWords, " ");
}
/**
* Remove tags, except for &lt;lt&gt; and &lt;gt&gt;
*
* @return
*/
private static String removeTags(String str)
{
StringBuffer stringBuffer = new StringBuffer();
Matcher matcher = TAG_REGEXP.matcher(str);
while (matcher.find())
{
matcher.appendReplacement(stringBuffer, "");
String match = matcher.group(0);
switch (match)
{
case "<lt>":
case "<gt>":
stringBuffer.append(match);
break;
}
}
matcher.appendTail(stringBuffer);
return stringBuffer.toString();
}
}
@@ -36,6 +36,7 @@ import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.ItemDefinition;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameStateChanged;
@@ -199,26 +200,26 @@ public class ExaminePlugin extends Plugin
log.debug("Got examine for {} {}: {}", pendingExamine.getType(), pendingExamine.getId(), event.getMessage());
// If it is an item, show the price of it
final ItemDefinition itemComposition;
final ItemDefinition Itemdefinition;
if (pendingExamine.getType() == ExamineType.ITEM || pendingExamine.getType() == ExamineType.ITEM_BANK_EQ)
{
final int itemId = pendingExamine.getId();
final int itemQuantity = pendingExamine.getQuantity();
itemComposition = itemManager.getItemDefinition(itemId);
Itemdefinition = itemManager.getItemDefinition(itemId);
if (itemComposition != null)
if (Itemdefinition != null)
{
final int id = itemManager.canonicalize(itemComposition.getId());
executor.submit(() -> getItemPrice(id, itemComposition, itemQuantity));
final int id = itemManager.canonicalize(Itemdefinition.getId());
executor.submit(() -> getItemPrice(id, Itemdefinition, itemQuantity));
}
}
else
{
itemComposition = null;
Itemdefinition = null;
}
// Don't submit examine info for tradeable items, which we already have from the RS item api
if (itemComposition != null && itemComposition.isTradeable())
if (Itemdefinition != null && Itemdefinition.isTradeable())
{
return;
}
@@ -49,6 +49,7 @@ import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.GameState;
import net.runelite.api.Item;
import net.runelite.api.ItemDefinition;
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2019 Hydrox6 <ikada@protonmail.ch>
* 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.interfacestyles;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import static net.runelite.api.SpriteID.*;
import net.runelite.client.game.SpriteOverride;
@RequiredArgsConstructor
enum HealthbarOverride implements SpriteOverride
{
BACK_30PX(HEALTHBAR_DEFAULT_BACK_30PX, "back_30px.png"),
BACK_50PX(HEALTHBAR_DEFAULT_BACK_50PX, "back_30px.png"),
BACK_60PX(HEALTHBAR_DEFAULT_BACK_60PX, "back_30px.png"),
BACK_80PX(HEALTHBAR_DEFAULT_BACK_80PX, "back_90px.png"),
BACK_100PX(HEALTHBAR_DEFAULT_BACK_100PX, "back_90px.png"),
BACK_120PX(HEALTHBAR_DEFAULT_BACK_120PX, "back_90px.png"),
BACK_140PX(HEALTHBAR_DEFAULT_BACK_140PX, "back_90px.png"),
BACK_160PX(HEALTHBAR_DEFAULT_BACK_160PX, "back_90px.png"),
FRONT_30PX(HEALTHBAR_DEFAULT_FRONT_30PX, "front_30px.png"),
FRONT_50PX(HEALTHBAR_DEFAULT_FRONT_50PX, "front_30px.png"),
FRONT_60PX(HEALTHBAR_DEFAULT_FRONT_60PX, "front_30px.png"),
FRONT_80PX(HEALTHBAR_DEFAULT_FRONT_80PX, "front_90px.png"),
FRONT_100PX(HEALTHBAR_DEFAULT_FRONT_100PX, "front_90px.png"),
FRONT_120PX(HEALTHBAR_DEFAULT_FRONT_120PX, "front_90px.png"),
FRONT_140PX(HEALTHBAR_DEFAULT_FRONT_140PX, "front_90px.png"),
FRONT_160PX(HEALTHBAR_DEFAULT_FRONT_160PX, "front_90px.png");
@Getter
private final int spriteId;
private final String fileName;
@Getter
private int padding = 1;
private static final Map<Integer, HealthbarOverride> MAP;
static
{
ImmutableMap.Builder<Integer, HealthbarOverride> builder = new ImmutableMap.Builder<>();
for (HealthbarOverride override : values())
{
builder.put(override.spriteId, override);
}
MAP = builder.build();
}
static HealthbarOverride get(int spriteID)
{
return MAP.get(spriteID);
}
@Override
public String getFileName()
{
return Skin.AROUND_2010.toString() + "/healthbar/" + this.fileName;
}
}
@@ -32,8 +32,6 @@ import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.HealthBar;
import net.runelite.api.HealthBarOverride;
import net.runelite.api.NodeCache;
import net.runelite.api.SpriteID;
import net.runelite.api.Sprite;
import net.runelite.api.events.BeforeMenuRender;
@@ -71,8 +69,6 @@ public class InterfaceStylesPlugin extends Plugin
@Inject
private SpriteManager spriteManager;
private HealthBarOverride healthBarOverride;
@Provides
InterfaceStylesConfig provideConfig(ConfigManager configManager)
{
@@ -92,10 +88,7 @@ public class InterfaceStylesPlugin extends Plugin
{
restoreWidgetDimensions();
removeGameframe();
healthBarOverride = null;
client.setHealthBarOverride(null);
NodeCache heathBarCache = client.getHealthBarCache();
heathBarCache.reset(); // invalidate healthbar cache so padding resets
restoreHealthBars();
});
}
@@ -117,19 +110,19 @@ public class InterfaceStylesPlugin extends Plugin
@Subscribe
public void onPostHealthBar(PostHealthBar postHealthBar)
{
if (healthBarOverride == null || !config.hdHealthBars())
if (!config.hdHealthBars())
{
return;
}
HealthBar healthBar = postHealthBar.getHealthBar();
Sprite frontSprite = healthBar.getHealthBarFrontSprite();
HealthbarOverride override = HealthbarOverride.get(healthBar.getHealthBarFrontSpriteId());
// Check if this is the health bar we are replacing
if (frontSprite == healthBarOverride.getFrontSprite() || frontSprite == healthBarOverride.getFrontSpriteLarge())
if (override != null)
{
// Increase padding to show some more green at very low hp percentages
healthBar.setPadding(1);
healthBar.setPadding(override.getPadding());
}
}
@@ -162,7 +155,7 @@ public class InterfaceStylesPlugin extends Plugin
if (skin == config.skin())
{
String file = config.skin().toString() + "/" + spriteOverride.getSpriteID() + ".png";
Sprite spritePixels = getFileSprite(file);
Sprite spritePixels = getFileSpritePixels(file);
if (spriteOverride.getSpriteID() == SpriteID.COMPASS_TEXTURE)
{
@@ -194,7 +187,7 @@ public class InterfaceStylesPlugin extends Plugin
if (widgetOverride.getSkin() == config.skin())
{
String file = config.skin().toString() + "/widget/" + widgetOverride.getName() + ".png";
Sprite spritePixels = getFileSprite(file);
Sprite spritePixels = getFileSpritePixels(file);
if (spritePixels != null)
{
@@ -218,7 +211,7 @@ public class InterfaceStylesPlugin extends Plugin
}
}
private Sprite getFileSprite(String file)
private Sprite getFileSpritePixels(String file)
{
try
{
@@ -272,31 +265,24 @@ public class InterfaceStylesPlugin extends Plugin
private void overrideHealthBars()
{
// Reset health bar cache to reset applied padding
NodeCache healthBarCache = client.getHealthBarCache();
healthBarCache.reset();
if (config.hdHealthBars())
{
String fileBase = Skin.AROUND_2010.toString() + "/healthbar/";
Sprite frontSprite = getFileSprite(fileBase + "front.png");
Sprite backSprite = getFileSprite(fileBase + "back.png");
Sprite frontSpriteLarge = getFileSprite(fileBase + "front_large.png");
Sprite backSpriteLarge = getFileSprite(fileBase + "back_large.png");
HealthBarOverride override = new HealthBarOverride(frontSprite, backSprite, frontSpriteLarge, backSpriteLarge);
healthBarOverride = override;
client.setHealthBarOverride(override);
spriteManager.addSpriteOverrides(HealthbarOverride.values());
// Reset health bar caches to apply the override
clientThread.invokeLater(client::resetHealthBarCaches);
}
else
{
healthBarOverride = null;
client.setHealthBarOverride(null);
restoreHealthBars();
}
}
private void restoreHealthBars()
{
spriteManager.removeSpriteOverrides(HealthbarOverride.values());
clientThread.invokeLater(client::resetHealthBarCaches);
}
private void restoreWidgetDimensions()
{
for (WidgetOffset widgetOffset : WidgetOffset.values())
@@ -27,6 +27,7 @@ package net.runelite.client.plugins.inventorygrid;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
import net.runelite.client.config.Range;
@ConfigGroup("inventorygrid")
public interface InventoryGridConfig extends Config
@@ -60,4 +61,15 @@ public interface InventoryGridConfig extends Config
{
return true;
}
@ConfigItem(
keyName = "dragDelay",
name = "Drag Delay",
description = "Time in ms to wait after item press before showing grid"
)
@Range(min = 100)
default int dragDelay()
{
return 100;
}
}
@@ -34,6 +34,7 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetItem;
@@ -45,7 +46,6 @@ import net.runelite.client.ui.overlay.OverlayPosition;
class InventoryGridOverlay extends Overlay
{
private static final int INVENTORY_SIZE = 28;
private static final int DRAG_DELAY = 5;
private static final Color HIGHLIGHT = new Color(0, 255, 0, 45);
private static final Color GRID = new Color(255, 255, 255, 45);
@@ -72,7 +72,7 @@ class InventoryGridOverlay extends Overlay
final Widget inventoryWidget = client.getWidget(WidgetInfo.INVENTORY);
if (if1DraggingWidget == null || if1DraggingWidget != inventoryWidget
|| client.getItemPressedDuration() < DRAG_DELAY)
|| client.getItemPressedDuration() < config.dragDelay() / Constants.CLIENT_TICK_LENGTH)
{
return null;
}
@@ -34,6 +34,7 @@ import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemDefinition;
@@ -51,9 +52,8 @@ import net.runelite.client.ui.overlay.components.TitleComponent;
class InventoryViewerOverlay extends Overlay
{
private static final int INVENTORY_SIZE = 28;
private static final int PLACEHOLDER_WIDTH = 36;
private static final int PLACEHOLDER_HEIGHT = 32;
private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(new BufferedImage(PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR));
private static final ImageComponent PLACEHOLDER_IMAGE = new ImageComponent(
new BufferedImage(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR));
private final Client client;
private final ItemManager itemManager;
@@ -29,6 +29,7 @@ import java.awt.Dimension;
import java.awt.Graphics2D;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemDefinition;
@@ -194,6 +195,7 @@ class ItemPricesOverlay extends Overlay
int gePrice = 0;
int haPrice = 0;
int haProfit = 0;
final int itemHaPrice = Math.round(itemDef.getPrice() * Constants.HIGH_ALCHEMY_MULTIPLIER);
if (config.showGEPrice())
{
@@ -203,9 +205,9 @@ class ItemPricesOverlay extends Overlay
{
haPrice = itemManager.getAlchValue(id);
}
if (gePrice > 0 && haPrice > 0 && config.showAlchProfit())
if (gePrice > 0 && itemHaPrice > 0 && config.showAlchProfit())
{
haProfit = calculateHAProfit(haPrice, gePrice);
haProfit = calculateHAProfit(itemHaPrice, gePrice);
}
if (gePrice > 0 || haPrice > 0)
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.itemskeptondeath;
import com.google.common.collect.ImmutableMap;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.ItemID;
/**
* Certain Items receive a white outline by Jagex as they are always lost on death. This is sometimes incorrectly
* added to Items by Jagex as the item is actually kept in non-pvp areas of the game, such as the Rune Pouch.
*
* The white outline will be added to these items when they are lost on death.
*/
@AllArgsConstructor
@Getter
enum AlwaysLostItem
{
RUNE_POUCH(ItemID.RUNE_POUCH, true),
LOOTING_BAG(ItemID.LOOTING_BAG, false),
CLUE_BOX(ItemID.CLUE_BOX, false);
private final int itemID;
private final boolean keptOutsideOfWilderness;
private static final ImmutableMap<Integer, AlwaysLostItem> ID_MAP;
static
{
final ImmutableMap.Builder<Integer, AlwaysLostItem> map = ImmutableMap.builder();
for (final AlwaysLostItem p : values())
{
map.put(p.itemID, p);
}
ID_MAP = map.build();
}
static AlwaysLostItem getByItemID(final int itemID)
{
return ID_MAP.get(itemID);
}
}
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.itemskeptondeath;
import com.google.common.collect.ImmutableSet;
import lombok.AllArgsConstructor;
import net.runelite.api.ItemID;
/**
* Some non tradeable items are kept on death inside low level wilderness (1-20) but are turned into a broken variant.
*
* The non-broken variant will be shown inside the interface.
*/
@AllArgsConstructor
enum BrokenOnDeathItem
{
// Capes
FIRE_CAPE(ItemID.FIRE_CAPE),
FIRE_MAX_CAPE(ItemID.FIRE_MAX_CAPE),
INFERNAL_CAPE(ItemID.INFERNAL_CAPE),
INFERNAL_MAX_CAPE(ItemID.INFERNAL_MAX_CAPE),
AVAS_ASSEMBLER(ItemID.AVAS_ASSEMBLER),
ASSEMBLER_MAX_CAPE(ItemID.ASSEMBLER_MAX_CAPE),
// Defenders
BRONZE_DEFENDER(ItemID.BRONZE_DEFENDER),
IRON_DEFENDER(ItemID.IRON_DEFENDER),
STEEL_DEFENDER(ItemID.STEEL_DEFENDER),
BLACK_DEFENDER(ItemID.BLACK_DEFENDER),
MITHRIL_DEFENDER(ItemID.MITHRIL_DEFENDER),
ADAMANT_DEFENDER(ItemID.ADAMANT_DEFENDER),
RUNE_DEFENDER(ItemID.RUNE_DEFENDER),
DRAGON_DEFENDER(ItemID.DRAGON_DEFENDER),
AVERNIC_DEFENDER(ItemID.AVERNIC_DEFENDER),
// Void
VOID_MAGE_HELM(ItemID.VOID_MAGE_HELM),
VOID_RANGER_HELM(ItemID.VOID_RANGER_HELM),
VOID_MELEE_HELM(ItemID.VOID_MELEE_HELM),
VOID_KNIGHT_TOP(ItemID.VOID_KNIGHT_TOP),
VOID_KNIGHT_ROBE(ItemID.VOID_KNIGHT_ROBE),
VOID_KNIGHT_GLOVES(ItemID.VOID_KNIGHT_GLOVES),
VOID_KNIGHT_MACE(ItemID.VOID_KNIGHT_MACE),
ELITE_VOID_TOP(ItemID.ELITE_VOID_TOP),
ELITE_VOID_ROBE(ItemID.ELITE_VOID_ROBE),
// Barb Assault
FIGHTER_HAT(ItemID.FIGHTER_HAT),
RANGER_HAT(ItemID.RANGER_HAT),
HEALER_HAT(ItemID.HEALER_HAT),
FIGHTER_TORSO(ItemID.FIGHTER_TORSO),
PENANCE_SKIRT(ItemID.PENANCE_SKIRT),
// Castle Wars
SARADOMIN_HALO(ItemID.SARADOMIN_HALO),
ZAMORAK_HALO(ItemID.ZAMORAK_HALO),
GUTHIX_HALO(ItemID.GUTHIX_HALO),
DECORATIVE_MAGIC_HAT(ItemID.DECORATIVE_ARMOUR_11898),
DECORATIVE_MAGIC_ROBE_TOP(ItemID.DECORATIVE_ARMOUR_11896),
DECORATIVE_MAGIC_ROBE_LEGS(ItemID.DECORATIVE_ARMOUR_11897),
DECORATIVE_RANGE_TOP(ItemID.DECORATIVE_ARMOUR_11899),
DECORATIVE_RANGE_BOTTOM(ItemID.DECORATIVE_ARMOUR_11900),
DECORATIVE_RANGE_QUIVER(ItemID.DECORATIVE_ARMOUR_11901),
GOLD_DECORATIVE_HELM(ItemID.DECORATIVE_HELM_4511),
GOLD_DECORATIVE_BODY(ItemID.DECORATIVE_ARMOUR_4509),
GOLD_DECORATIVE_LEGS(ItemID.DECORATIVE_ARMOUR_4510),
GOLD_DECORATIVE_SKIRT(ItemID.DECORATIVE_ARMOUR_11895),
GOLD_DECORATIVE_SHIELD(ItemID.DECORATIVE_SHIELD_4512),
GOLD_DECORATIVE_SWORD(ItemID.DECORATIVE_SWORD_4508);
private final int itemID;
private static final ImmutableSet<Integer> ID_SET;
static
{
final ImmutableSet.Builder<Integer> set = new ImmutableSet.Builder<>();
for (final BrokenOnDeathItem p : values())
{
set.add(p.itemID);
}
ID_SET = set.build();
}
static boolean isBrokenOnDeath(final int itemID)
{
return ID_SET.contains(itemID);
}
}
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.itemskeptondeath;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import javax.annotation.Nullable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.runelite.api.ItemID;
/**
* Some items have a fixed price that is added to its default value when calculating death prices.
* These are typically imbued items, such as Berserker ring (i), to help it protect over the non-imbued variants.
*/
@AllArgsConstructor
@Getter
enum FixedPriceItem
{
IMBUED_BLACK_MASK_I(ItemID.BLACK_MASK_I, 5000),
IMBUED_BLACK_MASK_1_I(ItemID.BLACK_MASK_1_I, 5000),
IMBUED_BLACK_MASK_2_I(ItemID.BLACK_MASK_2_I, 5000),
IMBUED_BLACK_MASK_3_I(ItemID.BLACK_MASK_3_I, 5000),
IMBUED_BLACK_MASK_4_I(ItemID.BLACK_MASK_4_I, 5000),
IMBUED_BLACK_MASK_5_I(ItemID.BLACK_MASK_5_I, 5000),
IMBUED_BLACK_MASK_6_I(ItemID.BLACK_MASK_6_I, 5000),
IMBUED_BLACK_MASK_7_I(ItemID.BLACK_MASK_7_I, 5000),
IMBUED_BLACK_MASK_8_I(ItemID.BLACK_MASK_8_I, 5000),
IMBUED_BLACK_MASK_9_I(ItemID.BLACK_MASK_9_I, 5000),
IMBUED_BLACK_MASK_10_I(ItemID.BLACK_MASK_10_I, 5000),
IMBUED_SLAYER_HELMET_I(ItemID.SLAYER_HELMET_I, 1000),
IMBUED_BLACK_SLAYER_HELMET_I(ItemID.BLACK_SLAYER_HELMET_I, 1000),
IMBUED_PURPLE_SLAYER_HELMET_I(ItemID.PURPLE_SLAYER_HELMET_I, 1000),
IMBUED_RED_SLAYER_HELMET_I(ItemID.RED_SLAYER_HELMET_I, 1000),
IMBUED_GREEN_SLAYER_HELMET_I(ItemID.GREEN_SLAYER_HELMET_I, 1000),
IMBUED_TURQUOISE_SLAYER_HELMET_I(ItemID.TURQUOISE_SLAYER_HELMET_I, 1000),
IMBUED_HYDRA_SLAYER_HELMET_I(ItemID.HYDRA_SLAYER_HELMET_I, 1000),
IMBUED_ARCHERS_RING_I(ItemID.ARCHERS_RING_I, 2000),
IMBUED_BERSERKER_RING_I(ItemID.BERSERKER_RING_I, 2000),
IMBUED_SEERS_RING_I(ItemID.SEERS_RING_I, 2000),
IMBUED_RING_OF_THE_GODS_I(ItemID.RING_OF_THE_GODS_I, 2000),
IMBUED_TREASONOUS_RING_I(ItemID.TREASONOUS_RING_I, 2000),
IMBUED_TYRANNICAL_RING_I(ItemID.TYRANNICAL_RING_I, 2000);
private final int itemId;
private final int offset;
private static final Map<Integer, FixedPriceItem> FIXED_ITEMS;
static
{
final ImmutableMap.Builder<Integer, FixedPriceItem> map = ImmutableMap.builder();
for (final FixedPriceItem p : values())
{
map.put(p.itemId, p);
}
FIXED_ITEMS = map.build();
}
@Nullable
static FixedPriceItem find(int itemId)
{
return FIXED_ITEMS.get(itemId);
}
}
@@ -0,0 +1,610 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* 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.itemskeptondeath;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.FontID;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
import net.runelite.api.ItemComposition;
import net.runelite.api.ItemContainer;
import net.runelite.api.ItemID;
import net.runelite.api.ScriptID;
import net.runelite.api.SkullIcon;
import net.runelite.api.SpriteID;
import net.runelite.api.Varbits;
import net.runelite.api.WorldType;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.vars.AccountType;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetType;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.ItemManager;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.util.StackFormatter;
@PluginDescriptor(
name = "Items Kept on Death",
description = "Updates the Items Kept on Death interface to be more accurate",
enabledByDefault = false
)
@Slf4j
public class ItemsKeptOnDeathPlugin extends Plugin
{
private static final int DEEP_WILDY = 20;
private static final Pattern WILDERNESS_LEVEL_PATTERN = Pattern.compile("^Level: (\\d+).*");
// Item Container helpers
private static final int MAX_ROW_ITEMS = 8;
private static final int ITEM_X_OFFSET = 5;
private static final int ITEM_Y_OFFSET = 25;
private static final int ITEM_X_STRIDE = 38;
private static final int ITEM_Y_STRIDE = 38;
private static final int ORIGINAL_LOST_HEIGHT = 209;
private static final int ORIGINAL_LOST_Y = 107;
// Information panel text helpers
private static final String LINE_BREAK = "<br>";
private static final int INFORMATION_CONTAINER_HEIGHT = 183;
private static final int FONT_COLOR = 0xFF981F;
// Button Images
private static final int PROTECT_ITEM_SPRITE_ID = SpriteID.PRAYER_PROTECT_ITEM;
private static final int SKULL_SPRITE_ID = SpriteID.PLAYER_KILLER_SKULL_523;
private static final int SWORD_SPRITE_ID = SpriteID.MULTI_COMBAT_ZONE_CROSSED_SWORDS;
private static final int SKULL_2_SPRITE_ID = SpriteID.FIGHT_PITS_WINNER_SKULL_RED;
@Inject
private Client client;
@Inject
private ItemManager itemManager;
private WidgetButton deepWildyButton;
private WidgetButton lowWildyButton;
private boolean isSkulled;
private boolean protectingItem;
private int wildyLevel;
@Subscribe
public void onScriptCallbackEvent(ScriptCallbackEvent event)
{
if (event.getEventName().equals("itemsKeptOnDeath"))
{
// The script in charge of building the Items Kept on Death interface has finished running.
// Make all necessary changes now.
// Players inside Safe Areas (POH/Clan Wars) or playing DMM see the default interface
if (isInSafeArea() || client.getWorldType().contains(WorldType.DEADMAN))
{
return;
}
syncSettings();
createWidgetButtons();
rebuildItemsKeptOnDeathInterface();
final Widget keptText = client.getWidget(WidgetInfo.ITEMS_KEPT_ON_DEATH_TEXT);
keptText.setText("Items you will keep on death:");
final Widget lostText = client.getWidget(WidgetInfo.ITEMS_LOST_ON_DEATH_TEXT);
lostText.setText("Items you will lose on death:");
}
}
// Sync user settings
private void syncSettings()
{
final SkullIcon s = client.getLocalPlayer().getSkullIcon();
// Ultimate iron men deaths are treated like they are always skulled
isSkulled = s == SkullIcon.SKULL || isUltimateIronman();
protectingItem = client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 1;
syncWildernessLevel();
}
private void syncWildernessLevel()
{
if (client.getVar(Varbits.IN_WILDERNESS) != 1)
{
// if they are in a PvP world and not in a safe zone act like in lvl 1 wildy
if (isInPvpWorld() && !isInPvPSafeZone())
{
wildyLevel = 1;
return;
}
wildyLevel = -1;
return;
}
final Widget wildernessLevelWidget = client.getWidget(WidgetInfo.PVP_WILDERNESS_LEVEL);
if (wildernessLevelWidget == null)
{
wildyLevel = -1;
return;
}
final String wildernessLevelText = wildernessLevelWidget.getText();
final Matcher m = WILDERNESS_LEVEL_PATTERN.matcher(wildernessLevelText);
if (!m.matches())
{
wildyLevel = -1;
return;
}
wildyLevel = Integer.parseInt(m.group(1));
}
private boolean isInPvpWorld()
{
final EnumSet<WorldType> world = client.getWorldType();
return world.contains(WorldType.PVP);
}
private boolean isProtectItemAllowed()
{
return !client.getWorldType().contains(WorldType.HIGH_RISK)
&& !isUltimateIronman();
}
private boolean isInPvPSafeZone()
{
final Widget w = client.getWidget(WidgetInfo.PVP_WORLD_SAFE_ZONE);
return w != null && !w.isHidden();
}
private boolean isInSafeArea()
{
final Widget w = client.getWidget(WidgetInfo.ITEMS_KEPT_SAFE_ZONE_CONTAINER);
return w != null && !w.isHidden();
}
private boolean isUltimateIronman()
{
return client.getAccountType() == AccountType.ULTIMATE_IRONMAN;
}
private int getDefaultItemsKept()
{
final int count = isSkulled ? 0 : 3;
return count + (protectingItem ? 1 : 0);
}
private void rebuildItemsKeptOnDeathInterface()
{
final Widget lost = client.getWidget(WidgetInfo.ITEMS_LOST_ON_DEATH_CONTAINER);
final Widget kept = client.getWidget(WidgetInfo.ITEMS_KEPT_ON_DEATH_CONTAINER);
if (lost == null || kept == null)
{
return;
}
lost.deleteAllChildren();
kept.deleteAllChildren();
// Grab all items on player
final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
final Item[] inv = inventory == null ? new Item[0] : inventory.getItems();
final ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
final Item[] equip = equipment == null ? new Item[0] : equipment.getItems();
final List<Item> items = new ArrayList<>();
Collections.addAll(items, inv);
Collections.addAll(items, equip);
// Sort by item price
items.sort(Comparator.comparing(this::getDeathPrice).reversed());
boolean hasAlwaysLost = false;
int keepCount = getDefaultItemsKept();
final List<Widget> keptItems = new ArrayList<>();
final List<Widget> lostItems = new ArrayList<>();
for (final Item i : items)
{
final int id = i.getId();
int itemQuantity = i.getQuantity();
if (id == -1)
{
continue;
}
final ItemComposition c = itemManager.getItemComposition(i.getId());
// Bonds are always kept and do not count towards the limit.
if (id == ItemID.OLD_SCHOOL_BOND || id == ItemID.OLD_SCHOOL_BOND_UNTRADEABLE)
{
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
keptItems.add(itemWidget);
continue;
}
// Certain items are always lost on death and have a white outline which we need to add
final AlwaysLostItem alwaysLostItem = AlwaysLostItem.getByItemID(i.getId());
if (alwaysLostItem != null)
{
// Some of these items are kept on death (outside wildy), like the Rune pouch. Ignore them
if (!alwaysLostItem.isKeptOutsideOfWilderness() || wildyLevel > 0)
{
final Widget itemWidget = createItemWidget(lost, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 0, itemQuantity, c.getName());
itemWidget.setBorderType(2); // white outline
lostItems.add(itemWidget);
hasAlwaysLost = true;
continue;
}
// the rune pouch is "always lost" but its kept outside of pvp, and does not count towards your keep count
}
else if (keepCount > 0)
{
// Keep most valuable items regardless of trade-ability.
if (i.getQuantity() > keepCount)
{
final Widget itemWidget = createItemWidget(kept, keepCount, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, keepCount, c.getName());
keptItems.add(itemWidget);
itemQuantity -= keepCount;
keepCount = 0;
// Fall through to below to drop the rest of the stack
}
else
{
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
keptItems.add(itemWidget);
keepCount -= i.getQuantity();
continue;
}
}
// Items are kept if:
// 1) is not tradeable
// 2) is under the deep wilderness line
// 3) is outside of the wilderness, or item has a broken form
if (!Pets.isPet(id)
&& !isTradeable(c) && wildyLevel <= DEEP_WILDY
&& (wildyLevel <= 0 || BrokenOnDeathItem.isBrokenOnDeath(i.getId())))
{
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
keptItems.add(itemWidget);
}
else
{
// Otherwise, the item is lost
final Widget itemWidget = createItemWidget(lost, itemQuantity, c);
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 0, itemQuantity, c.getName());
lostItems.add(itemWidget);
}
}
int rows = (keptItems.size() + MAX_ROW_ITEMS - 1) / MAX_ROW_ITEMS;
// Show an empty row if there isn't anything
if (rows > 0)
{
// ORIGINAL_LOST_Y/HEIGHT includes a row already
rows--;
}
// Adjust items lost container position if new rows were added to kept items container
lost.setOriginalY(ORIGINAL_LOST_Y + (rows * ITEM_Y_STRIDE));
lost.setOriginalHeight(ORIGINAL_LOST_HEIGHT - (rows * ITEM_Y_STRIDE));
positionWidgetItems(kept, keptItems);
positionWidgetItems(lost, lostItems);
updateKeptWidgetInfoText(hasAlwaysLost, keptItems, lostItems);
}
/**
* Get the price of an item
* @param item
* @return
*/
private int getDeathPrice(Item item)
{
int itemId = item.getId();
// Unnote/unplaceholder item
int canonicalizedItemId = itemManager.canonicalize(itemId);
int exchangePrice = itemManager.getItemPrice(canonicalizedItemId);
if (exchangePrice == 0)
{
final ItemComposition c1 = itemManager.getItemComposition(canonicalizedItemId);
exchangePrice = c1.getPrice();
}
else
{
// Some items have artifically applied death prices - such as ring imbues
// which are +2k over the non imbues. Check if the item has a fixed price.
FixedPriceItem fixedPrice = FixedPriceItem.find(canonicalizedItemId);
if (fixedPrice != null)
{
// Apply fixed price offset
exchangePrice += fixedPrice.getOffset();
}
}
return exchangePrice;
}
/**
* Position a list of widget items in the parent container
*/
private static void positionWidgetItems(final Widget parent, final List<Widget> widgets)
{
int startingIndex = 0;
for (final Widget w : widgets)
{
final int originalX = ITEM_X_OFFSET + ((startingIndex % MAX_ROW_ITEMS) * ITEM_X_STRIDE);
final int originalY = ITEM_Y_OFFSET + ((startingIndex / MAX_ROW_ITEMS) * ITEM_Y_STRIDE);
w.setOriginalX(originalX);
w.setOriginalY(originalY);
w.revalidate();
++startingIndex;
}
parent.revalidate();
}
/**
* Creates the text to be displayed in the right side of the interface based on current selections
*/
private String getInfoText(final boolean hasAlwaysLost)
{
final StringBuilder sb = new StringBuilder();
if (isUltimateIronman())
{
sb.append("You are an <col=FFFFFF>UIM<col=FF981F> which means <col=FFFFFF>0<col=FF981F> items are protected by default");
}
else
{
sb.append("<col=FFFFFF>3<col=FF981F> items protected by default");
if (isSkulled)
{
sb.append(LINE_BREAK)
.append("<col=ff3333>PK skull<col=ff981f> -3");
}
if (protectingItem)
{
sb.append(LINE_BREAK)
.append("<col=ff3333>Protect Item prayer<col=ff981f> +1");
}
sb.append(LINE_BREAK)
.append(String.format("Actually protecting <col=FFFFFF>%s<col=FF981F> items", getDefaultItemsKept()));
}
if (wildyLevel < 1)
{
sb.append(LINE_BREAK)
.append(LINE_BREAK)
.append("You will have 1 hour to retrieve your lost items.");
}
if (hasAlwaysLost)
{
sb.append(LINE_BREAK)
.append(LINE_BREAK)
.append("Items with a <col=ffffff>white outline<col=ff981f> will always be lost.");
}
sb.append(LINE_BREAK)
.append(LINE_BREAK)
.append("Untradeable items are kept on death in non-pvp scenarios.");
return sb.toString();
}
/**
* Updates the information panel based on the item containers
*/
private void updateKeptWidgetInfoText(final boolean hasAlwaysLost, final List<Widget> keptItems, final List<Widget> lostItems)
{
// Add Information text widget
final Widget textWidget = findOrCreateInfoText();
textWidget.setText(getInfoText(hasAlwaysLost));
textWidget.revalidate();
// Update Items lost total value
long total = 0;
for (final Widget w : lostItems)
{
int cid = itemManager.canonicalize(w.getItemId());
int price = itemManager.getItemPrice(cid);
if (price == 0)
{
// Default to alch price
price = (int) (itemManager.getItemComposition(cid).getPrice() * Constants.HIGH_ALCHEMY_MULTIPLIER);
}
total += (long) price * w.getItemQuantity();
}
final Widget lostValue = client.getWidget(WidgetInfo.ITEMS_LOST_VALUE);
lostValue.setText(StackFormatter.quantityToStackSize(total) + " gp");
// Update Max items kept
final Widget max = client.getWidget(WidgetInfo.ITEMS_KEPT_MAX);
final int keptQty = keptItems.stream().mapToInt(Widget::getItemQuantity).sum();
max.setText(String.format("<col=ffcc33>Max items kept on death:<br><br><col=ffcc33>~ %d ~", keptQty));
}
/**
* Check if an item is tradeable to another player
*
* @param c The item
* @return
*/
private static boolean isTradeable(final ItemComposition c)
{
// ItemComposition:: isTradeable checks if they are traded on the grand exchange, some items are trade-able but not via GE
if (c.getNote() != -1
|| c.getLinkedNoteId() != -1
|| c.isTradeable())
{
return true;
}
final int id = c.getId();
switch (id)
{
case ItemID.COINS_995:
case ItemID.PLATINUM_TOKEN:
return true;
default:
return false;
}
}
private Widget findOrCreateInfoText()
{
// The text was on the ITEMS_KEPT_INFORMATION_CONTAINER widget - but now that it is a layer,
// we need to create a child widget to hold the text
final Widget parent = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
// Use the text TEXT widget if it already exists. It should be the last child of the parent
final Widget[] children = parent.getChildren();
if (children != null && children.length > 0)
{
final Widget w = parent.getChild(children.length - 1);
if (w != null && w.getType() == WidgetType.TEXT)
{
log.debug("Reusing old text widget");
return w;
}
}
log.debug("Creating new text widget");
final Widget w = parent.createChild(-1, WidgetType.TEXT);
// Position under buttons taking remaining space
w.setOriginalWidth(parent.getOriginalWidth());
w.setOriginalHeight(INFORMATION_CONTAINER_HEIGHT - parent.getOriginalHeight());
w.setOriginalY(parent.getOriginalHeight());
w.setFontId(FontID.PLAIN_11);
w.setTextShadowed(true);
w.setTextColor(FONT_COLOR);
// Need to adjust parent height so text is visible
parent.setOriginalHeight(INFORMATION_CONTAINER_HEIGHT);
parent.revalidate();
return w;
}
private void createWidgetButtons()
{
final Widget parent = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
// Change the information container from a text widget to a layer
parent.setType(WidgetType.LAYER);
parent.deleteAllChildren();
// Ultimate Iron men are always skulled and can't use the protect item prayer
WidgetButton protectItemButton = isProtectItemAllowed()
? new WidgetButton(parent, "Protect Item Prayer", PROTECT_ITEM_SPRITE_ID, protectingItem, selected ->
{
protectingItem = selected;
rebuildItemsKeptOnDeathInterface();
}) : null;
WidgetButton skulledButton = !isUltimateIronman()
? new WidgetButton(parent, "Skulled", SKULL_SPRITE_ID, isSkulled, selected ->
{
isSkulled = selected;
rebuildItemsKeptOnDeathInterface();
}) : null;
lowWildyButton = new WidgetButton(parent, "Low Wildy (1-20)", SWORD_SPRITE_ID, wildyLevel > 0 && wildyLevel <= DEEP_WILDY, selected ->
{
if (!selected)
{
syncWildernessLevel();
}
else
{
wildyLevel = 1;
deepWildyButton.setSelected(false);
}
rebuildItemsKeptOnDeathInterface();
});
deepWildyButton = new WidgetButton(parent, "Deep Wildy (21+)", SKULL_2_SPRITE_ID, wildyLevel > DEEP_WILDY, selected ->
{
if (!selected)
{
syncWildernessLevel();
}
else
{
wildyLevel = DEEP_WILDY + 1;
lowWildyButton.setSelected(false);
}
rebuildItemsKeptOnDeathInterface();
});
parent.revalidate();
WidgetButton.layoutButtonsToContainer(parent, protectItemButton, skulledButton, lowWildyButton, deepWildyButton);
}
/**
* Creates an Item Widget for use inside the Kept on Death Interface
*
* @param qty Amount of item
* @param c Items Composition
* @return
*/
private static Widget createItemWidget(final Widget parent, final int qty, final ItemComposition c)
{
final Widget itemWidget = parent.createChild(-1, WidgetType.GRAPHIC);
itemWidget.setItemId(c.getId());
itemWidget.setItemQuantity(qty);
itemWidget.setHasListener(true);
itemWidget.setOriginalWidth(Constants.ITEM_SPRITE_WIDTH);
itemWidget.setOriginalHeight(Constants.ITEM_SPRITE_HEIGHT);
itemWidget.setBorderType(1);
itemWidget.setAction(1, String.format("Item: <col=ff981f>%s", c.getName()));
return itemWidget;
}
}
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2018 Abex
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.itemskeptondeath;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import static net.runelite.api.ItemID.*;
final class Pets
{
private Pets()
{
}
private static final Set<Integer> PETS = ImmutableSet.of(
BABY_MOLE,
PRINCE_BLACK_DRAGON,
PET_CORPOREAL_CRITTER, PET_DARK_CORE,
JALNIBREK, TZREKZUK,
KALPHITE_PRINCESS, KALPHITE_PRINCESS_12654,
LIL_ZIK,
SKOTOS,
PET_SNAKELING, PET_SNAKELING_12939, PET_SNAKELING_12940,
TZREKJAD,
VORKI,
OLMLET, PUPPADILE, TEKTINY, VANGUARD, VASA_MINIRIO, VESPINA,
PET_DAGANNOTH_PRIME, PET_DAGANNOTH_REX, PET_DAGANNOTH_SUPREME,
PET_GENERAL_GRAARDOR, PET_KRIL_TSUTSAROTH, PET_KREEARRA, PET_ZILYANA,
ABYSSAL_ORPHAN,
HELLPUPPY,
PET_KRAKEN,
MIDNIGHT, NOON,
PET_SMOKE_DEVIL, PET_SMOKE_DEVIL_22663,
IKKLE_HYDRA, IKKLE_HYDRA_22748, IKKLE_HYDRA_22750, IKKLE_HYDRA_22752,
CALLISTO_CUB,
PET_CHAOS_ELEMENTAL,
SCORPIAS_OFFSPRING,
VENENATIS_SPIDERLING,
VETION_JR, VETION_JR_13180,
BABY_CHINCHOMPA, BABY_CHINCHOMPA_13324, BABY_CHINCHOMPA_13325, BABY_CHINCHOMPA_13326,
BEAVER,
GIANT_SQUIRREL,
HERON,
RIFT_GUARDIAN, RIFT_GUARDIAN_20667, RIFT_GUARDIAN_20669, RIFT_GUARDIAN_20671, RIFT_GUARDIAN_20673, RIFT_GUARDIAN_20675,
RIFT_GUARDIAN_20677, RIFT_GUARDIAN_20679, RIFT_GUARDIAN_20681, RIFT_GUARDIAN_20683, RIFT_GUARDIAN_20685, RIFT_GUARDIAN_20687,
RIFT_GUARDIAN_20689, RIFT_GUARDIAN_20691, RIFT_GUARDIAN_21990,
ROCK_GOLEM, ROCK_GOLEM_21187, ROCK_GOLEM_21188, ROCK_GOLEM_21189, ROCK_GOLEM_21190, ROCK_GOLEM_21191, ROCK_GOLEM_21192,
ROCK_GOLEM_21193, ROCK_GOLEM_21194, ROCK_GOLEM_21195, ROCK_GOLEM_21196, ROCK_GOLEM_21197, ROCK_GOLEM_21340, ROCK_GOLEM_21358,
ROCK_GOLEM_21359, ROCK_GOLEM_21360,
ROCKY,
TANGLEROOT,
PET_KITTEN, PET_KITTEN_1556, PET_KITTEN_1557, PET_KITTEN_1558, PET_KITTEN_1559, PET_KITTEN_1560,
PET_CAT, PET_CAT_1562, PET_CAT_1563, PET_CAT_1564, PET_CAT_1565, PET_CAT_1566, PET_CAT_1567, PET_CAT_1568, PET_CAT_1569,
PET_CAT_1570, PET_CAT_1571, PET_CAT_1572,
LAZY_CAT, LAZY_CAT_6550, LAZY_CAT_6551, LAZY_CAT_6552, LAZY_CAT_6553, LAZY_CAT_6554,
WILY_CAT, WILY_CAT_6556, WILY_CAT_6557, WILY_CAT_6558, WILY_CAT_6559, WILY_CAT_6560,
OVERGROWN_HELLCAT, HELL_CAT, HELLKITTEN, LAZY_HELL_CAT, WILY_HELLCAT,
BLOODHOUND,
CHOMPY_CHICK,
HERBI,
PET_PENANCE_QUEEN,
PHOENIX
);
public static boolean isPet(int id)
{
return PETS.contains(id);
}
}
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
* 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.itemskeptondeath;
import net.runelite.api.ScriptEvent;
import net.runelite.api.SpriteID;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetType;
class WidgetButton
{
private static final int ICON_HEIGHT = 26;
private static final int ICON_WIDTH = 26;
private static final int BACKGROUND_HEIGHT = 32;
private static final int BACKGROUND_WIDTH = 32;
private static final int PADDING = 5;
private static final int ICON_PADDING = (BACKGROUND_HEIGHT - ICON_HEIGHT) / 2;
private static final int BACKGROUND_SPRITE_ID = SpriteID.EQUIPMENT_SLOT_TILE;
private static final int SELECTED_BACKGROUND_SPRITE_ID = SpriteID.EQUIPMENT_SLOT_SELECTED;
@FunctionalInterface
public interface WidgetButtonCallback
{
void run(boolean newState);
}
private final Widget parent;
private final String name;
private final int spriteID;
private boolean selected;
private final WidgetButtonCallback callback;
private Widget icon;
private Widget background;
WidgetButton(
final Widget parent,
final String name,
final int spriteID,
final boolean selectedStartState,
final WidgetButtonCallback callback)
{
this.parent = parent;
this.name = name;
this.spriteID = spriteID;
this.selected = selectedStartState;
this.callback = callback;
createBackgroundWidget();
createIconWidget();
}
private void createBackgroundWidget()
{
background = createWidget();
background.setOriginalWidth(BACKGROUND_WIDTH);
background.setOriginalHeight(BACKGROUND_HEIGHT);
syncBackgroundSprite();
}
private void createIconWidget()
{
icon = createWidget();
icon.setAction(1, "Toggle:");
icon.setOnOpListener((JavaScriptCallback) this::onButtonClicked);
icon.setOnMouseRepeatListener((JavaScriptCallback) e -> e.getSource().setOpacity(120));
icon.setOnMouseLeaveListener((JavaScriptCallback) e -> e.getSource().setOpacity(0));
icon.setHasListener(true);
icon.setSpriteId(spriteID);
}
private Widget createWidget()
{
final Widget w = parent.createChild(-1, WidgetType.GRAPHIC);
w.setOriginalWidth(ICON_WIDTH);
w.setOriginalHeight(ICON_HEIGHT);
w.setName("<col=ff981f>" + this.name);
return w;
}
public void setSelected(boolean selected)
{
this.selected = selected;
syncBackgroundSprite();
}
private void syncBackgroundSprite()
{
background.setSpriteId(selected ? SELECTED_BACKGROUND_SPRITE_ID : BACKGROUND_SPRITE_ID);
}
/**
* Adds the collection of WidgetButtons to the container overriding any existing children.
*
* @param container Widget to add buttons too
* @param buttons buttons to add
*/
static void layoutButtonsToContainer(final Widget container, final WidgetButton... buttons)
{
// Each button has two widgets, Icon and Background
final int xIncrement = BACKGROUND_WIDTH + PADDING;
final int yIncrement = BACKGROUND_HEIGHT + PADDING;
int maxRowItems = container.getWidth() / xIncrement;
// Ensure at least 1 button per row
maxRowItems = maxRowItems < 1 ? 1 : maxRowItems;
int index = 0;
for (final WidgetButton w : buttons)
{
if (w == null)
{
continue;
}
final int originalX = ((index % maxRowItems) * xIncrement);
final int originalY = ((index / maxRowItems) * yIncrement);
w.background.setOriginalX(originalX);
w.background.setOriginalY(originalY);
w.background.revalidate();
// Icon must be padded to center inside image
w.icon.setOriginalX(originalX + ICON_PADDING);
w.icon.setOriginalY(originalY + ICON_PADDING);
w.icon.revalidate();
index++;
}
final int numButtons = index;
final int rows = 1 + (numButtons > maxRowItems ? numButtons / maxRowItems : 0);
container.setOriginalHeight(yIncrement * rows);
container.revalidate();
}
private void onButtonClicked(ScriptEvent scriptEvent)
{
setSelected(!selected);
callback.run(selected);
}
}
@@ -92,6 +92,16 @@ public interface ItemStatConfig extends Config
return false;
}
@ConfigItem(
keyName = "showWeight",
name = "Show Weight",
description = "Show weight in tooltip"
)
default boolean showWeight()
{
return true;
}
@ConfigItem(
keyName = "colorBetterUncapped",
name = "Better (Uncapped)",
@@ -189,7 +189,10 @@ public class ItemStatOverlay extends Overlay
private String buildStatBonusString(ItemStats s)
{
final StringBuilder b = new StringBuilder();
b.append(getChangeString("Weight", s.getWeight(), true, false));
if (config.showWeight())
{
b.append(getChangeString("Weight", s.getWeight(), true, false));
}
ItemStats other = null;
final ItemEquipmentStats currentEquipment = s.getEquipment();
@@ -35,6 +35,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import net.runelite.api.Client;
import net.runelite.api.Constants;
import net.runelite.api.FontID;
import net.runelite.api.InventoryID;
import net.runelite.api.Item;
@@ -232,8 +233,8 @@ public class ItemStatPlugin extends Plugin
Widget icon = invContainer.createChild(-1, WidgetType.GRAPHIC);
icon.setOriginalX(8);
icon.setOriginalY(yPos);
icon.setOriginalWidth(36);
icon.setOriginalHeight(32);
icon.setOriginalWidth(Constants.ITEM_SPRITE_WIDTH);
icon.setOriginalHeight(Constants.ITEM_SPRITE_HEIGHT);
icon.setItemId(id);
icon.setItemQuantityMode(0);
icon.setBorderType(1);
@@ -47,7 +47,7 @@ class MiningOverlay extends Overlay
{
// Range of Motherlode vein respawn time not 100% confirmed but based on observation
@Getter(AccessLevel.PACKAGE)
private static final int ORE_VEIN_MAX_RESPAWN_TIME = 123;
public static final int ORE_VEIN_MAX_RESPAWN_TIME = 123;
private static final int ORE_VEIN_MIN_RESPAWN_TIME = 90;
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);
@@ -168,6 +168,7 @@ public class MiningPlugin extends Plugin
case ORE_VEIN_26663: // Motherlode vein
case ORE_VEIN_26664: // Motherlode vein
{
// If the vein respawns before the timer is up, remove it
final WorldPoint point = object.getWorldLocation();
respawns.removeIf(rockRespawn -> rockRespawn.getWorldPoint().equals(point));
break;
@@ -49,6 +49,7 @@ import static net.runelite.api.ObjectID.ROCKS_11376;
import static net.runelite.api.ObjectID.ROCKS_11377;
import static net.runelite.api.ObjectID.ROCKS_11386;
import static net.runelite.api.ObjectID.ROCKS_11387;
import static net.runelite.api.ObjectID.ASH_PILE;
enum Rock
{
@@ -98,8 +99,9 @@ enum Rock
return inMiningGuild ? Duration.ofMinutes(6) : super.respawnTime;
}
},
ORE_VEIN(Duration.ofSeconds(MiningOverlay.getORE_VEIN_MAX_RESPAWN_TIME()), 150),
AMETHYST(Duration.ofSeconds(75), 120);
ORE_VEIN(Duration.ofSeconds(MiningOverlay.ORE_VEIN_MAX_RESPAWN_TIME), 150),
AMETHYST(Duration.ofSeconds(75), 120),
ASH_VEIN(Duration.ofSeconds(30), 0, ASH_PILE);
private static final Map<Integer, Rock> ROCKS;
@@ -784,7 +784,7 @@ public class SlayerPlugin extends Plugin
private boolean doubleTroubleExtraKill()
{
return WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()).getRegionID() == GROTESQUE_GUARDIANS_REGION &&
SlayerUnlock.GROTESQUE_GARDIAN_DOUBLE_COUNT.isEnabled(client);
SlayerUnlock.GROTESQUE_GUARDIAN_DOUBLE_COUNT.isEnabled(client);
}
// checks if any contiguous subsequence of seq0 exactly matches the String toMatch
@@ -126,13 +126,13 @@ public class TimersPlugin extends Plugin
private static final String CANNON_REPAIR_MESSAGE = "You repair your cannon, restoring it to working order.";
private static final String CHARGE_EXPIRED_MESSAGE = "<col=ef1020>Your magical charge fades away.</col>";
private static final String CHARGE_MESSAGE = "<col=ef1020>You feel charged with magic power.</col>";
private static final String DEADMAN_HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A teleblock spell has been cast on you. It will expire in 1 minute, 15 seconds.</col>";
private static final String DEADMAN_HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A Tele Block spell has been cast on you. It will expire in 1 minute, 15 seconds.</col>";
private static final String EXTENDED_ANTIFIRE_DRINK_MESSAGE = "You drink some of your extended antifire potion.";
private static final String EXTENDED_SUPER_ANTIFIRE_DRINK_MESSAGE = "You drink some of your extended super antifire potion.";
private static final String FROZEN_MESSAGE = "<col=ef1020>You have been frozen!</col>";
private static final String FULL_TELEBLOCK_MESSAGE = "<col=4f006f>A teleblock spell has been cast on you. It will expire in 5 minutes, 0 seconds.</col>";
private static final String FULL_TELEBLOCK_MESSAGE = "<col=4f006f>A Tele Block spell has been cast on you. It will expire in 5 minutes, 0 seconds.</col>";
private static final String GOD_WARS_ALTAR_MESSAGE = "you recharge your prayer.";
private static final String HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A teleblock spell has been cast on you. It will expire in 2 minutes, 30 seconds.</col>";
private static final String HALF_TELEBLOCK_MESSAGE = "<col=4f006f>A Tele Block spell has been cast on you. It will expire in 2 minutes, 30 seconds.</col>";
private static final String IMBUED_HEART_READY_MESSAGE = "<col=ef1020>Your imbued heart has regained its magical power.</col>";
private static final String IMBUED_HEART_NOTREADY_MESSAGE = "The heart is still drained of its power.";
private static final String MAGIC_IMBUE_EXPIRED_MESSAGE = "Your Magic Imbue charge has ended.";
@@ -35,6 +35,7 @@ import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import net.runelite.api.Constants;
import net.runelite.client.game.ItemManager;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
@@ -60,7 +61,7 @@ class OverviewItemPanel extends JPanel
setBorder(new EmptyBorder(7, 7, 7, 7));
JLabel iconLabel = new JLabel();
iconLabel.setMinimumSize(new Dimension(36, 32));
iconLabel.setMinimumSize(new Dimension(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT));
itemManager.getImage(tab.getItemID()).addTo(iconLabel);
add(iconLabel, BorderLayout.WEST);
@@ -33,6 +33,7 @@ import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import lombok.Getter;
import net.runelite.api.Constants;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.components.ThinProgressBar;
@@ -58,7 +59,7 @@ public class TimeablePanel<T> extends JPanel
topContainer.setLayout(new BorderLayout());
topContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
icon.setMinimumSize(new Dimension(36, 32));
icon.setMinimumSize(new Dimension(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT));
JPanel infoPanel = new JPanel();
infoPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
@@ -27,151 +27,159 @@ package net.runelite.client.plugins.worldmap;
import lombok.Getter;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.Quest;
// Some quests are in the same spot, but they are done in order. If multiple
// quests start in the same location, an array of quests is expected.
enum QuestStartLocation
{
//Free Quests
COOKS_ASSISTANT_RFD("Cook's Assistant", new WorldPoint(3211, 3216, 0)),
THE_CORSAIR_CURSE("The Corsair Curse", new WorldPoint(3029, 3273, 0)),
DEMON_SLAYER("Demon Slayer", new WorldPoint(3204, 3424, 0)),
DORICS_QUEST("Doric's Quest", new WorldPoint(2952, 3450, 0)),
DRAGON_SLAYER("Dragon Slayer", new WorldPoint(3190, 3362, 0)),
ERNEST_THE_CHICKEN("Ernest the Chicken", new WorldPoint(3109, 3330, 0)),
GOBLIN_DIPLOMACY("Goblin Diplomacy", new WorldPoint(2957, 3509, 0)),
IMP_CATCHER("Imp Catcher", new WorldPoint(3108, 3160, 0)),
THE_KNIGHTS_SWORD("The Knight's Sword", new WorldPoint(2976, 3342, 0)),
MISTHALIN_MYSTERY("Misthalin Mystery", new WorldPoint(3234, 3155, 0)),
PIRATES_TREASURE("Pirate's Treasure", new WorldPoint(3051, 3252, 0)),
PRINCE_ALI_RESCUE("Prince Ali Rescue", new WorldPoint(3301, 3163, 0)),
THE_RESTLESS_GHOST("The Restless Ghost", new WorldPoint(3240, 3210, 0)),
RUNE_MYSTERIES("Rune Mysteries", new WorldPoint(3210, 3220, 0)),
SHEEP_SHEARER("Sheep Shearer", new WorldPoint(3190, 3272, 0)),
SHIELD_OF_ARRAV_PHOENIX_GANG("Shield of Arrav (Phoenix Gang)", new WorldPoint(3208, 3495, 0)),
SHIELD_OF_ARRAV_BLACK_ARM_GANG("Shield of Arrav (Black Arm Gang)", new WorldPoint(3208, 3392, 0)),
VAMPIRE_SLAYER("Vampire Slayer", new WorldPoint(3096, 3266, 0)),
WITCHS_POTION("Witch's Potion", new WorldPoint(2967, 3203, 0)),
X_MARKS_THE_SPOT("X Marks the Spot", new WorldPoint(3227, 3242, 0)),
COOKS_ASSISTANT_RFD(Quest.COOKS_ASSISTANT, new WorldPoint(3211, 3216, 0)),
THE_CORSAIR_CURSE(Quest.THE_CORSAIR_CURSE, new WorldPoint(3029, 3273, 0)),
DEMON_SLAYER(Quest.DEMON_SLAYER, new WorldPoint(3204, 3424, 0)),
DORICS_QUEST(Quest.DORICS_QUEST, new WorldPoint(2952, 3450, 0)),
DRAGON_SLAYER(Quest.DRAGON_SLAYER, new WorldPoint(3190, 3362, 0)),
ERNEST_THE_CHICKEN(Quest.ERNEST_THE_CHICKEN, new WorldPoint(3109, 3330, 0)),
GOBLIN_DIPLOMACY(Quest.GOBLIN_DIPLOMACY, new WorldPoint(2957, 3509, 0)),
IMP_CATCHER(Quest.IMP_CATCHER, new WorldPoint(3108, 3160, 0)),
THE_KNIGHTS_SWORD(Quest.THE_KNIGHTS_SWORD, new WorldPoint(2976, 3342, 0)),
MISTHALIN_MYSTERY(Quest.MISTHALIN_MYSTERY, new WorldPoint(3234, 3155, 0)),
PIRATES_TREASURE(Quest.PIRATES_TREASURE, new WorldPoint(3051, 3252, 0)),
PRINCE_ALI_RESCUE(Quest.PRINCE_ALI_RESCUE, new WorldPoint(3301, 3163, 0)),
THE_RESTLESS_GHOST(Quest.THE_RESTLESS_GHOST, new WorldPoint(3240, 3210, 0)),
RUNE_MYSTERIES(Quest.RUNE_MYSTERIES, new WorldPoint(3210, 3220, 0)),
SHEEP_SHEARER(Quest.SHEEP_SHEARER, new WorldPoint(3190, 3272, 0)),
SHIELD_OF_ARRAV(Quest.SHIELD_OF_ARRAV, new WorldPoint(3208, 3495, 0)),
VAMPIRE_SLAYER(Quest.VAMPIRE_SLAYER, new WorldPoint(3096, 3266, 0)),
WITCHS_POTION(Quest.WITCHS_POTION, new WorldPoint(2967, 3203, 0)),
X_MARKS_THE_SPOT(Quest.X_MARKS_THE_SPOT, new WorldPoint(3227, 3242, 0)),
//Members' Quests
ANIMAL_MAGNETISM("Animal Magnetism", new WorldPoint(3094, 3360, 0)),
ANOTHER_SLICE_OF_HAM("Another Slice of H.A.M.", new WorldPoint(2799, 5428, 0)),
THE_ASCENT_OF_ARCEUUS("The Ascent of Arceuus", new WorldPoint(1700, 3742, 0)),
BETWEEN_A_ROCK("Between a Rock...", new WorldPoint(2823, 10168, 0)),
BIG_CHOMPY_BIRD_HUNTING("Big Chompy Bird Hunting", new WorldPoint(2629, 2981, 0)),
BIOHAZARD("Biohazard", new WorldPoint(2591, 3335, 0)),
BONE_VOYAGE("Bone Voyage", new WorldPoint(3259, 3450, 0)),
CABIN_FEVER("Cabin Fever", new WorldPoint(3674, 3496, 0)),
CLIENT_OF_KOUREND("Client of Kourend", new WorldPoint(1823, 3690, 0)),
CLOCK_TOWER("Clock Tower", new WorldPoint(2568, 3249, 0)),
COLD_WAR("Cold War", new WorldPoint(2593, 3265, 0)),
CONTACT("Contact!", new WorldPoint(3280, 2770, 0)),
CREATURE_OF_FENKENSTRAIN("Creature of Fenkenstrain", new WorldPoint(3487, 3485, 0)),
DARKNESS_OF_HALLOWVALE("Darkness of Hallowvale", new WorldPoint(3494, 9628, 0)),
DEATH_PLATEAU_TROLL_STRONGHOLD("Death Plateau & Troll Stronghold", new WorldPoint(2895, 3528, 0)),
DEATH_TO_THE_DORGESHUUN("Death to the Dorgeshuun", new WorldPoint(3316, 9613, 0)),
THE_DEPTHS_OF_DESPAIR("The Depths of Despair", new WorldPoint(1846, 3556, 0)),
DESERT_TREASURE("Desert Treasure", new WorldPoint(3177, 3043, 0)),
DEVIOUS_MINDS("Devious Minds", new WorldPoint(3405, 3492, 0)),
THE_DIG_SITE("The Dig Site", new WorldPoint(3363, 3337, 0)),
DRAGON_SLAYER_II("Dragon Slayer II", new WorldPoint(2456, 2868, 0)),
DREAM_MENTOR("Dream Mentor", new WorldPoint(2144, 10346, 0)),
DRUIDIC_RITUAL("Druidic Ritual", new WorldPoint(2916, 3484, 0)),
DWARF_CANNON("Dwarf Cannon", new WorldPoint(2566, 3461, 0)),
EADGARS_RUSE("Eadgar's Ruse", new WorldPoint(2896, 3426, 0)),
EAGLES_PEAK("Eagles' Peak", new WorldPoint(2605, 3264, 0)),
ELEMENTAL_WORKSHOP("Elemental Workshop I & II", new WorldPoint(2714, 3482, 0)),
ENAKHRAS_LAMENT("Enakhra's Lament", new WorldPoint(3190, 2926, 0)),
ENLIGHTENED_JOURNEY("Enlightened Journey", new WorldPoint(2809, 3356, 0)),
THE_EYES_OF_GLOUPHRIE("The Eyes of Glouphrie", new WorldPoint(2400, 3419, 0)),
FAIRYTALE("Fairytale I & II", new WorldPoint(3077, 3258, 0)),
FAMILY_CREST("Family Crest", new WorldPoint(3278, 3404, 0)),
THE_FEUD("The Feud", new WorldPoint(3301, 3211, 0)),
FIGHT_ARENA("Fight Arena", new WorldPoint(2565, 3199, 0)),
FISHING_CONTEST_1("Fishing Contest", new WorldPoint(2875, 3483, 0)),
FISHING_CONTEST_2("Fishing Contest", new WorldPoint(2820, 3487, 0)),
FORGETTABLE_TALE("Forgettable Tale...", new WorldPoint(2826, 10215, 0)),
THE_FORSAKEN_TOWER("The Forsaken Tower", new WorldPoint(1484, 3747, 0)),
THE_FREMENNIK_ISLES("The Fremennik Isles", new WorldPoint(2645, 3711, 0)),
THE_FREMENNIK_TRIALS("The Fremennik Trials", new WorldPoint(2657, 3669, 0)),
GARDEN_OF_TRANQUILLITY("Garden of Tranquillity", new WorldPoint(3227, 3477, 0)),
GERTRUDES_CAT_RATCATCHERS("Gertrude's Cat & Ratcatchers", new WorldPoint(3150, 3411, 0)),
GHOSTS_AHOY("Ghosts Ahoy", new WorldPoint(3677, 3510, 0)),
THE_GIANT_DWARF("The Giant Dwarf", new WorldPoint(2841, 10129, 0)),
THE_GOLEM("The Golem", new WorldPoint(3487, 3089, 0)),
THE_GRAND_TREE_MONKEY_MADNESS("The Grand Tree & Monkey Madness I & II", new WorldPoint(2466, 3497, 0)),
THE_GREAT_BRAIN_ROBBERY("The Great Brain Robbery", new WorldPoint(3681, 2963, 0)),
GRIM_TALES("Grim Tales", new WorldPoint(2890, 3454, 0)),
THE_HAND_IN_THE_SAND("The Hand in the Sand", new WorldPoint(2552, 3101, 0)),
HAUNTED_MINE("Haunted Mine", new WorldPoint(3443, 3258, 0)),
HAZEEL_CULT("Hazeel Cult", new WorldPoint(2565, 3271, 0)),
HEROES_QUEST("Heroes' Quest", new WorldPoint(2903, 3511, 0)),
HOLY_GRAIL("Holy Grail & Merlin's Crystal", new WorldPoint(2763, 3515, 0)),
HORROR_FROM_THE_DEEP("Horror from the Deep", new WorldPoint(2507, 3635, 0)),
ICTHLARINS_LITTLE_HELPER("Icthlarin's Little Helper", new WorldPoint(3314, 2849, 0)),
IN_SEARCH_OF_THE_MYREQUE("In Search of the Myreque", new WorldPoint(3502, 3477, 0)),
JUNGLE_POTION("Jungle Potion", new WorldPoint(2809, 3086, 0)),
KINGS_RANSOM("King's Ransom", new WorldPoint(2741, 3554, 0)),
LEGENDS_QUEST("Legends' Quest", new WorldPoint(2725, 3367, 0)),
LOST_CITY("Lost City", new WorldPoint(3149, 3205, 0)),
THE_LOST_TRIBE("The Lost Tribe", new WorldPoint(3211, 3224, 0)),
LUNAR_DIPLOMACY("Lunar Diplomacy", new WorldPoint(2619, 3689, 0)),
MAKING_FRIENDS_WITH_MY_ARM("Making Friends with My Arm", new WorldPoint(2904, 10092, 0)),
MAKING_HISTORY("Making History", new WorldPoint(2435, 3346, 0)),
MONKS_FRIEND("Monk's Friend", new WorldPoint(2605, 3209, 0)),
MOUNTAIN_DAUGHTER("Mountain Daughter", new WorldPoint(2810, 3672, 0)),
MOURNINGS_ENDS_PART_I("Mourning's Ends Part I", new WorldPoint(2289, 3149, 0)),
MOURNINGS_ENDS_PART_II("Mourning's Ends Part II", new WorldPoint(2352, 3172, 0)),
MURDER_MYSTERY("Murder Mystery", new WorldPoint(2740, 3562, 0)),
MY_ARMS_BIG_ADVENTURE("My Arm's Big Adventure", new WorldPoint(2908, 10088, 0)),
NATURE_SPIRIT("Nature Spirit", new WorldPoint(3440, 9894, 0)),
OBSERVATORY_QUEST("Observatory Quest", new WorldPoint(2438, 3185, 0)),
OLAFS_QUEST("Olaf's Quest", new WorldPoint(2723, 3729, 0)),
ONE_SMALL_FAVOUR("One Small Favour", new WorldPoint(2834, 2985, 0)),
PLAGUE_CITY("Plague City", new WorldPoint(2567, 3334, 0)),
PRIEST_IN_PERIL("Priest in Peril", new WorldPoint(3219, 3473, 0)),
THE_QUEEN_OF_THIEVES("The Queen of Thieves", new WorldPoint(1795, 3782, 0)),
RAG_AND_BONE_MAN("Rag and Bone Man I & II", new WorldPoint(3359, 3504, 0)),
RECRUITMENT_DRIVE_BLACK_KNIGHTS_FORTRESS("Recruitment Drive & Black Knights' Fortress", new WorldPoint(2959, 3336, 0)),
ROVING_ELVES("Roving Elves", new WorldPoint(2289, 3146, 0)),
RUM_DEAL("Rum Deal", new WorldPoint(3679, 3535, 0)),
SCORPION_CATCHER("Scorpion Catcher", new WorldPoint(2701, 3399, 0)),
SEA_SLUG("Sea Slug", new WorldPoint(2715, 3302, 0)),
SHADES_OF_MORTTON("Shades of Mort'ton", new WorldPoint(3463, 3308, 0)),
SHADOW_OF_THE_STORM("Shadow of the Storm", new WorldPoint(3270, 3159, 0)),
SHEEP_HERDER("Sheep Herder", new WorldPoint(2616, 3299, 0)),
SHILO_VILLAGE("Shilo Village", new WorldPoint(2882, 2951, 0)),
A_SOULS_BANE("A Soul's Bane", new WorldPoint(3307, 3454, 0)),
SPIRITS_OF_THE_ELID("Spirits of the Elid", new WorldPoint(3441, 2911, 0)),
SWAN_SONG("Swan Song", new WorldPoint(2345, 3652, 0)),
TAI_BWO_WANNAI_TRIO("Tai Bwo Wannai Trio", new WorldPoint(2779, 3087, 0)),
A_TAIL_OF_TWO_CATS("A Tail of Two Cats", new WorldPoint(2917, 3557, 0)),
TALE_OF_THE_RIGHTEOUS("Tale of the Righteous", new WorldPoint(1511, 3631, 0)),
A_TASTE_OF_HOPE("A Taste of Hope", new WorldPoint(3668, 3216, 0)),
TEARS_OF_GUTHIX("Tears of Guthix", new WorldPoint(3251, 9517, 0)),
TEMPLE_OF_IKOV("Temple of Ikov", new WorldPoint(2574, 3320, 0)),
THRONE_OF_MISCELLANIA_ROYAL_TROUBLE("Throne of Miscellania & Royal Trouble", new WorldPoint(2497, 3859, 0)),
THE_TOURIST_TRAP("The Tourist Trap", new WorldPoint(3302, 3113, 0)),
TOWER_OF_LIFE("Tower of Life", new WorldPoint(2640, 3218, 0)),
TREE_GNOME_VILLAGE("Tree Gnome Village", new WorldPoint(2541, 3169, 0)),
TRIBAL_TOTEM("Tribal Totem", new WorldPoint(2790, 3182, 0)),
TROLL_ROMANCE("Troll Romance", new WorldPoint(2890, 10097, 0)),
UNDERGROUND_PASS_REGICIDE("Underground Pass & Regicide", new WorldPoint(2575, 3293, 0)),
WANTED_SLUG_MENACE("Wanted! & The Slug Menace", new WorldPoint(2996, 3373, 0)),
WATCHTOWER("Watchtower", new WorldPoint(2545, 3112, 0)),
WATERFALL_QUEST("Waterfall Quest", new WorldPoint(2521, 3498, 0)),
WHAT_LIES_BELOW("What Lies Below", new WorldPoint(3265, 3333, 0)),
WITCHS_HOUSE("Witch's House", new WorldPoint(2927, 3456, 0)),
ZOGRE_FLESH_EATERS("Zogre Flesh Eaters", new WorldPoint(2442, 3051, 0));
@Getter
private final String tooltip;
ANIMAL_MAGNETISM(Quest.ANIMAL_MAGNETISM, new WorldPoint(3094, 3360, 0)),
ANOTHER_SLICE_OF_HAM(Quest.ANOTHER_SLICE_OF_HAM, new WorldPoint(2799, 5428, 0)),
THE_ASCENT_OF_ARCEUUS(Quest.THE_ASCENT_OF_ARCEUUS, new WorldPoint(1700, 3742, 0)),
BETWEEN_A_ROCK(Quest.BETWEEN_A_ROCK, new WorldPoint(2823, 10168, 0)),
BIG_CHOMPY_BIRD_HUNTING(Quest.BIG_CHOMPY_BIRD_HUNTING, new WorldPoint(2629, 2981, 0)),
BIOHAZARD(Quest.BIOHAZARD, new WorldPoint(2591, 3335, 0)),
BONE_VOYAGE(Quest.BONE_VOYAGE, new WorldPoint(3259, 3450, 0)),
CABIN_FEVER(Quest.CABIN_FEVER, new WorldPoint(3674, 3496, 0)),
CLIENT_OF_KOUREND(Quest.CLIENT_OF_KOUREND, new WorldPoint(1823, 3690, 0)),
CLOCK_TOWER(Quest.CLOCK_TOWER, new WorldPoint(2568, 3249, 0)),
COLD_WAR(Quest.COLD_WAR, new WorldPoint(2593, 3265, 0)),
CONTACT(Quest.CONTACT, new WorldPoint(3280, 2770, 0)),
CREATURE_OF_FENKENSTRAIN(Quest.CREATURE_OF_FENKENSTRAIN, new WorldPoint(3487, 3485, 0)),
DARKNESS_OF_HALLOWVALE(Quest.DARKNESS_OF_HALLOWVALE, new WorldPoint(3494, 9628, 0)),
DEATH_PLATEAU_TROLL_STRONGHOLD(new Quest[]{Quest.DEATH_PLATEAU, Quest.TROLL_STRONGHOLD}, new WorldPoint(2895, 3528, 0)),
DEATH_TO_THE_DORGESHUUN(Quest.DEATH_TO_THE_DORGESHUUN, new WorldPoint(3316, 9613, 0)),
THE_DEPTHS_OF_DESPAIR(Quest.THE_DEPTHS_OF_DESPAIR, new WorldPoint(1846, 3556, 0)),
DESERT_TREASURE(Quest.DESERT_TREASURE, new WorldPoint(3177, 3043, 0)),
DEVIOUS_MINDS(Quest.DEVIOUS_MINDS, new WorldPoint(3405, 3492, 0)),
THE_DIG_SITE(Quest.THE_DIG_SITE, new WorldPoint(3363, 3337, 0)),
DRAGON_SLAYER_II(Quest.DRAGON_SLAYER_II, new WorldPoint(2456, 2868, 0)),
DREAM_MENTOR(Quest.DREAM_MENTOR, new WorldPoint(2144, 10346, 0)),
DRUIDIC_RITUAL(Quest.DRUIDIC_RITUAL, new WorldPoint(2916, 3484, 0)),
DWARF_CANNON(Quest.DWARF_CANNON, new WorldPoint(2566, 3461, 0)),
EADGARS_RUSE(Quest.EADGARS_RUSE, new WorldPoint(2896, 3426, 0)),
EAGLES_PEAK(Quest.EAGLES_PEAK, new WorldPoint(2605, 3264, 0)),
ELEMENTAL_WORKSHOP(new Quest[]{Quest.ELEMENTAL_WORKSHOP_I, Quest.ELEMENTAL_WORKSHOP_II}, new WorldPoint(2714, 3482, 0)),
ENAKHRAS_LAMENT(Quest.ENAKHRAS_LAMENT, new WorldPoint(3190, 2926, 0)),
ENLIGHTENED_JOURNEY(Quest.ENLIGHTENED_JOURNEY, new WorldPoint(2809, 3356, 0)),
THE_EYES_OF_GLOUPHRIE(Quest.THE_EYES_OF_GLOUPHRIE, new WorldPoint(2400, 3419, 0)),
FAIRYTALE(new Quest[]{Quest.FAIRYTALE_I__GROWING_PAINS, Quest.FAIRYTALE_II__CURE_A_QUEEN}, new WorldPoint(3077, 3258, 0)),
FAMILY_CREST(Quest.FAMILY_CREST, new WorldPoint(3278, 3404, 0)),
THE_FEUD(Quest.THE_FEUD, new WorldPoint(3301, 3211, 0)),
FIGHT_ARENA(Quest.FIGHT_ARENA, new WorldPoint(2565, 3199, 0)),
FISHING_CONTEST_1(Quest.FISHING_CONTEST, new WorldPoint(2875, 3483, 0)),
FISHING_CONTEST_2(Quest.FISHING_CONTEST, new WorldPoint(2820, 3487, 0)),
FORGETTABLE_TALE(Quest.FORGETTABLE_TALE, new WorldPoint(2826, 10215, 0)),
THE_FORSAKEN_TOWER(Quest.THE_FORSAKEN_TOWER, new WorldPoint(1484, 3747, 0)),
THE_FREMENNIK_ISLES(Quest.THE_FREMENNIK_ISLES, new WorldPoint(2645, 3711, 0)),
THE_FREMENNIK_TRIALS(Quest.THE_FREMENNIK_TRIALS, new WorldPoint(2657, 3669, 0)),
GARDEN_OF_TRANQUILLITY(Quest.GARDEN_OF_TRANQUILLITY, new WorldPoint(3227, 3477, 0)),
GERTRUDES_CAT_RATCATCHERS(Quest.GERTRUDES_CAT, new WorldPoint(3150, 3411, 0)),
GHOSTS_AHOY(Quest.GHOSTS_AHOY, new WorldPoint(3677, 3510, 0)),
THE_GIANT_DWARF(Quest.THE_GIANT_DWARF, new WorldPoint(2841, 10129, 0)),
THE_GOLEM(Quest.THE_GOLEM, new WorldPoint(3487, 3089, 0)),
THE_GRAND_TREE_MONKEY_MADNESS(new Quest[]{Quest.THE_GRAND_TREE, Quest.MONKEY_MADNESS_I, Quest.MONKEY_MADNESS_II}, new WorldPoint(2466, 3497, 0)),
THE_GREAT_BRAIN_ROBBERY(Quest.THE_GREAT_BRAIN_ROBBERY, new WorldPoint(3681, 2963, 0)),
GRIM_TALES(Quest.GRIM_TALES, new WorldPoint(2890, 3454, 0)),
THE_HAND_IN_THE_SAND(Quest.THE_HAND_IN_THE_SAND, new WorldPoint(2552, 3101, 0)),
HAUNTED_MINE(Quest.HAUNTED_MINE, new WorldPoint(3443, 3258, 0)),
HAZEEL_CULT(Quest.HAZEEL_CULT, new WorldPoint(2565, 3271, 0)),
HEROES_QUEST(Quest.HEROES_QUEST, new WorldPoint(2903, 3511, 0)),
HOLY_GRAIL(new Quest[]{Quest.MERLINS_CRYSTAL, Quest.HOLY_GRAIL}, new WorldPoint(2763, 3515, 0)),
HORROR_FROM_THE_DEEP(Quest.HORROR_FROM_THE_DEEP, new WorldPoint(2507, 3635, 0)),
ICTHLARINS_LITTLE_HELPER(Quest.ICTHLARINS_LITTLE_HELPER, new WorldPoint(3314, 2849, 0)),
IN_SEARCH_OF_THE_MYREQUE(Quest.IN_SEARCH_OF_THE_MYREQUE, new WorldPoint(3502, 3477, 0)),
JUNGLE_POTION(Quest.JUNGLE_POTION, new WorldPoint(2809, 3086, 0)),
KINGS_RANSOM(Quest.KINGS_RANSOM, new WorldPoint(2741, 3554, 0)),
LEGENDS_QUEST(Quest.LEGENDS_QUEST, new WorldPoint(2725, 3367, 0)),
LOST_CITY(Quest.LOST_CITY, new WorldPoint(3149, 3205, 0)),
THE_LOST_TRIBE(Quest.THE_LOST_TRIBE, new WorldPoint(3211, 3224, 0)),
LUNAR_DIPLOMACY(Quest.LUNAR_DIPLOMACY, new WorldPoint(2619, 3689, 0)),
MAKING_FRIENDS_WITH_MY_ARM(Quest.MAKING_FRIENDS_WITH_MY_ARM, new WorldPoint(2904, 10092, 0)),
MAKING_HISTORY(Quest.MAKING_HISTORY, new WorldPoint(2435, 3346, 0)),
MONKS_FRIEND(Quest.MONKS_FRIEND, new WorldPoint(2605, 3209, 0)),
MOUNTAIN_DAUGHTER(Quest.MOUNTAIN_DAUGHTER, new WorldPoint(2810, 3672, 0)),
MOURNINGS_ENDS_PART_I(Quest.MOURNINGS_ENDS_PART_I, new WorldPoint(2289, 3149, 0)),
MOURNINGS_ENDS_PART_II(Quest.MONKEY_MADNESS_II, new WorldPoint(2352, 3172, 0)),
MURDER_MYSTERY(Quest.MURDER_MYSTERY, new WorldPoint(2740, 3562, 0)),
MY_ARMS_BIG_ADVENTURE(Quest.MY_ARMS_BIG_ADVENTURE, new WorldPoint(2908, 10088, 0)),
NATURE_SPIRIT(Quest.NATURE_SPIRIT, new WorldPoint(3440, 9894, 0)),
OBSERVATORY_QUEST(Quest.OBSERVATORY_QUEST, new WorldPoint(2438, 3185, 0)),
OLAFS_QUEST(Quest.OLAFS_QUEST, new WorldPoint(2723, 3729, 0)),
ONE_SMALL_FAVOUR(Quest.ONE_SMALL_FAVOUR, new WorldPoint(2834, 2985, 0)),
PLAGUE_CITY(Quest.PLAGUE_CITY, new WorldPoint(2567, 3334, 0)),
PRIEST_IN_PERIL(Quest.PRIEST_IN_PERIL, new WorldPoint(3219, 3473, 0)),
THE_QUEEN_OF_THIEVES(Quest.THE_QUEEN_OF_THIEVES, new WorldPoint(1795, 3782, 0)),
RAG_AND_BONE_MAN(new Quest[]{Quest.RAG_AND_BONE_MAN, Quest.RAG_AND_BONE_MAN_II}, new WorldPoint(3359, 3504, 0)),
RECRUITMENT_DRIVE_BLACK_KNIGHTS_FORTRESS(new Quest[]{Quest.BLACK_KNIGHTS_FORTRESS, Quest.RECRUITMENT_DRIVE}, new WorldPoint(2959, 3336, 0)),
ROVING_ELVES(Quest.ROVING_ELVES, new WorldPoint(2289, 3146, 0)),
RUM_DEAL(Quest.RUM_DEAL, new WorldPoint(3679, 3535, 0)),
SCORPION_CATCHER(Quest.SCORPION_CATCHER, new WorldPoint(2701, 3399, 0)),
SEA_SLUG(Quest.SEA_SLUG, new WorldPoint(2715, 3302, 0)),
SHADES_OF_MORTTON(Quest.SHADES_OF_MORTTON, new WorldPoint(3463, 3308, 0)),
SHADOW_OF_THE_STORM(Quest.SHADES_OF_MORTTON, new WorldPoint(3270, 3159, 0)),
SHEEP_HERDER(Quest.SHEEP_HERDER, new WorldPoint(2616, 3299, 0)),
SHILO_VILLAGE(Quest.SHILO_VILLAGE, new WorldPoint(2882, 2951, 0)),
A_SOULS_BANE(Quest.A_SOULS_BANE, new WorldPoint(3307, 3454, 0)),
SPIRITS_OF_THE_ELID(Quest.SPIRITS_OF_THE_ELID, new WorldPoint(3441, 2911, 0)),
SWAN_SONG(Quest.SWAN_SONG, new WorldPoint(2345, 3652, 0)),
TAI_BWO_WANNAI_TRIO(Quest.TAI_BWO_WANNAI_TRIO, new WorldPoint(2779, 3087, 0)),
A_TAIL_OF_TWO_CATS(Quest.A_TAIL_OF_TWO_CATS, new WorldPoint(2917, 3557, 0)),
TALE_OF_THE_RIGHTEOUS(Quest.TALE_OF_THE_RIGHTEOUS, new WorldPoint(1511, 3631, 0)),
A_TASTE_OF_HOPE(Quest.A_TASTE_OF_HOPE, new WorldPoint(3668, 3216, 0)),
TEARS_OF_GUTHIX(Quest.TEARS_OF_GUTHIX, new WorldPoint(3251, 9517, 0)),
TEMPLE_OF_IKOV(Quest.TEMPLE_OF_IKOV, new WorldPoint(2574, 3320, 0)),
THRONE_OF_MISCELLANIA_ROYAL_TROUBLE(new Quest[]{Quest.THRONE_OF_MISCELLANIA, Quest.ROYAL_TROUBLE}, new WorldPoint(2497, 3859, 0)),
THE_TOURIST_TRAP(Quest.THE_TOURIST_TRAP, new WorldPoint(3302, 3113, 0)),
TOWER_OF_LIFE(Quest.TOWER_OF_LIFE, new WorldPoint(2640, 3218, 0)),
TREE_GNOME_VILLAGE(Quest.TREE_GNOME_VILLAGE, new WorldPoint(2541, 3169, 0)),
TRIBAL_TOTEM(Quest.TRIBAL_TOTEM, new WorldPoint(2790, 3182, 0)),
TROLL_ROMANCE(Quest.TROLL_ROMANCE, new WorldPoint(2890, 10097, 0)),
UNDERGROUND_PASS_REGICIDE(new Quest[]{Quest.REGICIDE, Quest.UNDERGROUND_PASS}, new WorldPoint(2575, 3293, 0)),
WANTED_SLUG_MENACE(new Quest[]{Quest.WANTED, Quest.THE_SLUG_MENACE}, new WorldPoint(2996, 3373, 0)),
WATCHTOWER(Quest.WATCHTOWER, new WorldPoint(2545, 3112, 0)),
WATERFALL_QUEST(Quest.WATERFALL_QUEST, new WorldPoint(2521, 3498, 0)),
WHAT_LIES_BELOW(Quest.WHAT_LIES_BELOW, new WorldPoint(3265, 3333, 0)),
WITCHS_HOUSE(Quest.WITCHS_HOUSE, new WorldPoint(2927, 3456, 0)),
ZOGRE_FLESH_EATERS(Quest.ZOGRE_FLESH_EATERS, new WorldPoint(2442, 3051, 0));
@Getter
private final WorldPoint location;
QuestStartLocation(String description, WorldPoint location)
@Getter
private final Quest[] quests;
QuestStartLocation(Quest[] quests, WorldPoint location)
{
this.tooltip = "Quest Start - " + description;
this.location = location;
this.quests = quests;
}
QuestStartLocation(Quest quest, WorldPoint location)
{
this.location = location;
this.quests = new Quest[]{quest};
}
}
@@ -25,15 +25,15 @@
*/
package net.runelite.client.plugins.worldmap;
import net.runelite.api.coords.WorldPoint;
import java.awt.image.BufferedImage;
import net.runelite.client.ui.overlay.worldmap.WorldMapPoint;
class QuestStartPoint extends WorldMapPoint
{
QuestStartPoint(QuestStartLocation data, BufferedImage icon)
QuestStartPoint(WorldPoint location, BufferedImage icon, String tooltip)
{
super(data.getLocation(), icon);
setTooltip(data.getTooltip());
super(location, icon);
setTooltip(tooltip);
}
}
@@ -166,8 +166,8 @@ public interface WorldMapConfig extends Config
@ConfigItem(
keyName = WorldMapPlugin.CONFIG_KEY_QUEST_START_TOOLTIPS,
name = "Show quest names",
description = "Indicates the names of quests and highlights incomplete ones",
name = "Show quest names and status",
description = "Indicates the names of quests and shows completion status",
position = 13
)
default boolean questStartTooltips()
@@ -31,9 +31,15 @@ import java.awt.image.BufferedImage;
import java.util.Arrays;
import net.runelite.api.Client;
import net.runelite.api.Experience;
import net.runelite.api.GameState;
import net.runelite.api.Skill;
import net.runelite.api.Quest;
import net.runelite.api.QuestState;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.ExperienceChanged;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.WidgetID;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.game.AgilityShortcut;
@@ -52,6 +58,9 @@ public class WorldMapPlugin extends Plugin
static final BufferedImage BLANK_ICON;
private static final BufferedImage FAIRY_TRAVEL_ICON;
private static final BufferedImage NOPE_ICON;
private static final BufferedImage NOT_STARTED_ICON;
private static final BufferedImage STARTED_ICON;
private static final BufferedImage FINISHED_ICON;
static final String CONFIG_KEY = "worldmap";
static final String CONFIG_KEY_FAIRY_RING_TOOLTIPS = "fairyRingTooltips";
@@ -77,6 +86,9 @@ public class WorldMapPlugin extends Plugin
//A size of 17 gives us a buffer when triggering tooltips
final int iconBufferSize = 17;
//Quest icons are a bit bigger.
final int questIconBufferSize = 22;
BLANK_ICON = new BufferedImage(iconBufferSize, iconBufferSize, BufferedImage.TYPE_INT_ARGB);
FAIRY_TRAVEL_ICON = new BufferedImage(iconBufferSize, iconBufferSize, BufferedImage.TYPE_INT_ARGB);
@@ -86,11 +98,26 @@ public class WorldMapPlugin extends Plugin
NOPE_ICON = new BufferedImage(iconBufferSize, iconBufferSize, BufferedImage.TYPE_INT_ARGB);
final BufferedImage nopeImage = ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, "nope_icon.png");
NOPE_ICON.getGraphics().drawImage(nopeImage, 1, 1, null);
NOT_STARTED_ICON = new BufferedImage(questIconBufferSize, questIconBufferSize, BufferedImage.TYPE_INT_ARGB);
final BufferedImage notStartedIcon = ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, "quest_not_started_icon.png");
NOT_STARTED_ICON.getGraphics().drawImage(notStartedIcon, 4, 4, null);
STARTED_ICON = new BufferedImage(questIconBufferSize, questIconBufferSize, BufferedImage.TYPE_INT_ARGB);
final BufferedImage startedIcon = ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, "quest_started_icon.png");
STARTED_ICON.getGraphics().drawImage(startedIcon, 4, 4, null);
FINISHED_ICON = new BufferedImage(questIconBufferSize, questIconBufferSize, BufferedImage.TYPE_INT_ARGB);
final BufferedImage finishedIcon = ImageUtil.getResourceStreamFromClass(WorldMapPlugin.class, "quest_completed_icon.png");
FINISHED_ICON.getGraphics().drawImage(finishedIcon, 4, 4, null);
}
@Inject
private Client client;
@Inject
private ClientThread clientThread;
@Inject
private WorldMapConfig config;
@@ -164,6 +191,17 @@ public class WorldMapPlugin extends Plugin
}
}
@Subscribe
public void onWidgetLoaded(WidgetLoaded widgetLoaded)
{
if (widgetLoaded.getGroupId() == WidgetID.WORLD_MAP_GROUP_ID)
{
// Quest icons are per-account due to showing quest status,
// so we recreate them each time the map is loaded
updateQuestStartPointIcons();
}
}
private void updateAgilityIcons()
{
worldMapPointManager.removeIf(AgilityShortcutPoint.class::isInstance);
@@ -200,6 +238,7 @@ public class WorldMapPlugin extends Plugin
{
updateAgilityIcons();
updateRareTreeIcons();
updateQuestStartPointIcons();
worldMapPointManager.removeIf(FairyRingPoint.class::isInstance);
if (config.fairyRingIcon() || config.fairyRingTooltips())
@@ -219,14 +258,6 @@ public class WorldMapPlugin extends Plugin
.forEach(worldMapPointManager::add);
}
worldMapPointManager.removeIf(QuestStartPoint.class::isInstance);
if (config.questStartTooltips())
{
Arrays.stream(QuestStartLocation.values())
.map(value -> new QuestStartPoint(value, BLANK_ICON))
.forEach(worldMapPointManager::add);
}
worldMapPointManager.removeIf(TransportationPoint.class::isInstance);
if (config.transportationTeleportTooltips())
{
@@ -271,4 +302,72 @@ public class WorldMapPlugin extends Plugin
}).map(TeleportPoint::new)
.forEach(worldMapPointManager::add);
}
private void updateQuestStartPointIcons()
{
worldMapPointManager.removeIf(QuestStartPoint.class::isInstance);
if (!config.questStartTooltips())
{
return;
}
// Must setup the quest icons on the client thread, after the player has logged in.
clientThread.invokeLater(() ->
{
if (client.getGameState() != GameState.LOGGED_IN)
{
return false;
}
Arrays.stream(QuestStartLocation.values())
.map(this::createQuestStartPoint)
.forEach(worldMapPointManager::add);
return true;
});
}
private QuestStartPoint createQuestStartPoint(QuestStartLocation data)
{
Quest[] quests = data.getQuests();
// Get first uncompleted quest. Else, return the last quest.
Quest quest = null;
for (int i = 0; i < quests.length; i++)
{
if (quests[i].getState(client) != QuestState.FINISHED)
{
quest = quests[i];
break;
}
}
if (quest == null)
{
quest = quests[quests.length - 1];
}
BufferedImage icon = BLANK_ICON;
String tooltip = "";
if (quest != null)
{
tooltip = quest.getName();
switch (quest.getState(client))
{
case FINISHED:
icon = FINISHED_ICON;
tooltip += " - Finished";
break;
case IN_PROGRESS:
icon = STARTED_ICON;
tooltip += " - Started";
break;
case NOT_STARTED:
icon = NOT_STARTED_ICON;
tooltip += " - Not Started";
break;
}
}
return new QuestStartPoint(data.getLocation(), icon, tooltip);
}
}
@@ -176,6 +176,10 @@
237,
1487
],
"wine of zamorak": [
245,
23489
],
"key": [
275,
423,
Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

@@ -0,0 +1 @@
15F58F5939D9311F3D76FA2F0F3441B7B0DA1E8EAE23C654948095A7D51E07F0
@@ -0,0 +1,634 @@
.id 1601
.int_stack_count 4
.string_stack_count 2
.int_var_count 14
.string_var_count 3
; callback "itemsKeptOnDeath"
; Used by the ItemsKepthOnDeath plugin to edit the interface
; Put a rune pouch in your inventory and it shouldn't have a white outline
; in the Items kept on death screen
sload 1
iconst 262167
if_settext
iconst 0
istore 4
iconst 0
istore 5
iconst -1
istore 6
iconst 0
istore 7
sconst ""
sstore 2
iconst 0
istore 8
iconst 0
istore 9
iconst 0
istore 10
iconst 0
istore 11
iload 1
define_array 111
iconst 0
istore 12
iconst 0
istore 13
iload 0
iconst 0
if_icmpeq LABEL31
jump LABEL525
LABEL31:
iconst 93
iconst 13190
inv_total
iconst 0
if_icmpgt LABEL42
iconst 93
iconst 13192
inv_total
iconst 0
if_icmpgt LABEL42
jump LABEL44
LABEL42:
iconst 1
istore 9
LABEL44:
iload 10
iload 1
if_icmplt LABEL48
jump LABEL88
LABEL48:
iconst 584
iload 11
inv_getobj
istore 6
iload 6
iconst -1
if_icmpne LABEL56
jump LABEL85
LABEL56:
iconst 584
iload 11
inv_getnum
istore 7
LABEL60:
iload 10
iload 1
if_icmplt LABEL64
jump LABEL80
LABEL64:
iload 7
iconst 0
if_icmpgt LABEL68
jump LABEL80
LABEL68:
iload 10
iload 6
set_array_int
iload 7
iconst 1
sub
istore 7
iload 10
iconst 1
add
istore 10
jump LABEL60
LABEL80:
iload 11
iconst 1
add
istore 11
jump LABEL87
LABEL85:
iload 1
istore 10
LABEL87:
jump LABEL44
LABEL88:
iload 4
iload 1
if_icmplt LABEL92
jump LABEL147
LABEL92:
iconst 262162
iconst 5
iload 4
cc_create
iconst 36
iconst 32
iconst 0
iconst 0
cc_setsize
iconst 5
iload 4
iconst 40
multiply
add
iconst 25
iconst 0
iconst 0
cc_setposition
iload 4
get_array_int
istore 6
iload 6
iconst -1
if_icmpne LABEL117
jump LABEL144
LABEL117:
iload 6
iconst 1
cc_setobject
sconst "<col=ff981f>"
iload 6
oc_name
join_string 2
cc_setopbase
iconst 1
sconst "Item:"
cc_setop
iconst 1603
iconst 1
iconst 1
iload 6
oc_name
sconst "1is"
cc_setonop
iconst 1118481
cc_setgraphicshadow
iconst 1
cc_setoutline
iload 4
iconst 1
add
istore 4
jump LABEL146
LABEL144:
iload 1
istore 4
LABEL146:
jump LABEL88
LABEL147:
iconst 0
istore 4
LABEL149:
iload 4
iconst 468
inv_size
if_icmplt LABEL154
jump LABEL350
LABEL154:
iconst 468
iload 4
inv_getobj
istore 6
iload 6
iconst -1
if_icmpne LABEL162
jump LABEL345
LABEL162:
iconst 262165
iconst 5
iload 5
cc_create
iconst 36
iconst 32
iconst 0
iconst 0
cc_setsize
iconst 5
iload 5
iconst 8
mod
iconst 38
multiply
add
iconst 25
iconst 38
iload 5
iconst 8
div
multiply
add
iconst 0
iconst 0
cc_setposition
iload 6
iconst 468
iload 4
inv_getnum
cc_setobject
sconst "<col=ff981f>"
iload 6
oc_name
join_string 2
cc_setopbase
iconst 1
sconst "Item:"
cc_setop
iconst 1603
iconst 0
iconst 468
iload 4
inv_getnum
iload 6
oc_name
sconst "1is"
cc_setonop
iconst 1118481
cc_setgraphicshadow
iconst 111
iconst 49
iconst 879
iload 6
oc_uncert
enum
iconst 1
if_icmpeq LABEL221
jump LABEL226
LABEL221:
iconst 2
cc_setoutline
iconst 1
istore 8
jump LABEL228
LABEL226:
iconst 1
cc_setoutline
LABEL228:
iload 5
iconst 1
add
istore 5
iload 6
oc_stackable
iconst 1
if_icmpeq LABEL237
jump LABEL345
LABEL237:
iconst 0
istore 10
iconst 0
istore 13
LABEL241:
iload 10
iload 1
if_icmplt LABEL245
jump LABEL259
LABEL245:
iload 10
get_array_int
iload 6
if_icmpeq LABEL250
jump LABEL254
LABEL250:
iload 13
iconst 1
add
istore 13
LABEL254:
iload 10
iconst 1
add
istore 10
jump LABEL241
LABEL259:
iconst 2147483647
iconst 94
iload 6
inv_total
sub
iconst 93
iload 6
inv_total
sub
iload 13
add
istore 12
iconst 0
iload 12
sub
istore 12
iload 12
iconst 0
if_icmpgt LABEL279
jump LABEL345
LABEL279:
iconst 262165
iconst 5
iload 5
cc_create
iconst 36
iconst 32
iconst 0
iconst 0
cc_setsize
iconst 5
iload 5
iconst 8
mod
iconst 38
multiply
add
iconst 25
iconst 38
iload 5
iconst 8
div
multiply
add
iconst 0
iconst 0
cc_setposition
iload 6
iload 12
cc_setobject
sconst "<col=ff981f>"
iload 6
oc_name
join_string 2
cc_setopbase
iconst 1
sconst "Item:"
cc_setop
iconst 1603
iconst 0
iload 12
iload 6
oc_name
sconst "1is"
cc_setonop
iconst 1118481
cc_setgraphicshadow
iconst 111
iconst 49
iconst 879
iload 6
oc_uncert
enum
iconst 1
if_icmpeq LABEL334
jump LABEL339
LABEL334:
iconst 2
cc_setoutline
iconst 1
istore 8
jump LABEL341
LABEL339:
iconst 1
cc_setoutline
LABEL341:
iload 5
iconst 1
add
istore 5
LABEL345:
iload 4
iconst 1
add
istore 4
jump LABEL149
LABEL350:
sconst "The normal amount of items kept is "
sconst "three"
sconst "."
sconst "<br>"
sconst "<br>"
join_string 5
sstore 2
iload 3
iconst 1
if_icmpeq LABEL361
jump LABEL371
LABEL361:
sload 2
sconst "You're an "
sconst "<col=ff3333>"
sconst "Ultimate Iron Man"
sconst "<col=ff981f>"
sconst ", so you will always keep zero items."
join_string 5
append
sstore 2
jump LABEL434
LABEL371:
iload 1
iconst 0
if_icmpeq LABEL375
jump LABEL387
LABEL375:
sload 2
sconst "You're marked with a "
sconst "<col=ff3333>"
sconst "PK skull"
sconst "<col=ff981f>"
sconst ". This reduces the items you keep from "
sconst "three"
sconst " to zero!"
join_string 7
append
sstore 2
jump LABEL434
LABEL387:
iload 1
iconst 1
if_icmpeq LABEL391
jump LABEL410
LABEL391:
sload 2
sconst "You're marked with a "
sconst "<col=ff3333>"
sconst "PK skull"
sconst "<col=ff981f>"
sconst ". This reduces the items you keep from "
sconst "three"
sconst " to zero!"
sconst "<br>"
sconst "<br>"
sconst "However, you also have the "
sconst "<col=ff3333>"
sconst "Protect Items"
sconst "<col=ff981f>"
sconst " prayer active, which saves you one extra item!"
join_string 14
append
sstore 2
jump LABEL434
LABEL410:
iload 1
iconst 3
if_icmpeq LABEL414
jump LABEL419
LABEL414:
sload 2
sconst "You have no factors affecting the items you keep."
append
sstore 2
jump LABEL434
LABEL419:
iload 1
iconst 3
iconst 1
add
if_icmpeq LABEL425
jump LABEL434
LABEL425:
sload 2
sconst "You have the "
sconst "<col=ff3333>"
sconst "Protect Items"
sconst "<col=ff981f>"
sconst " prayer active, which saves you one extra item!"
join_string 5
append
sstore 2
LABEL434:
iload 8
iconst 1
if_icmpeq LABEL441
iload 9
iconst 1
if_icmpeq LABEL441
jump LABEL492
LABEL441:
iload 8
iconst 1
if_icmpeq LABEL445
jump LABEL466
LABEL445:
iload 9
iconst 1
if_icmpeq LABEL449
jump LABEL466
LABEL449:
sload 2
sconst "<br>"
sconst "<br>"
sconst "Items with a "
sconst "<col=ffffff>"
sconst "white outline"
sconst "<col=ff981f>"
sconst " will always be lost."
sconst "<br>"
sconst "<col=00ff00>"
sconst "Bonds"
sconst "</col>"
sconst " are always protected."
join_string 12
append
sstore 2
jump LABEL492
LABEL466:
iload 8
iconst 1
if_icmpeq LABEL470
jump LABEL482
LABEL470:
sload 2
sconst "<br>"
sconst "<br>"
sconst "Items with a "
sconst "<col=ffffff>"
sconst "white outline"
sconst "<col=ff981f>"
sconst " will always be lost."
join_string 7
append
sstore 2
jump LABEL492
LABEL482:
sload 2
sconst "<br>"
sconst "<br>"
sconst "<col=00ff00>"
sconst "Bonds"
sconst "</col>"
sconst " are always protected, so are not shown here."
join_string 6
append
sstore 2
LABEL492:
sload 2
iconst 262173
if_settext
sconst "<col=ffcc33>"
sconst "Max items kept on death :"
sconst "<br>"
sconst "<br>"
sconst "<col=ffcc33>"
sconst "~ "
iload 1
tostring
sconst " ~"
join_string 8
iconst 262174
if_settext
iload 2
iconst 0
if_icmpgt LABEL511
jump LABEL518
LABEL511:
sconst "Items you will keep on death:"
iconst 262161
if_settext
sconst "Items you will lose on death:"
iconst 262164
if_settext
jump LABEL524
LABEL518:
sconst "Items you will keep on death if not skulled:"
iconst 262161
if_settext
sconst "Items you will lose on death if not skulled:"
iconst 262164
if_settext
LABEL524:
jump LABEL565
LABEL525:
iconst 1
iconst 262165
if_sethide
iconst 1
iconst 262162
if_sethide
iconst 0
iconst 262175
if_sethide
sload 0
iconst 262176
if_settext
sconst "The normal amount of items kept is "
sconst "three"
sconst "."
sconst "<br>"
sconst "<br>"
join_string 5
sstore 2
sload 2
sconst "You're in a "
sconst "<col=ff3333>"
sconst "safe area"
sconst "<col=ff981f>"
sconst ". See information to the left for a more detailed description."
join_string 5
append
sstore 2
sload 2
iconst 262173
if_settext
sconst "<col=ffcc33>"
sconst "Max items kept on death :"
sconst "<br>"
sconst "<br>"
sconst "<col=ffcc33>"
sconst "All items!"
join_string 6
iconst 262174
if_settext
LABEL565:
sconst "itemsKeptOnDeath" ; push event name
runelite_callback ; invoke callback
return
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* 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.emojis;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.testing.fieldbinder.Bind;
import com.google.inject.testing.fieldbinder.BoundFieldModule;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.IndexedSprite;
import net.runelite.api.MessageNode;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.GameStateChanged;
import net.runelite.client.chat.ChatMessageManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class EmojiPluginTest
{
@Mock
@Bind
private Client client;
@Mock
@Bind
private ChatMessageManager chatMessageManager;
@Inject
private EmojiPlugin emojiPlugin;
@Before
public void before()
{
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
}
@Test
public void testOnChatMessage()
{
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
when(client.getModIcons()).thenReturn(new IndexedSprite[0]);
when(client.createIndexedSprite()).thenReturn(mock(IndexedSprite.class));
// Trip emoji loading
GameStateChanged gameStateChanged = new GameStateChanged();
gameStateChanged.setGameState(GameState.LOGGED_IN);
emojiPlugin.onGameStateChanged(gameStateChanged);
MessageNode messageNode = mock(MessageNode.class);
// With chat recolor, message may be wrapped in col tags
when(messageNode.getValue()).thenReturn("<col=ff0000>:) :) :)</col>");
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
emojiPlugin.onChatMessage(chatMessage);
verify(messageNode).setRuneLiteFormatMessage("<col=ff0000><img=0> <img=0> <img=0></col>");
}
@Test
public void testGtLt()
{
when(client.getGameState()).thenReturn(GameState.LOGGED_IN);
when(client.getModIcons()).thenReturn(new IndexedSprite[0]);
when(client.createIndexedSprite()).thenReturn(mock(IndexedSprite.class));
// Trip emoji loading
GameStateChanged gameStateChanged = new GameStateChanged();
gameStateChanged.setGameState(GameState.LOGGED_IN);
emojiPlugin.onGameStateChanged(gameStateChanged);
MessageNode messageNode = mock(MessageNode.class);
when(messageNode.getValue()).thenReturn("<gt>:D<lt>");
ChatMessage chatMessage = new ChatMessage();
chatMessage.setType(ChatMessageType.PUBLICCHAT);
chatMessage.setMessageNode(messageNode);
emojiPlugin.onChatMessage(chatMessage);
verify(messageNode).setRuneLiteFormatMessage("<img=10>");
}
}
@@ -1268,13 +1268,6 @@ public abstract class RSClientMixin implements RSClient
client.getCallbacks().post(new UsernameChanged());
}
@Inject
@Override
public void setHealthBarOverride(HealthBarOverride override)
{
healthBarOverride = override;
}
@Override
@Inject
public int getTickCount()
@@ -1565,4 +1558,12 @@ public abstract class RSClientMixin implements RSClient
enumCache.put(id, rsEnumDefinition);
return rsEnumDefinition;
}
@Inject
@Override
public void resetHealthBarCaches()
{
getHealthBarCache().reset();
getHealthBarSpriteCache().reset();
}
}
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2019, Lotto <https://github.com/devLotto>
* 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.mixins;
import net.runelite.api.events.PostHealthBar;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.MethodHook;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSBuffer;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSHealthBar;
@Mixin(RSHealthBar.class)
public abstract class RSHealthBarMixin implements RSHealthBar
{
@Shadow("client")
private static RSClient client;
@MethodHook(value = "get", end = true)
@Inject
public void onRead(RSBuffer buffer)
{
PostHealthBar postHealthBar = new PostHealthBar();
postHealthBar.setHealthBar(this);
client.getCallbacks().post(postHealthBar);
}
}
@@ -1001,4 +1001,5 @@ public interface RSClient extends RSGameShell, Client
@Import("isSpellSelected")
boolean getIsSpellSelected();
}
@@ -1,12 +1,29 @@
package net.runelite.rs.api;
import net.runelite.api.HealthBar;
import net.runelite.mapping.Import;
public interface RSHealthBar extends RSNode
public interface RSHealthBar extends RSNode, HealthBar
{
@Import("updates")
RSIterableNodeDeque getUpdates(); // "combatinfolist" but only thing it has is getNode so this works
@Import("definition")
RSHealthBarDefinition getDefinition();
@Import("healthBarFrontSpriteId")
@Override
int getHealthBarFrontSpriteId();
@Import("getHealthBarFrontSprite")
@Override
RSSprite getHealthBarFrontSprite();
@Import("getHealthBarBackSprite")
@Override
RSSprite getHealthBarBackSprite();
@Import("healthBarPadding")
@Override
void setPadding(int padding);
}