diff --git a/runelite-api/src/main/java/net/runelite/api/InventoryID.java b/runelite-api/src/main/java/net/runelite/api/InventoryID.java index 000bb8aa52..ff099afd70 100644 --- a/runelite-api/src/main/java/net/runelite/api/InventoryID.java +++ b/runelite-api/src/main/java/net/runelite/api/InventoryID.java @@ -57,6 +57,10 @@ public enum InventoryID * Chambers of Xeric chest inventory. */ CHAMBERS_OF_XERIC_CHEST(581), + /** + * Looting Bag inventory + */ + LOOTING_BAG(516), /** * Theater of Blood reward chest inventory (Raids 2) */ @@ -78,4 +82,4 @@ public enum InventoryID { return id; } -} +} \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/Varbits.java b/runelite-api/src/main/java/net/runelite/api/Varbits.java index 8c4c18bf91..038362c66d 100644 --- a/runelite-api/src/main/java/net/runelite/api/Varbits.java +++ b/runelite-api/src/main/java/net/runelite/api/Varbits.java @@ -32,472 +32,471 @@ import lombok.Getter; */ @AllArgsConstructor @Getter -public enum Varbits -{ - /* - * If chatbox is transparent or not - */ - TRANSPARENT_CHATBOX(4608), +public enum Varbits { + /* + * If chatbox is transparent or not + */ + TRANSPARENT_CHATBOX(4608), - /* - * If the player has an active stamina potion effect or not - */ - RUN_SLOWED_DEPLETION_ACTIVE(25), + /* + * If the player has an active stamina potion effect or not + */ + RUN_SLOWED_DEPLETION_ACTIVE(25), - /** - * If scrollbar in resizable mode chat is on the left - */ - CHAT_SCROLLBAR_ON_LEFT(6374), + /** + * If scrollbar in resizable mode chat is on the left + */ + CHAT_SCROLLBAR_ON_LEFT(6374), - /** - * Runepouch - */ - RUNE_POUCH_RUNE1(29), - RUNE_POUCH_RUNE2(1622), - RUNE_POUCH_RUNE3(1623), - RUNE_POUCH_AMOUNT1(1624), - RUNE_POUCH_AMOUNT2(1625), - RUNE_POUCH_AMOUNT3(1626), + /** + * Runepouch + */ + RUNE_POUCH_RUNE1(29), + RUNE_POUCH_RUNE2(1622), + RUNE_POUCH_RUNE3(1623), + RUNE_POUCH_AMOUNT1(1624), + RUNE_POUCH_AMOUNT2(1625), + RUNE_POUCH_AMOUNT3(1626), - /** - * Prayers - */ - QUICK_PRAYER(4103), - PRAYER_THICK_SKIN(4104), - PRAYER_BURST_OF_STRENGTH(4105), - PRAYER_CLARITY_OF_THOUGHT(4106), - PRAYER_SHARP_EYE(4122), - PRAYER_MYSTIC_WILL(4123), - PRAYER_ROCK_SKIN(4107), - PRAYER_SUPERHUMAN_STRENGTH(4108), - PRAYER_IMPROVED_REFLEXES(4109), - PRAYER_RAPID_RESTORE(4110), - PRAYER_RAPID_HEAL(4111), - PRAYER_PROTECT_ITEM(4112), - PRAYER_HAWK_EYE(4124), - PRAYER_MYSTIC_LORE(4125), - PRAYER_STEEL_SKIN(4113), - PRAYER_ULTIMATE_STRENGTH(4114), - PRAYER_INCREDIBLE_REFLEXES(4115), - PRAYER_PROTECT_FROM_MAGIC(4116), - PRAYER_PROTECT_FROM_MISSILES(4117), - PRAYER_PROTECT_FROM_MELEE(4118), - PRAYER_EAGLE_EYE(4126), - PRAYER_MYSTIC_MIGHT(4127), - PRAYER_RETRIBUTION(4119), - PRAYER_REDEMPTION(4120), - PRAYER_SMITE(4121), - PRAYER_CHIVALRY(4128), - PRAYER_PIETY(4129), - PRAYER_PRESERVE(5466), - PRAYER_RIGOUR(5464), - PRAYER_AUGURY(5465), + /** + * Prayers + */ + QUICK_PRAYER(4103), + PRAYER_THICK_SKIN(4104), + PRAYER_BURST_OF_STRENGTH(4105), + PRAYER_CLARITY_OF_THOUGHT(4106), + PRAYER_SHARP_EYE(4122), + PRAYER_MYSTIC_WILL(4123), + PRAYER_ROCK_SKIN(4107), + PRAYER_SUPERHUMAN_STRENGTH(4108), + PRAYER_IMPROVED_REFLEXES(4109), + PRAYER_RAPID_RESTORE(4110), + PRAYER_RAPID_HEAL(4111), + PRAYER_PROTECT_ITEM(4112), + PRAYER_HAWK_EYE(4124), + PRAYER_MYSTIC_LORE(4125), + PRAYER_STEEL_SKIN(4113), + PRAYER_ULTIMATE_STRENGTH(4114), + PRAYER_INCREDIBLE_REFLEXES(4115), + PRAYER_PROTECT_FROM_MAGIC(4116), + PRAYER_PROTECT_FROM_MISSILES(4117), + PRAYER_PROTECT_FROM_MELEE(4118), + PRAYER_EAGLE_EYE(4126), + PRAYER_MYSTIC_MIGHT(4127), + PRAYER_RETRIBUTION(4119), + PRAYER_REDEMPTION(4120), + PRAYER_SMITE(4121), + PRAYER_CHIVALRY(4128), + PRAYER_PIETY(4129), + PRAYER_PRESERVE(5466), + PRAYER_RIGOUR(5464), + PRAYER_AUGURY(5465), - /** - * Diary Entries - */ - DIARY_ARDOUGNE_EASY(4458), - DIARY_ARDOUGNE_MEDIUM(4459), - DIARY_ARDOUGNE_HARD(4460), - DIARY_ARDOUGNE_ELITE(4461), + /** + * Diary Entries + */ + DIARY_ARDOUGNE_EASY(4458), + DIARY_ARDOUGNE_MEDIUM(4459), + DIARY_ARDOUGNE_HARD(4460), + DIARY_ARDOUGNE_ELITE(4461), - DIARY_DESERT_EASY(4483), - DIARY_DESERT_MEDIUM(4484), - DIARY_DESERT_HARD(4485), - DIARY_DESERT_ELITE(4486), + DIARY_DESERT_EASY(4483), + DIARY_DESERT_MEDIUM(4484), + DIARY_DESERT_HARD(4485), + DIARY_DESERT_ELITE(4486), - DIARY_FALADOR_EASY(4462), - DIARY_FALADOR_MEDIUM(4463), - DIARY_FALADOR_HARD(4464), - DIARY_FALADOR_ELITE(4465), + DIARY_FALADOR_EASY(4462), + DIARY_FALADOR_MEDIUM(4463), + DIARY_FALADOR_HARD(4464), + DIARY_FALADOR_ELITE(4465), - DIARY_FREMENNIK_EASY(4491), - DIARY_FREMENNIK_MEDIUM(4492), - DIARY_FREMENNIK_HARD(4493), - DIARY_FREMENNIK_ELITE(4494), + DIARY_FREMENNIK_EASY(4491), + DIARY_FREMENNIK_MEDIUM(4492), + DIARY_FREMENNIK_HARD(4493), + DIARY_FREMENNIK_ELITE(4494), - DIARY_KANDARIN_EASY(4475), - DIARY_KANDARIN_MEDIUM(4476), - DIARY_KANDARIN_HARD(4477), - DIARY_KANDARIN_ELITE(4478), + DIARY_KANDARIN_EASY(4475), + DIARY_KANDARIN_MEDIUM(4476), + DIARY_KANDARIN_HARD(4477), + DIARY_KANDARIN_ELITE(4478), - DIARY_KARAMJA_EASY(3578), - DIARY_KARAMJA_MEDIUM(3599), - DIARY_KARAMJA_HARD(3611), - DIARY_KARAMJA_ELITE(4566), + DIARY_KARAMJA_EASY(3578), + DIARY_KARAMJA_MEDIUM(3599), + DIARY_KARAMJA_HARD(3611), + DIARY_KARAMJA_ELITE(4566), - DIARY_LUMBRIDGE_EASY(4495), - DIARY_LUMBRIDGE_MEDIUM(4496), - DIARY_LUMBRIDGE_HARD(4497), - DIARY_LUMBRIDGE_ELITE(4498), + DIARY_LUMBRIDGE_EASY(4495), + DIARY_LUMBRIDGE_MEDIUM(4496), + DIARY_LUMBRIDGE_HARD(4497), + DIARY_LUMBRIDGE_ELITE(4498), - DIARY_MORYTANIA_EASY(4487), - DIARY_MORYTANIA_MEDIUM(4488), - DIARY_MORYTANIA_HARD(4489), - DIARY_MORYTANIA_ELITE(4490), + DIARY_MORYTANIA_EASY(4487), + DIARY_MORYTANIA_MEDIUM(4488), + DIARY_MORYTANIA_HARD(4489), + DIARY_MORYTANIA_ELITE(4490), - DIARY_VARROCK_EASY(4479), - DIARY_VARROCK_MEDIUM(4480), - DIARY_VARROCK_HARD(4481), - DIARY_VARROCK_ELITE(4482), + DIARY_VARROCK_EASY(4479), + DIARY_VARROCK_MEDIUM(4480), + DIARY_VARROCK_HARD(4481), + DIARY_VARROCK_ELITE(4482), - DIARY_WESTERN_EASY(4471), - DIARY_WESTERN_MEDIUM(4472), - DIARY_WESTERN_HARD(4473), - DIARY_WESTERN_ELITE(4474), + DIARY_WESTERN_EASY(4471), + DIARY_WESTERN_MEDIUM(4472), + DIARY_WESTERN_HARD(4473), + DIARY_WESTERN_ELITE(4474), - DIARY_WILDERNESS_EASY(4466), - DIARY_WILDERNESS_MEDIUM(4467), - DIARY_WILDERNESS_HARD(4468), - DIARY_WILDERNESS_ELITE(4469), + DIARY_WILDERNESS_EASY(4466), + DIARY_WILDERNESS_MEDIUM(4467), + DIARY_WILDERNESS_HARD(4468), + DIARY_WILDERNESS_ELITE(4469), - /** - * Kourend house favours - */ - KOUREND_FAVOR_ARCEUUS(4896), - KOUREND_FAVOR_HOSIDIUS(4895), - KOUREND_FAVOR_LOVAKENGJ(4898), - KOUREND_FAVOR_PISCARILIUS(4899), - KOUREND_FAVOR_SHAYZIEN(4894), + /** + * Kourend house favours + */ + KOUREND_FAVOR_ARCEUUS(4896), + KOUREND_FAVOR_HOSIDIUS(4895), + KOUREND_FAVOR_LOVAKENGJ(4898), + KOUREND_FAVOR_PISCARILIUS(4899), + KOUREND_FAVOR_SHAYZIEN(4894), - /** - * Equipped weapon type - */ - EQUIPPED_WEAPON_TYPE(357), + /** + * Equipped weapon type + */ + EQUIPPED_WEAPON_TYPE(357), - /** - * Defensive casting mode - */ - DEFENSIVE_CASTING_MODE(2668), + /** + * Defensive casting mode + */ + DEFENSIVE_CASTING_MODE(2668), - /** - * Options - */ - SIDE_PANELS(4607), + /** + * Options + */ + SIDE_PANELS(4607), - /** - * Herbiboar Trails - */ - HB_TRAIL_31303(5737), - HB_TRAIL_31306(5738), - HB_TRAIL_31309(5739), - HB_TRAIL_31312(5740), - HB_TRAIL_31315(5741), - HB_TRAIL_31318(5742), - HB_TRAIL_31321(5743), - HB_TRAIL_31324(5744), - HB_TRAIL_31327(5745), - HB_TRAIL_31330(5746), + /** + * Herbiboar Trails + */ + HB_TRAIL_31303(5737), + HB_TRAIL_31306(5738), + HB_TRAIL_31309(5739), + HB_TRAIL_31312(5740), + HB_TRAIL_31315(5741), + HB_TRAIL_31318(5742), + HB_TRAIL_31321(5743), + HB_TRAIL_31324(5744), + HB_TRAIL_31327(5745), + HB_TRAIL_31330(5746), - HB_TRAIL_31333(5768), - HB_TRAIL_31336(5769), - HB_TRAIL_31339(5770), - HB_TRAIL_31342(5771), - HB_TRAIL_31345(5772), - HB_TRAIL_31348(5773), - HB_TRAIL_31351(5774), - HB_TRAIL_31354(5775), - HB_TRAIL_31357(5776), - HB_TRAIL_31360(5777), + HB_TRAIL_31333(5768), + HB_TRAIL_31336(5769), + HB_TRAIL_31339(5770), + HB_TRAIL_31342(5771), + HB_TRAIL_31345(5772), + HB_TRAIL_31348(5773), + HB_TRAIL_31351(5774), + HB_TRAIL_31354(5775), + HB_TRAIL_31357(5776), + HB_TRAIL_31360(5777), - HB_TRAIL_31363(5747), - HB_TRAIL_31366(5748), - HB_TRAIL_31369(5749), - HB_TRAIL_31372(5750), + HB_TRAIL_31363(5747), + HB_TRAIL_31366(5748), + HB_TRAIL_31369(5749), + HB_TRAIL_31372(5750), - HB_FINISH(5766), - HB_STARTED(5767), //not working + HB_FINISH(5766), + HB_STARTED(5767), //not working - /** - * Barbarian Assault - */ - IN_GAME_BA(3923), + /** + * Barbarian Assault + */ + IN_GAME_BA(3923), - /** - * 0 = Outside wilderness - * 1 = In wilderness - */ - IN_WILDERNESS(5963), + /** + * 0 = Outside wilderness + * 1 = In wilderness + */ + IN_WILDERNESS(5963), - /** - * Fishing Trawler - * FISHING_TRAWLER_ACTIVITY Expected values: 0-255 - */ - FISHING_TRAWLER_ACTIVITY(3377), + /** + * Fishing Trawler + * FISHING_TRAWLER_ACTIVITY Expected values: 0-255 + */ + FISHING_TRAWLER_ACTIVITY(3377), - /** - * Blast Furnace Bar Dispenser - * - * These are the expected values: - * 0 = No bars being processed - * 1 = Ores are being processed on the conveyor belt, bar dispenser cannot be checked - * 2 = Bars are cooling down - * 3 = Bars can be collected - */ - BAR_DISPENSER(936), + /** + * Blast Furnace Bar Dispenser + *

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

+ * EXPERIENCE_TRACKER_POSITION expected values: + * 0 = Right + * 1 = Middle + * 2 = Left + */ + EXPERIENCE_TRACKER_POSITION(4692), + EXPERIENCE_TRACKER_COUNTER(4697), + EXPERIENCE_TRACKER_PROGRESS_BAR(4698), - /** - * Experience drop color - */ - EXPERIENCE_DROP_COLOR(4695), + /** + * Experience drop color + */ + EXPERIENCE_DROP_COLOR(4695), - /** - * Tithe Farm - */ - TITHE_FARM_SACK_AMOUNT(4900), - TITHE_FARM_SACK_ICON(5370), - TITHE_FARM_POINTS(4893), - - /** - * Blast Mine - */ - BLAST_MINE_COAL(4924), - BLAST_MINE_GOLD(4925), - BLAST_MINE_MITHRIL(4926), - BLAST_MINE_ADAMANTITE(4921), - BLAST_MINE_RUNITE(4922), + /** + * Tithe Farm + */ + TITHE_FARM_SACK_AMOUNT(4900), + TITHE_FARM_SACK_ICON(5370), + TITHE_FARM_POINTS(4893), - /** - * Raids - */ - IN_RAID(5432), - TOTAL_POINTS(5431), - PERSONAL_POINTS(5422), - RAID_PARTY_SIZE(5424), + /** + * Blast Mine + */ + BLAST_MINE_COAL(4924), + BLAST_MINE_GOLD(4925), + BLAST_MINE_MITHRIL(4926), + BLAST_MINE_ADAMANTITE(4921), + BLAST_MINE_RUNITE(4922), - /** - * Theatre of Blood 1=In Party, 2=Inside/Spectator, 3=Dead Spectating - */ - THEATRE_OF_BLOOD(6440), + /** + * Raids + */ + IN_RAID(5432), + TOTAL_POINTS(5431), + PERSONAL_POINTS(5422), + RAID_PARTY_SIZE(5424), - /** - * Nightmare Zone - */ - NMZ_ABSORPTION(3956), - NMZ_POINTS(3949), + /** + * Theatre of Blood 1=In Party, 2=Inside/Spectator, 3=Dead Spectating + */ + THEATRE_OF_BLOOD(6440), - /** - * Blast Furnace - */ - BLAST_FURNACE_COPPER_ORE(959), - BLAST_FURNACE_TIN_ORE(950), - BLAST_FURNACE_IRON_ORE(951), - BLAST_FURNACE_COAL(949), - BLAST_FURNACE_MITHRIL_ORE(952), - BLAST_FURNACE_ADAMANTITE_ORE(953), - BLAST_FURNACE_RUNITE_ORE(954), - BLAST_FURNACE_SILVER_ORE(956), - BLAST_FURNACE_GOLD_ORE(955), + /** + * Nightmare Zone + */ + NMZ_ABSORPTION(3956), + NMZ_POINTS(3949), - BLAST_FURNACE_BRONZE_BAR(941), - BLAST_FURNACE_IRON_BAR(942), - BLAST_FURNACE_STEEL_BAR(943), - BLAST_FURNACE_MITHRIL_BAR(944), - BLAST_FURNACE_ADAMANTITE_BAR(945), - BLAST_FURNACE_RUNITE_BAR(946), - BLAST_FURNACE_SILVER_BAR(948), - BLAST_FURNACE_GOLD_BAR(947), + /** + * Blast Furnace + */ + BLAST_FURNACE_COPPER_ORE(959), + BLAST_FURNACE_TIN_ORE(950), + BLAST_FURNACE_IRON_ORE(951), + BLAST_FURNACE_COAL(949), + BLAST_FURNACE_MITHRIL_ORE(952), + BLAST_FURNACE_ADAMANTITE_ORE(953), + BLAST_FURNACE_RUNITE_ORE(954), + BLAST_FURNACE_SILVER_ORE(956), + BLAST_FURNACE_GOLD_ORE(955), - BLAST_FURNACE_COFFER(5357), + BLAST_FURNACE_BRONZE_BAR(941), + BLAST_FURNACE_IRON_BAR(942), + BLAST_FURNACE_STEEL_BAR(943), + BLAST_FURNACE_MITHRIL_BAR(944), + BLAST_FURNACE_ADAMANTITE_BAR(945), + BLAST_FURNACE_RUNITE_BAR(946), + BLAST_FURNACE_SILVER_BAR(948), + BLAST_FURNACE_GOLD_BAR(947), - /** - * Pyramid plunder - */ - PYRAMID_PLUNDER_TIMER(2375), - PYRAMID_PLUNDER_ROOM(2377), + BLAST_FURNACE_COFFER(5357), - /** - * Barrows - */ - BARROWS_KILLED_AHRIM(457), - BARROWS_KILLED_DHAROK(458), - BARROWS_KILLED_GUTHAN(459), - BARROWS_KILLED_KARIL(460), - BARROWS_KILLED_TORAG(461), - BARROWS_KILLED_VERAC(462), - BARROWS_REWARD_POTENTIAL(463), - BARROWS_NPCS_SLAIN(464), + /** + * Pyramid plunder + */ + PYRAMID_PLUNDER_TIMER(2375), + PYRAMID_PLUNDER_ROOM(2377), - /** - * Spicy stew ingredients - */ - SPICY_STEW_RED_SPICES(1879), - SPICY_STEW_YELLOW_SPICES(1880), - SPICY_STEW_BROWN_SPICES(1881), - SPICY_STEW_ORANGE_SPICES(1882), + /** + * Barrows + */ + BARROWS_KILLED_AHRIM(457), + BARROWS_KILLED_DHAROK(458), + BARROWS_KILLED_GUTHAN(459), + BARROWS_KILLED_KARIL(460), + BARROWS_KILLED_TORAG(461), + BARROWS_KILLED_VERAC(462), + BARROWS_REWARD_POTENTIAL(463), + BARROWS_NPCS_SLAIN(464), - /** - * Multicombat area - */ - MULTICOMBAT_AREA(4605), + /** + * Spicy stew ingredients + */ + SPICY_STEW_RED_SPICES(1879), + SPICY_STEW_YELLOW_SPICES(1880), + SPICY_STEW_BROWN_SPICES(1881), + SPICY_STEW_ORANGE_SPICES(1882), - /** - * In the Wilderness - */ - IN_THE_WILDERNESS(5963), + /** + * Multicombat area + */ + MULTICOMBAT_AREA(4605), - /** - * Kingdom Management - */ - KINGDOM_FAVOR(72), - KINGDOM_COFFER(74), + /** + * In the Wilderness + */ + IN_THE_WILDERNESS(5963), - /** - * The Hand in the Sand quest status - */ - QUEST_THE_HAND_IN_THE_SAND(1527), + /** + * Kingdom Management + */ + KINGDOM_FAVOR(72), + KINGDOM_COFFER(74), - /** - * Daily Tasks (Collection availability) - */ - DAILY_HERB_BOXES_COLLECTED(3961), - DAILY_STAVES_COLLECTED(4539), - DAILY_ESSENCE_COLLECTED(4547), - DAILY_RUNES_COLLECTED(4540), - DAILY_SAND_COLLECTED(4549), - DAILY_FLAX_STATE(4559), - /** - * This varbit tracks how much bonemeal has been redeemed from Robin - * The player gets 13 for each diary completed above and including Medium, for a maxiumum of 39 - */ - DAILY_BONEMEAL_STATE(4543), + /** + * The Hand in the Sand quest status + */ + QUEST_THE_HAND_IN_THE_SAND(1527), - /** - * Fairy Ring - */ - FAIR_RING_LAST_DESTINATION(5374), - FAIRY_RING_DIAL_ADCB(3985), //Left dial - FAIRY_RIGH_DIAL_ILJK(3986), //Middle dial - FAIRY_RING_DIAL_PSRQ(3987), //Right dial + /** + * Daily Tasks (Collection availability) + */ + DAILY_HERB_BOXES_COLLECTED(3961), + DAILY_STAVES_COLLECTED(4539), + DAILY_ESSENCE_COLLECTED(4547), + DAILY_RUNES_COLLECTED(4540), + DAILY_SAND_COLLECTED(4549), + DAILY_FLAX_STATE(4559), + /** + * This varbit tracks how much bonemeal has been redeemed from Robin + * The player gets 13 for each diary completed above and including Medium, for a maxiumum of 39 + */ + DAILY_BONEMEAL_STATE(4543), - /** - * Transmog controllers for farming - */ - FARMING_4771(4771), - FARMING_4772(4772), - FARMING_4773(4773), - FARMING_4774(4774), - FARMING_4775(4775), - FARMING_7904(7904), - FARMING_7905(7905), - FARMING_7906(7906), - FARMING_7907(7907), - FARMING_7908(7908), - FARMING_7909(7909), - FARMING_7910(7910), - FARMING_7911(7911), + /** + * Fairy Ring + */ + FAIR_RING_LAST_DESTINATION(5374), + FAIRY_RING_DIAL_ADCB(3985), //Left dial + FAIRY_RIGH_DIAL_ILJK(3986), //Middle dial + FAIRY_RING_DIAL_PSRQ(3987), //Right dial - /** - * Transmog controllers for grapes - */ - GRAPES_4953(4953), - GRAPES_4954(4954), - GRAPES_4955(4955), - GRAPES_4956(4956), - GRAPES_4957(4957), - GRAPES_4958(4958), - GRAPES_4959(4959), - GRAPES_4960(4960), - GRAPES_4961(4961), - GRAPES_4962(4962), - GRAPES_4963(4963), - GRAPES_4964(4964), + /** + * Transmog controllers for farming + */ + FARMING_4771(4771), + FARMING_4772(4772), + FARMING_4773(4773), + FARMING_4774(4774), + FARMING_4775(4775), + FARMING_7904(7904), + FARMING_7905(7905), + FARMING_7906(7906), + FARMING_7907(7907), + FARMING_7908(7908), + FARMING_7909(7909), + FARMING_7910(7910), + FARMING_7911(7911), - /** - * Automatically weed farming patches - */ - AUTOWEED(5557), + /** + * Transmog controllers for grapes + */ + GRAPES_4953(4953), + GRAPES_4954(4954), + GRAPES_4955(4955), + GRAPES_4956(4956), + GRAPES_4957(4957), + GRAPES_4958(4958), + GRAPES_4959(4959), + GRAPES_4960(4960), + GRAPES_4961(4961), + GRAPES_4962(4962), + GRAPES_4963(4963), + GRAPES_4964(4964), - /** - * The varbit that stores the players {@code AccountType}. - */ - ACCOUNT_TYPE(1777), + /** + * Automatically weed farming patches + */ + AUTOWEED(5557), - /** - * The varbit that stores the oxygen percentage for player - */ - OXYGEN_LEVEL(5811), - - /** - * Corp beast damage - */ - CORP_DAMAGE(999), + /** + * The varbit that stores the players {@code AccountType}. + */ + ACCOUNT_TYPE(1777), - /** - * Toggleable slayer unlocks - */ - SUPERIOR_ENABLED(5362), - FOSSIL_ISLAND_WYVERN_DISABLE(6251), + /** + * The varbit that stores the oxygen percentage for player + */ + OXYGEN_LEVEL(5811), - CURRENT_BANK_TAB(4150), + /** + * Corp beast damage + */ + CORP_DAMAGE(999), - WORLDHOPPER_FAVROITE_1(4597), - WORLDHOPPER_FAVROITE_2(4598), + /** + * Toggleable slayer unlocks + */ + SUPERIOR_ENABLED(5362), + FOSSIL_ISLAND_WYVERN_DISABLE(6251), - /** - * Vengeance is active - */ - VENGEANCE_ACTIVE(2450), + CURRENT_BANK_TAB(4150), - /** - * Spell cooldowns - */ - VENGEANCE_COOLDOWN(2451), + WORLDHOPPER_FAVROITE_1(4597), + WORLDHOPPER_FAVROITE_2(4598), - /** - * Amount of items in each bank tab - */ - BANK_TAB_ONE_COUNT(4171), - BANK_TAB_TWO_COUNT(4172), - BANK_TAB_THREE_COUNT(4173), - BANK_TAB_FOUR_COUNT(4174), - BANK_TAB_FIVE_COUNT(4175), - BANK_TAB_SIX_COUNT(4176), - BANK_TAB_SEVEN_COUNT(4177), - BANK_TAB_EIGHT_COUNT(4178), - BANK_TAB_NINE_COUNT(4179), + /** + * Vengeance is active + */ + VENGEANCE_ACTIVE(2450), - /** - * Type of GE offer currently being created - * 0 = buy - * 1 = sell - */ - GE_OFFER_CREATION_TYPE(4397), + /** + * Spell cooldowns + */ + VENGEANCE_COOLDOWN(2451), - /** - * The active tab within the quest interface - */ - QUEST_TAB(8168), - - /** - * Temple Trekking - */ - TREK_POINTS(1955), - TREK_STARTED(1956), - TREK_EVENT(1958), - TREK_STATUS(6719); + /** + * Amount of items in each bank tab + */ + BANK_TAB_ONE_COUNT(4171), + BANK_TAB_TWO_COUNT(4172), + BANK_TAB_THREE_COUNT(4173), + BANK_TAB_FOUR_COUNT(4174), + BANK_TAB_FIVE_COUNT(4175), + BANK_TAB_SIX_COUNT(4176), + BANK_TAB_SEVEN_COUNT(4177), + BANK_TAB_EIGHT_COUNT(4178), + BANK_TAB_NINE_COUNT(4179), + /** + * Type of GE offer currently being created + * 0 = buy + * 1 = sell + */ + GE_OFFER_CREATION_TYPE(4397), - /** - * The raw varbit ID. - */ - private final int id; + /** + * The active tab within the quest interface + */ + QUEST_TAB(8168), + + /** + * Temple Trekking + */ + TREK_POINTS(1955), + TREK_STARTED(1956), + TREK_EVENT(1958), + TREK_STATUS(6719), + BLOAT_ENTERED_ROOM(6447); + + /** + * The raw varbit ID. + */ + private final int id; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java index e630c28b4f..1d54442c6d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPanel.java @@ -44,7 +44,6 @@ public class EquipmentInspectorPanel extends PluginPanel c.weightx = 1; c.gridx = 0; c.gridy = 0; - header = new JPanel(); header.setLayout(new BorderLayout()); header.setBorder(new CompoundBorder( @@ -53,9 +52,7 @@ public class EquipmentInspectorPanel extends PluginPanel nameLabel = new JLabel(NO_PLAYER_SELECTED); nameLabel.setForeground(Color.WHITE); - header.add(nameLabel, BorderLayout.CENTER); - layout.setHorizontalGroup(layout.createParallelGroup() .addComponent(equipmentPanels) .addComponent(header) @@ -65,7 +62,6 @@ public class EquipmentInspectorPanel extends PluginPanel .addGap(10) .addComponent(equipmentPanels) ); - update(new HashMap<>(), ""); } @@ -79,7 +75,6 @@ public class EquipmentInspectorPanel extends PluginPanel { nameLabel.setText("Player: " + playerName); } - SwingUtilities.invokeLater(() -> { equipmentPanels.removeAll(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java index 5ea9ea76b6..29904c2fb8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/EquipmentInspectorPlugin.java @@ -3,7 +3,10 @@ package net.runelite.client.plugins.equipmentinspector; import com.google.inject.Provides; import lombok.extern.slf4j.Slf4j; -import net.runelite.api.*; +import net.runelite.api.ChatMessageType; +import net.runelite.api.Client; +import net.runelite.api.ItemComposition; +import net.runelite.api.Player; import net.runelite.api.events.PlayerMenuOptionClicked; import net.runelite.api.kit.KitType; import net.runelite.client.chat.ChatColorType; @@ -18,11 +21,10 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; +import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; -import net.runelite.http.api.item.ItemPrice; import javax.annotation.Nullable; -import javax.imageio.ImageIO; import javax.inject.Inject; import javax.swing.*; import java.awt.image.BufferedImage; @@ -32,211 +34,195 @@ import java.util.*; import java.util.concurrent.ScheduledExecutorService; @PluginDescriptor( - name = "Equipment Inspector", - description = "Inspects enemy equipment", - enabledByDefault = false, - type = "utility" + name = "Equipment Inspector", + enabledByDefault = false, + type = "utility" ) @Slf4j public class EquipmentInspectorPlugin extends Plugin { - private static final String INSPECT_EQUIPMENT = "Gear"; - private static final String KICK_OPTION = "Kick"; + private static final String INSPECT_EQUIPMENT = "Gear"; + private static final String KICK_OPTION = "Kick"; - @Inject - @Nullable - private Client client; + @Inject + @Nullable + private Client client; - @Inject - private ItemManager itemManager; + @Inject + private ItemManager itemManager; - @Inject - private EquipmentInspectorConfig config; + @Inject + private EquipmentInspectorConfig config; - @Inject - private ChatMessageManager chatMessageManager; - @Inject - private MenuManager menuManager; + @Inject + private ChatMessageManager chatMessageManager; + @Inject + private MenuManager menuManager; - @Inject - private ScheduledExecutorService executor; + @Inject + private ScheduledExecutorService executor; - @Inject - private ClientToolbar pluginToolbar; + @Inject + private ClientToolbar pluginToolbar; + private NavigationButton navButton; + private EquipmentInspectorPanel equipmentInspectorPanel; + private int TotalPrice = 0; + private int Prot1 = 0; + private int Prot2 = 0; + private int Prot3 = 0; + private int Prot4 = 0; - @Provides - EquipmentInspectorConfig provideConfig(ConfigManager configManager) - { - return configManager.getConfig(EquipmentInspectorConfig.class); - } + @Provides + EquipmentInspectorConfig provideConfig(ConfigManager configManager) { + return configManager.getConfig(EquipmentInspectorConfig.class); + } - private NavigationButton navButton; - private EquipmentInspectorPanel equipmentInspectorPanel; - private int TotalPrice = 0; - private int Prot1 = 0; - private int Prot2 = 0; - private int Prot3 = 0; - private int Prot4 = 0; + @Override + protected void startUp() throws Exception { + + equipmentInspectorPanel = injector.getInstance(EquipmentInspectorPanel.class); + if (client != null) { + menuManager.addPlayerMenuItem(INSPECT_EQUIPMENT); + } + + //synchronized (ImageIO.class) + //{ + final BufferedImage icon = ImageUtil.getResourceStreamFromClass(this.getClass(), "normal.png"); + //} + + navButton = NavigationButton.builder() + .tooltip("Equipment Inspector") + .icon(icon) + .priority(5) + .panel(equipmentInspectorPanel) + .build(); - @Override - protected void startUp() throws Exception - { + pluginToolbar.addNavigation(navButton); - equipmentInspectorPanel = injector.getInstance(EquipmentInspectorPanel.class); - if(client != null) { - menuManager.addPlayerMenuItem(INSPECT_EQUIPMENT); - } + } - BufferedImage icon; - synchronized (ImageIO.class) - { - icon = ImageIO.read(getClass().getResourceAsStream("normal.png")); - } + @Override + protected void shutDown() throws Exception { - navButton = NavigationButton.builder() - .tooltip("Equipment Inspector") - .icon(icon) - .priority(5) - .panel(equipmentInspectorPanel) - .build(); + menuManager.removePlayerMenuItem(INSPECT_EQUIPMENT); + } + + @Subscribe + public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) { + if (event.getMenuOption().equals(INSPECT_EQUIPMENT)) { - pluginToolbar.addNavigation(navButton); + executor.execute(() -> + { + try { + SwingUtilities.invokeAndWait(() -> + { + if (!navButton.isSelected()) { + navButton.getOnSelect().run(); + } + }); + } catch (InterruptedException | InvocationTargetException e) { - } + throw new RuntimeException(e); - @Override - protected void shutDown() throws Exception - { + } + String playerName = Text.removeTags(event.getMenuTarget()); + // The player menu uses a non-breaking space in the player name, we need to replace this to compare + // against the playerName in the player cache. + String finalPlayerName = playerName.replace('\u00A0', ' '); + System.out.println(finalPlayerName); + List players = client.getPlayers(); + Optional targetPlayer = players.stream() + .filter(Objects::nonNull) + .filter(p -> p.getName().equals(finalPlayerName)).findFirst(); - menuManager.removePlayerMenuItem(INSPECT_EQUIPMENT); - } + if (targetPlayer.isPresent()) { + TotalPrice = 0; + Prot1 = 0; + Prot2 = 0; + Prot3 = 0; + Prot4 = 0; + Player p = targetPlayer.get(); + Map playerEquipment = new HashMap<>(); - @Subscribe - public void onPlayerMenuOptionClicked(PlayerMenuOptionClicked event) - { - if (event.getMenuOption().equals(INSPECT_EQUIPMENT)) - { + for (KitType kitType : KitType.values()) { + int itemId = p.getPlayerComposition().getEquipmentId(kitType); + if (itemId != -1) { + ItemComposition itemComposition = client.getItemDefinition(itemId); + playerEquipment.put(kitType, itemComposition); + int ItemPrice = itemManager.getItemPrice(itemId); + TotalPrice += ItemPrice; + if (ItemPrice > Prot1) { + Prot4 = Prot3; + Prot3 = Prot2; + Prot2 = Prot1; + Prot1 = ItemPrice; + } else if (ItemPrice > Prot2) { + Prot4 = Prot3; + Prot3 = Prot2; + Prot2 = ItemPrice; + } else if (ItemPrice > Prot3) { + Prot4 = Prot3; + Prot3 = ItemPrice; + } else if (ItemPrice > Prot4) { + Prot4 = ItemPrice; + } + } + } + int IgnoredItems = config.protecteditems(); + if (IgnoredItems != 0 && IgnoredItems != 1 && IgnoredItems != 2 && IgnoredItems != 3) { + IgnoredItems = 4; - executor.execute(() -> - { - try - { - SwingUtilities.invokeAndWait(() -> - { - if (!navButton.isSelected()) - { - navButton.getOnSelect().run(); - } - }); - } - catch (InterruptedException | InvocationTargetException e) - { + } + if (config.ShowValue()) { + switch (IgnoredItems) { + case 1: + TotalPrice = TotalPrice - Prot1; + break; + case 2: + TotalPrice = TotalPrice - Prot1; + TotalPrice = TotalPrice - Prot2; - throw new RuntimeException(e); + break; + case 3: + TotalPrice = TotalPrice - Prot1; + TotalPrice = TotalPrice - Prot2; + TotalPrice = TotalPrice - Prot3; + break; + case 4: + TotalPrice = TotalPrice - Prot1; + TotalPrice = TotalPrice - Prot2; + TotalPrice = TotalPrice - Prot3; + TotalPrice = TotalPrice - Prot4; + break; + } + String StringPrice = ""; + if (!config.ExactValue()) { + TotalPrice = TotalPrice / 1000; + StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); + StringPrice = StringPrice + 'K'; + } + if (config.ExactValue()) { + StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); + } + chatMessageManager.queue(QueuedMessage.builder() + .type(ChatMessageType.FRIENDSCHATNOTIFICATION) + .runeLiteFormattedMessage(new ChatMessageBuilder() + .append(ChatColorType.HIGHLIGHT) + .append("Risked Value: ") + .append(ChatColorType.NORMAL) + .append(StringPrice) + .build()) + .build()); + } + equipmentInspectorPanel.update(playerEquipment, playerName); - } - String playerName = Text.removeTags(event.getMenuTarget()); - // The player menu uses a non-breaking space in the player name, we need to replace this to compare - // against the playerName in the player cache. - String finalPlayerName = playerName.replace('\u00A0', ' '); - System.out.println(finalPlayerName); - List players = client.getPlayers(); - Optional targetPlayer = players.stream() - .filter(Objects::nonNull) - .filter(p -> p.getName().equals(finalPlayerName)).findFirst(); - - if (targetPlayer.isPresent()) - { - TotalPrice = 0; - Prot1 = 0; - Prot2 = 0; - Prot3 = 0; - Prot4 = 0; - Player p = targetPlayer.get(); - Map playerEquipment = new HashMap<>(); - - for (KitType kitType : KitType.values()) - { - int itemId = p.getPlayerComposition().getEquipmentId(kitType); - if (itemId != -1) - { - ItemComposition itemComposition = client.getItemDefinition(itemId); - playerEquipment.put(kitType, itemComposition); - int ItemPrice = itemManager.getItemPrice(itemId); - TotalPrice += ItemPrice; - if (ItemPrice > Prot1 ) { - Prot4 = Prot3; - Prot3 = Prot2; - Prot2 = Prot1; - - Prot1 = ItemPrice; - } else if (ItemPrice > Prot2){ - Prot4 = Prot3; - Prot3 = Prot2; - Prot2 = ItemPrice; - } else if (ItemPrice > Prot3){ - Prot4 = Prot3; - Prot3 = ItemPrice; - } else if (ItemPrice > Prot4){ - Prot4 = ItemPrice; - } - } - } - int IgnoredItems = config.protecteditems(); - if (IgnoredItems != 0 && IgnoredItems != 1 && IgnoredItems != 2 && IgnoredItems != 3) { - IgnoredItems = 4; - - } - if (config.ShowValue()) { - switch (IgnoredItems) { - case 1: - TotalPrice = TotalPrice - Prot1; - break; - case 2: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - - break; - case 3: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - TotalPrice = TotalPrice - Prot3; - break; - case 4: - TotalPrice = TotalPrice - Prot1; - TotalPrice = TotalPrice - Prot2; - TotalPrice = TotalPrice - Prot3; - TotalPrice = TotalPrice - Prot4; - break; - } - String StringPrice = ""; - if (!config.ExactValue()) { - TotalPrice = TotalPrice / 1000; - StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); - StringPrice = StringPrice + 'K'; - } - if (config.ExactValue()) { - StringPrice = NumberFormat.getIntegerInstance().format(TotalPrice); - } - chatMessageManager.queue(QueuedMessage.builder() - .type(ChatMessageType.FRIENDSCHATNOTIFICATION) - .runeLiteFormattedMessage(new ChatMessageBuilder() - .append(ChatColorType.HIGHLIGHT) - .append("Risked Value: ") - .append(ChatColorType.NORMAL) - .append(StringPrice) - .build()) - .build()); - } - equipmentInspectorPanel.update(playerEquipment, playerName); - - } - }); - } - } -} + } + }); + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java index 873bf058b6..fadc684588 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/equipmentinspector/ItemPanel.java @@ -15,7 +15,8 @@ class ItemPanel extends JPanel ItemPanel(ItemComposition item, KitType kitType, AsyncBufferedImage icon) { - setBorder(new EmptyBorder(3, 3, 3, 3)); + + setBorder(new EmptyBorder(3, 3, 3, 3)); setBackground(ColorScheme.DARK_GRAY_COLOR); GroupLayout layout = new GroupLayout(this); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java index 78199bfcc5..4bee22c082 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/fkeyremapping/fKeyRemappingPlugin.java @@ -16,6 +16,7 @@ import net.runelite.client.plugins.PluginDescriptor; name = "fKeyRemapping", description = "Used for interface hotkeys", tags = {"hotkey", "remapping"}, + type = "utility", enabledByDefault = true ) public class fKeyRemappingPlugin extends Plugin diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java new file mode 100644 index 0000000000..85a07780de --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerOverlay.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018 AWPH-I + * 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.lootingbagviewer; + +import net.runelite.api.Client; +import net.runelite.api.InventoryID; +import net.runelite.api.Item; +import net.runelite.api.ItemContainer; +import net.runelite.client.game.ItemManager; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ImageComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; + +import javax.inject.Inject; +import java.awt.*; +import java.awt.image.BufferedImage; + +class LootingBagViewerOverlay 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 final Client client; + private final ItemManager itemManager; + + private final PanelComponent panelComponent = new PanelComponent(); + + private ItemContainer itemContainer; + private Item[] items; + + @Inject + private LootingBagViewerOverlay(Client client, ItemManager itemManager) + { + setPosition(OverlayPosition.BOTTOM_RIGHT); + panelComponent.setWrapping(4); + panelComponent.setGap(new Point(6, 4)); + panelComponent.setOrientation(PanelComponent.Orientation.HORIZONTAL); + this.itemManager = itemManager; + this.client = client; + + } + + @Override + public Dimension render(Graphics2D graphics) + { + if (itemContainer == null) + { + if(client.getItemContainer(InventoryID.LOOTING_BAG) != null) { + itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); + items = itemContainer.getItems(); + } + return null; + } + else if(itemContainer != null && client.getItemContainer(InventoryID.LOOTING_BAG) != null) + { + itemContainer = client.getItemContainer(InventoryID.LOOTING_BAG); + Item[] tempItems = itemContainer.getItems(); + + for(int i = 0; i < items.length; i++) + { + if(!items[i].equals(tempItems[i])) + { + items = tempItems; + } + } + } + + panelComponent.getChildren().clear(); + + for (int i = 0; i < INVENTORY_SIZE; i++) + { + if (i < items.length) + { + final Item item = items[i]; + if (item.getQuantity() > 0) + { + final BufferedImage image = getImage(item); + if (image != null) + { + panelComponent.getChildren().add(new ImageComponent(image)); + continue; + } + } + } + + // put a placeholder image so each item is aligned properly and the panel is not resized + panelComponent.getChildren().add(PLACEHOLDER_IMAGE); + } + + return panelComponent.render(graphics); + } + + private BufferedImage getImage(Item item) + { + return itemManager.getImage(item.getId(), item.getQuantity(), item.getQuantity() > 1); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java new file mode 100644 index 0000000000..5d28a4bbea --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/lootingbagviewer/LootingBagViewerPlugin.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018 AWPH-I + * 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.lootingbagviewer; + +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.OverlayManager; + +import javax.inject.Inject; + +@PluginDescriptor( + name = "PvP Looting Bag Viewer", + description = "Add an overlay showing the contents of your looting bag", + tags = {"alternate", "items", "overlay", "second"}, + type = "utility", + enabledByDefault = false +) +public class LootingBagViewerPlugin extends Plugin +{ + @Inject + private net.runelite.client.plugins.lootingbagviewer.LootingBagViewerOverlay overlay; + + @Inject + private OverlayManager overlayManager; + + @Override + public void startUp() + { + overlayManager.add(overlay); + } + + @Override + public void shutDown() + { + overlayManager.remove(overlay); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java new file mode 100644 index 0000000000..ebbad81a54 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/BatSolver.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving.BatSolver; + +import java.util.Map; +import java.util.HashSet; +import java.util.HashMap; +import java.util.TreeSet; +import java.util.List; +import java.util.ArrayList; +import static net.runelite.client.plugins.raidsthieving.BatSolver.SolutionSet.SOLUTION_SETS; + +public class BatSolver +{ + private Map numberOfSolutionsWithPoison; + private final SolutionSet solution; + + private final HashSet grubsChests; + + public BatSolver(ThievingRoomType roomType) + { + solution = new SolutionSet(roomType); + grubsChests = new HashSet<>(); + } + + public void addEmptyChest(int chestId) + { + // When a new empty chest is found, add it to the current solution set + solution.addEmptyChest(chestId); + calculateChanceOfPoison(); + } + + public void addGrubsChest(int chestId) + { + // When a chest with grubs is found, keep track of it to invalidate solutions + grubsChests.add(chestId); + calculateChanceOfPoison(); + } + + public TreeSet matchSolutions() + { + TreeSet possibleEmptyChests = new TreeSet<>(); + for (SolutionSet knownSolution : SolutionSet.SOLUTION_SETS) + { + if (knownSolution.getType() == solution.getType() && matchSolution(knownSolution)) + { + possibleEmptyChests.addAll(knownSolution.getEmptyChests()); + } + } + + return possibleEmptyChests; + } + + private boolean matchSolution(SolutionSet testSolution) + { + for (Integer grubsChest : grubsChests) + { + if (testSolution.containsChest(grubsChest)) + { + // If one of the chests is known to have grubs, it cannot be a solution + return false; + } + } + + boolean matchesAll = true; + boolean everMatched = false; + for (int i : solution.getEmptyChests()) + { + if (!testSolution.containsChest(i)) + { + matchesAll = false; + } + else + { + everMatched = true; + } + } + return matchesAll && everMatched; + } + + public ThievingRoomType getType() + { + return solution.getType(); + } + + + public void calculateChanceOfPoison() + { + if (getType() == null) + { + numberOfSolutionsWithPoison = null; + return; + } + + numberOfSolutionsWithPoison = new HashMap<>(); + for (SolutionSet sol : getPosssibleSolutions()) + { + if (getType() == sol.getType() && (solution.getEmptyChests().size() == 0 || matchSolution(sol))) + { + for (Integer i : sol.getEmptyChests()) + { + if (numberOfSolutionsWithPoison.containsKey(i)) + { + numberOfSolutionsWithPoison.put(i, numberOfSolutionsWithPoison.get(i) + 1); + } + else + { + numberOfSolutionsWithPoison.put(i, 1); + } + } + } + } + } + + private List getPosssibleSolutions() + { + List possibleSolutions = new ArrayList<>(); + for (SolutionSet soln : SOLUTION_SETS) + { + // Check if we've found grubs in one of the chests, invalidating it as an solution + boolean foundMatch = false; + for (int i : grubsChests) + { + if (soln.containsChest(i)) + { + foundMatch = true; + } + } + if (!foundMatch) + { + possibleSolutions.add(soln); + } + } + return possibleSolutions; + } + + public double relativeLikelihoodPoison(int chestId) + { + // Returns a double between 0 and 1 of how likely the chest has poison based on the number of possible solutions + // Uses a Sigmoid like function to give good contrast in drawn opacity, + // perhaps could be changed to something more accurate quantitavely. + if (numberOfSolutionsWithPoison == null) + { + calculateChanceOfPoison(); + } + if (numberOfSolutionsWithPoison == null) + { + return 1.0; + } + int mostFrequentPoison = 0; + for (Map.Entry entry : numberOfSolutionsWithPoison.entrySet()) + { + if (entry.getValue() > mostFrequentPoison) + { + mostFrequentPoison = entry.getValue(); + } + } + int timesFound = 0; + if (numberOfSolutionsWithPoison.containsKey(chestId)) + { + timesFound = numberOfSolutionsWithPoison.get(chestId); + } + double chestChance = (double) (timesFound) / (double) (mostFrequentPoison); + return 1. / (1 + Math.exp(5 - 10 * chestChance)); + } + + public int getNumberOfEmptyChests() + { + return solution.getEmptyChests().size(); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java new file mode 100644 index 0000000000..7346e4ecf6 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ChestIdentifier.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving.BatSolver; + +import net.runelite.client.plugins.raidsthieving.InstancePoint; +import net.runelite.client.plugins.raidsthieving.ThievingChest; +import java.util.HashMap; +import java.util.Map; + +public class ChestIdentifier +{ + public ChestIdentifier(ThievingRoomType roomType) + { + chestIds = new HashMap<>(); + switch (roomType) + { + case LEFT_TURN: + chestIds.put(new InstancePoint(3283, 5379), 1); + chestIds.put(new InstancePoint(3285, 5380), 2); + chestIds.put(new InstancePoint(3279, 5381), 3); + chestIds.put(new InstancePoint(3287, 5382), 4); + chestIds.put(new InstancePoint(3281, 5382), 5); + chestIds.put(new InstancePoint(3284, 5383), 6); + chestIds.put(new InstancePoint(3283, 5384), 7); + chestIds.put(new InstancePoint(3286, 5384), 8); + chestIds.put(new InstancePoint(3288, 5384), 9); + chestIds.put(new InstancePoint(3277, 5385), 10); + chestIds.put(new InstancePoint(3280, 5385), 11); + chestIds.put(new InstancePoint(3285, 5386), 12); + chestIds.put(new InstancePoint(3290, 5386), 13); + chestIds.put(new InstancePoint(3275, 5387), 14); + chestIds.put(new InstancePoint(3287, 5387), 15); + chestIds.put(new InstancePoint(3288, 5387), 16); + chestIds.put(new InstancePoint(3281, 5388), 17); + chestIds.put(new InstancePoint(3291, 5388), 18); + chestIds.put(new InstancePoint(3280, 5389), 19); + chestIds.put(new InstancePoint(3285, 5389), 20); + chestIds.put(new InstancePoint(3289, 5389), 21); + chestIds.put(new InstancePoint(3283, 5390), 22); + chestIds.put(new InstancePoint(3285, 5390), 23); + chestIds.put(new InstancePoint(3288, 5390), 24); + chestIds.put(new InstancePoint(3290, 5390), 25); + chestIds.put(new InstancePoint(3282, 5391), 26); + chestIds.put(new InstancePoint(3289, 5391), 27); + chestIds.put(new InstancePoint(3292, 5391), 28); + chestIds.put(new InstancePoint(3279, 5392), 29); + chestIds.put(new InstancePoint(3276, 5393), 30); + chestIds.put(new InstancePoint(3279, 5393), 31); + chestIds.put(new InstancePoint(3284, 5393), 32); + chestIds.put(new InstancePoint(3285, 5393), 33); + chestIds.put(new InstancePoint(3291, 5393), 34); + chestIds.put(new InstancePoint(3275, 5394), 35); + chestIds.put(new InstancePoint(3277, 5394), 36); + chestIds.put(new InstancePoint(3288, 5394), 37); + chestIds.put(new InstancePoint(3276, 5395), 38); + chestIds.put(new InstancePoint(3281, 5395), 39); + chestIds.put(new InstancePoint(3285, 5395), 40); + chestIds.put(new InstancePoint(3287, 5395), 41); + chestIds.put(new InstancePoint(3289, 5395), 42); + chestIds.put(new InstancePoint(3274, 5396), 43); + chestIds.put(new InstancePoint(3283, 5396), 44); + chestIds.put(new InstancePoint(3285, 5396), 45); + chestIds.put(new InstancePoint(3288, 5396), 46); + chestIds.put(new InstancePoint(3272, 5397), 47); + chestIds.put(new InstancePoint(3280, 5397), 48); + chestIds.put(new InstancePoint(3277, 5398), 49); + chestIds.put(new InstancePoint(3281, 5398), 50); + chestIds.put(new InstancePoint(3284, 5398), 51); + chestIds.put(new InstancePoint(3276, 5399), 52); + chestIds.put(new InstancePoint(3278, 5399), 53); + chestIds.put(new InstancePoint(3283, 5399), 54); + chestIds.put(new InstancePoint(3285, 5399), 55); + chestIds.put(new InstancePoint(3277, 5400), 56); + chestIds.put(new InstancePoint(3284, 5400), 57); + chestIds.put(new InstancePoint(3288, 5400), 58); + chestIds.put(new InstancePoint(3281, 5401), 59); + chestIds.put(new InstancePoint(3286, 5401), 60); + chestIds.put(new InstancePoint(3279, 5402), 61); + chestIds.put(new InstancePoint(3285, 5402), 62); + chestIds.put(new InstancePoint(3280, 5403), 63); + chestIds.put(new InstancePoint(3283, 5403), 64); + break; + case RIGHT_TURN: + chestIds.put(new InstancePoint(3338, 5405), 1); + chestIds.put(new InstancePoint(3334, 5405), 2); + chestIds.put(new InstancePoint(3342, 5404), 3); + chestIds.put(new InstancePoint(3340, 5404), 4); + chestIds.put(new InstancePoint(3345, 5403), 5); + chestIds.put(new InstancePoint(3334, 5403), 6); + chestIds.put(new InstancePoint(3330, 5403), 7); + chestIds.put(new InstancePoint(3343, 5402), 8); + chestIds.put(new InstancePoint(3342, 5402), 9); + chestIds.put(new InstancePoint(3339, 5402), 10); + chestIds.put(new InstancePoint(3338, 5402), 11); + chestIds.put(new InstancePoint(3336, 5402), 12); + chestIds.put(new InstancePoint(3347, 5401), 13); + chestIds.put(new InstancePoint(3330, 5401), 14); + chestIds.put(new InstancePoint(3345, 5400), 15); + chestIds.put(new InstancePoint(3341, 5400), 16); + chestIds.put(new InstancePoint(3337, 5400), 17); + chestIds.put(new InstancePoint(3334, 5400), 18); + chestIds.put(new InstancePoint(3345, 5399), 19); + chestIds.put(new InstancePoint(3343, 5399), 20); + chestIds.put(new InstancePoint(3340, 5399), 21); + chestIds.put(new InstancePoint(3335, 5399), 22); + chestIds.put(new InstancePoint(3331, 5399), 23); + chestIds.put(new InstancePoint(3338, 5398), 24); + chestIds.put(new InstancePoint(3337, 5398), 25); + chestIds.put(new InstancePoint(3345, 5397), 26); + chestIds.put(new InstancePoint(3341, 5397), 27); + chestIds.put(new InstancePoint(3334, 5397), 28); + chestIds.put(new InstancePoint(3331, 5397), 29); + chestIds.put(new InstancePoint(3346, 5396), 30); + chestIds.put(new InstancePoint(3343, 5396), 31); + chestIds.put(new InstancePoint(3339, 5396), 32); + chestIds.put(new InstancePoint(3335, 5396), 33); + chestIds.put(new InstancePoint(3333, 5396), 34); + chestIds.put(new InstancePoint(3340, 5395), 35); + chestIds.put(new InstancePoint(3337, 5395), 36); + chestIds.put(new InstancePoint(3334, 5395), 37); + chestIds.put(new InstancePoint(3345, 5394), 38); + chestIds.put(new InstancePoint(3342, 5394), 39); + chestIds.put(new InstancePoint(3332, 5394), 40); + chestIds.put(new InstancePoint(3343, 5393), 41); + chestIds.put(new InstancePoint(3341, 5393), 42); + chestIds.put(new InstancePoint(3338, 5393), 43); + chestIds.put(new InstancePoint(3335, 5393), 44); + chestIds.put(new InstancePoint(3334, 5393), 45); + chestIds.put(new InstancePoint(3346, 5392), 46); + chestIds.put(new InstancePoint(3342, 5392), 47); + chestIds.put(new InstancePoint(3332, 5392), 48); + chestIds.put(new InstancePoint(3350, 5391), 49); + chestIds.put(new InstancePoint(3346, 5391), 50); + chestIds.put(new InstancePoint(3340, 5391), 51); + chestIds.put(new InstancePoint(3339, 5391), 52); + chestIds.put(new InstancePoint(3336, 5391), 53); + chestIds.put(new InstancePoint(3333, 5391), 54); + chestIds.put(new InstancePoint(3349, 5390), 55); + chestIds.put(new InstancePoint(3343, 5390), 56); + chestIds.put(new InstancePoint(3337, 5390), 57); + chestIds.put(new InstancePoint(3335, 5390), 58); + chestIds.put(new InstancePoint(3344, 5389), 59); + chestIds.put(new InstancePoint(3340, 5389), 60); + chestIds.put(new InstancePoint(3336, 5389), 61); + chestIds.put(new InstancePoint(3333, 5389), 62); + chestIds.put(new InstancePoint(3346, 5388), 63); + chestIds.put(new InstancePoint(3340, 5387), 64); + chestIds.put(new InstancePoint(3337, 5386), 65); + chestIds.put(new InstancePoint(3333, 5386), 66); + chestIds.put(new InstancePoint(3338, 5385), 67); + chestIds.put(new InstancePoint(3336, 5385), 68); + chestIds.put(new InstancePoint(3337, 5384), 69); + chestIds.put(new InstancePoint(3340, 5382), 70); + chestIds.put(new InstancePoint(3334, 5383), 71); + chestIds.put(new InstancePoint(3340, 5379), 72); + chestIds.put(new InstancePoint(3338, 5380), 73); + chestIds.put(new InstancePoint(3336, 5381), 74); + break; + case STRAIGHT: + chestIds.put(new InstancePoint(3308, 5378), 1); + chestIds.put(new InstancePoint(3305, 5379), 2); + chestIds.put(new InstancePoint(3307, 5379), 3); + chestIds.put(new InstancePoint(3304, 5381), 4); + chestIds.put(new InstancePoint(3310, 5381), 5); + chestIds.put(new InstancePoint(3302, 5382), 6); + chestIds.put(new InstancePoint(3307, 5382), 7); + chestIds.put(new InstancePoint(3312, 5382), 8); + chestIds.put(new InstancePoint(3317, 5382), 9); + chestIds.put(new InstancePoint(3319, 5382), 10); + chestIds.put(new InstancePoint(3304, 5383), 11); + chestIds.put(new InstancePoint(3305, 5383), 12); + chestIds.put(new InstancePoint(3307, 5383), 13); + chestIds.put(new InstancePoint(3310, 5383), 14); + chestIds.put(new InstancePoint(3315, 5383), 15); + chestIds.put(new InstancePoint(3320, 5383), 16); + chestIds.put(new InstancePoint(3300, 5384), 17); + chestIds.put(new InstancePoint(3309, 5384), 18); + chestIds.put(new InstancePoint(3311, 5384), 19); + chestIds.put(new InstancePoint(3313, 5384), 20); + chestIds.put(new InstancePoint(3317, 5384), 21); + chestIds.put(new InstancePoint(3318, 5384), 22); + chestIds.put(new InstancePoint(3302, 5385), 23); + chestIds.put(new InstancePoint(3306, 5385), 24); + chestIds.put(new InstancePoint(3310, 5385), 25); + chestIds.put(new InstancePoint(3313, 5385), 26); + chestIds.put(new InstancePoint(3320, 5385), 27); + chestIds.put(new InstancePoint(3302, 5386), 28); + chestIds.put(new InstancePoint(3305, 5386), 29); + chestIds.put(new InstancePoint(3316, 5386), 30); + chestIds.put(new InstancePoint(3321, 5386), 31); + chestIds.put(new InstancePoint(3300, 5387), 32); + chestIds.put(new InstancePoint(3308, 5387), 33); + chestIds.put(new InstancePoint(3314, 5387), 34); + chestIds.put(new InstancePoint(3317, 5387), 35); + chestIds.put(new InstancePoint(3301, 5388), 36); + chestIds.put(new InstancePoint(3306, 5388), 37); + chestIds.put(new InstancePoint(3312, 5388), 38); + chestIds.put(new InstancePoint(3322, 5388), 39); + chestIds.put(new InstancePoint(3309, 5389), 40); + chestIds.put(new InstancePoint(3311, 5389), 41); + chestIds.put(new InstancePoint(3313, 5389), 42); + chestIds.put(new InstancePoint(3316, 5389), 43); + chestIds.put(new InstancePoint(3320, 5389), 44); + chestIds.put(new InstancePoint(3300, 5390), 45); + chestIds.put(new InstancePoint(3303, 5390), 46); + chestIds.put(new InstancePoint(3304, 5390), 47); + chestIds.put(new InstancePoint(3312, 5390), 48); + chestIds.put(new InstancePoint(3320, 5390), 49); + chestIds.put(new InstancePoint(3307, 5391), 50); + chestIds.put(new InstancePoint(3310, 5391), 51); + chestIds.put(new InstancePoint(3317, 5391), 52); + chestIds.put(new InstancePoint(3318, 5391), 53); + chestIds.put(new InstancePoint(3323, 5391), 54); + chestIds.put(new InstancePoint(3301, 5392), 55); + chestIds.put(new InstancePoint(3303, 5392), 56); + chestIds.put(new InstancePoint(3309, 5392), 57); + chestIds.put(new InstancePoint(3314, 5392), 58); + chestIds.put(new InstancePoint(3322, 5392), 59); + chestIds.put(new InstancePoint(3305, 5393), 60); + chestIds.put(new InstancePoint(3307, 5393), 61); + chestIds.put(new InstancePoint(3316, 5393), 62); + chestIds.put(new InstancePoint(3309, 5394), 63); + chestIds.put(new InstancePoint(3312, 5394), 64); + chestIds.put(new InstancePoint(3322, 5394), 65); + chestIds.put(new InstancePoint(3310, 5379), 66); + break; + } + + } + + public int indentifyChest(ThievingChest chest) + { + int id = chestIds.get(chest.getInstancePoint()); + chest.setChestId(id); + return id; + } + + private Map chestIds; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java new file mode 100644 index 0000000000..dc1c3c3dc2 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/SolutionSet.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving.BatSolver; + +import lombok.Getter; +import java.util.HashSet; +import java.util.Arrays; +import java.util.Set; + +// Each Thieving room has 4 empty chests +// User-reported data shows these 4 come in groups, +// +// e.g. if there is an empty chest in L room chest 1, the other empty chests could be 16, 17, 38, 54, 55 +// See https://dikkenoob.github.io/ for more information + +public class SolutionSet +{ + public static final SolutionSet[] SOLUTION_SETS = + { + new SolutionSet(ThievingRoomType.LEFT_TURN, 1, 16, 17, 55), + new SolutionSet(ThievingRoomType.LEFT_TURN, 1, 17, 38, 54), + new SolutionSet(ThievingRoomType.LEFT_TURN, 2, 7, 21, 37), + new SolutionSet(ThievingRoomType.LEFT_TURN, 3, 5, 19, 30), + new SolutionSet(ThievingRoomType.LEFT_TURN, 3, 11, 15, 40), + new SolutionSet(ThievingRoomType.LEFT_TURN, 4, 22, 27, 46), + new SolutionSet(ThievingRoomType.LEFT_TURN, 5, 9, 19, 45), + new SolutionSet(ThievingRoomType.LEFT_TURN, 6, 24, 26, 41), + new SolutionSet(ThievingRoomType.LEFT_TURN, 6, 26, 32, 52), + new SolutionSet(ThievingRoomType.LEFT_TURN, 7, 13, 44, 59), + new SolutionSet(ThievingRoomType.LEFT_TURN, 8, 14, 41, 43), + new SolutionSet(ThievingRoomType.LEFT_TURN, 8, 10, 28, 33), + new SolutionSet(ThievingRoomType.LEFT_TURN, 8, 31, 47, 50), + new SolutionSet(ThievingRoomType.LEFT_TURN, 10, 35, 54, 63), + new SolutionSet(ThievingRoomType.LEFT_TURN, 10, 30, 32, 59), + new SolutionSet(ThievingRoomType.LEFT_TURN, 12, 40, 53, 56), + new SolutionSet(ThievingRoomType.LEFT_TURN, 12, 13, 42, 54), + new SolutionSet(ThievingRoomType.LEFT_TURN, 13, 22, 27, 46), + new SolutionSet(ThievingRoomType.LEFT_TURN, 14, 18, 23, 51), + new SolutionSet(ThievingRoomType.LEFT_TURN, 15, 43, 44, 58), + new SolutionSet(ThievingRoomType.LEFT_TURN, 15, 16, 42, 45), + new SolutionSet(ThievingRoomType.LEFT_TURN, 20, 29, 45, 51), + new SolutionSet(ThievingRoomType.LEFT_TURN, 20, 25, 32, 34), + new SolutionSet(ThievingRoomType.LEFT_TURN, 20, 28, 51, 62), + new SolutionSet(ThievingRoomType.LEFT_TURN, 21, 39, 41, 58), + new SolutionSet(ThievingRoomType.LEFT_TURN, 22, 25, 54, 64), + new SolutionSet(ThievingRoomType.LEFT_TURN, 23, 31, 47, 55), + new SolutionSet(ThievingRoomType.LEFT_TURN, 23, 33, 37, 60), + new SolutionSet(ThievingRoomType.LEFT_TURN, 24, 34, 55), + new SolutionSet(ThievingRoomType.LEFT_TURN, 26, 50, 63, 27), + new SolutionSet(ThievingRoomType.LEFT_TURN, 29, 39, 41, 61), + new SolutionSet(ThievingRoomType.LEFT_TURN, 33, 46, 52, 57), + new SolutionSet(ThievingRoomType.LEFT_TURN, 34, 45, 49, 60), + new SolutionSet(ThievingRoomType.LEFT_TURN, 36, 40, 42, 62), + new SolutionSet(ThievingRoomType.LEFT_TURN, 37, 38, 51, 64), + new SolutionSet(ThievingRoomType.LEFT_TURN, 48, 53, 55, 56), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 1, 6, 28, 41), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 1, 42, 55, 60), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 2, 10, 31, 44), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 2, 33, 51, 68), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 3, 31, 43, 46), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 3, 5, 21, 48), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 4, 20, 24, 33), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 4, 38, 47), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 5, 21, 48), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 5, 17, 35, 63), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 7, 17, 45, 47), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 7, 37, 41, 52), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 8, 13, 40, 42), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 8, 20, 24, 30), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 9, 15, 23, 35), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 11, 13, 21, 50), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 11, 18, 37, 39), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 12, 14, 27, 34), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 14, 45, 67, 71), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 16, 22, 29, 32), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 18, 28, 31, 64), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 19, 21, 63, 69), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 20, 51, 68, 72), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 22, 29, 56, 61), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 23, 53, 66, 74), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 26, 35, 53, 59), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 27, 30, 55, 57), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 31, 58, 60, 73), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 34, 57, 58, 70), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 38, 56, 61, 70), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 40, 54, 65, 72), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 42, 46, 65), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 47, 49, 66, 67), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 48, 62, 69), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 9, 19, 32, 41), + new SolutionSet(ThievingRoomType.RIGHT_TURN, 16, 26, 36, 39), + new SolutionSet(ThievingRoomType.STRAIGHT, 1, 39, 43, 51), + new SolutionSet(ThievingRoomType.STRAIGHT, 2, 15, 20, 53), + new SolutionSet(ThievingRoomType.STRAIGHT, 3, 10, 42, 44), + new SolutionSet(ThievingRoomType.STRAIGHT, 4, 14, 38, 52), + new SolutionSet(ThievingRoomType.STRAIGHT, 5, 6, 35, 41), + new SolutionSet(ThievingRoomType.STRAIGHT, 7, 16, 34, 49), + new SolutionSet(ThievingRoomType.STRAIGHT, 9, 12, 26, 27), + new SolutionSet(ThievingRoomType.STRAIGHT, 13, 25, 30, 31), + new SolutionSet(ThievingRoomType.STRAIGHT, 15, 20, 53), + new SolutionSet(ThievingRoomType.STRAIGHT, 17, 24, 34, 58), + new SolutionSet(ThievingRoomType.STRAIGHT, 18, 23, 35, 57), + new SolutionSet(ThievingRoomType.STRAIGHT, 19, 26, 47, 65), + new SolutionSet(ThievingRoomType.STRAIGHT, 21, 33, 36, 61), + new SolutionSet(ThievingRoomType.STRAIGHT, 21, 54, 66), + new SolutionSet(ThievingRoomType.STRAIGHT, 22, 25, 46, 55), + new SolutionSet(ThievingRoomType.STRAIGHT, 24, 34, 58), + new SolutionSet(ThievingRoomType.STRAIGHT, 28, 40, 52, 62), + new SolutionSet(ThievingRoomType.STRAIGHT, 29, 41, 42, 63), + new SolutionSet(ThievingRoomType.STRAIGHT, 30, 32, 37, 64), + new SolutionSet(ThievingRoomType.STRAIGHT, 39, 43, 51), + new SolutionSet(ThievingRoomType.STRAIGHT, 43, 45, 50, 60), + new SolutionSet(ThievingRoomType.STRAIGHT, 51, 53, 56, 59) + }; + + SolutionSet(ThievingRoomType type) + { + this.type = type; + emptyChests = new HashSet<>(); + } + + private SolutionSet(ThievingRoomType type, Integer... emptyChests) + { + this.type = type; + this.emptyChests = new HashSet<>(Arrays.asList(emptyChests)); + } + + public void addEmptyChest(int chestId) + { + emptyChests.add(chestId); + } + + public boolean containsChest(int chestId) + { + return emptyChests.contains(chestId); + } + + @Getter + private ThievingRoomType type; + + @Getter + private Set emptyChests; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java new file mode 100644 index 0000000000..f709b2d435 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/BatSolver/ThievingRoomType.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving.BatSolver; + +// There are three distinct Thieving rooms, distinguished by the position of the entrance relative to the exit +// e.g. If you enter the room and must turn left to get to the exit and trough, this is a LEFT_TURN + +import net.runelite.client.plugins.raidsthieving.InstancePoint; + +public enum ThievingRoomType +{ + LEFT_TURN(3271, 5389), + RIGHT_TURN(3350, 5399), + STRAIGHT(3317, 5397); + + private final int x; + private final int y; + + ThievingRoomType(int x, int y) + { + this.x = x; + this.y = y; + } + + public static ThievingRoomType IdentifyByInstancePoint(InstancePoint point) + { + for (ThievingRoomType type : ThievingRoomType.values()) + { + if (Math.abs(type.x - point.getX()) <= 1 && + Math.abs(type.y - point.getY()) <= 1) + { + return type; + } + } + + return null; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java new file mode 100644 index 0000000000..5e09486f89 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ChestOverlay.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2018, Tim Lehner + * 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.raidsthieving; + +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.plugins.raidsthieving.BatSolver.BatSolver; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.ProgressPieComponent; +import javax.inject.Inject; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.util.Map; +import java.util.TreeSet; + +/** + * Represents the overlay that shows timers on traps that are placed by the + * player. + */ +public class ChestOverlay extends Overlay +{ + + private final Client client; + private final RaidsThievingPlugin plugin; + private final RaidsThievingConfig config; + + @Inject + ChestOverlay(Client client, RaidsThievingPlugin plugin, RaidsThievingConfig config) + { + setPosition(OverlayPosition.DYNAMIC); + setLayer(OverlayLayer.ABOVE_SCENE); + this.plugin = plugin; + this.config = config; + this.client = client; + } + + @Override + public Dimension render(Graphics2D graphics) + { + drawChests(graphics); + return null; + } + + /** + * Updates the timer colors. + */ + public void updateConfig() + { + } + + /** + * Iterates over all the traps that were placed by the local player, and + * draws a circle or a timer on the trap, depending on the trap state. + * + * @param graphics + */ + private void drawChests(Graphics2D graphics) + { + + for (Map.Entry entry : plugin.getChests().entrySet()) + { + ThievingChest chest = entry.getValue(); + WorldPoint pos = entry.getKey(); + + + if (chest != null) + { + if (!plugin.isBatsFound() && !chest.isEverOpened()) + { + if (shouldDrawChest(pos)) + { + Color drawColor = new Color(config.getPotentialBatColor().getRed(), + config.getPotentialBatColor().getGreen(), + config.getPotentialBatColor().getBlue(), + getChestOpacity(pos)); + drawCircleOnTrap(graphics, chest, drawColor); + } + } + if (chest.isPoison()) + { + drawCircleOnTrap(graphics, chest, config.getPoisonTrapColor()); + } + } + } + } + + private boolean shouldDrawChest(WorldPoint chestPos) + { + if (plugin.numberOfEmptyChestsFound() == 0) + { + return true; + } + int chestId = plugin.getChestId(chestPos); + BatSolver solver = plugin.getSolver(); + if (solver != null && chestId != -1) + { + TreeSet matches = solver.matchSolutions(); + return matches.contains(chestId) || matches.size() == 0; + } + return true; + } + + /** + * Draws a timer on a given trap. + * + * @param graphics + * @param chest The chest on which the circle needs to be drawn + * @param fill The fill color of the timer + */ + private void drawCircleOnTrap(Graphics2D graphics, ThievingChest chest, Color fill) + { + if (chest.getLocalPoint().getPlane() != client.getPlane()) + { + return; + } + LocalPoint localLoc = LocalPoint.fromWorld(client, chest.getLocalPoint()); + if (localLoc == null) + { + return; + } + Point loc = Perspective.localToCanvas(client, localLoc, chest.getLocalPoint().getPlane()); + + ProgressPieComponent pie = new ProgressPieComponent(); + pie.setFill(fill); + pie.setBorderColor(Color.BLACK); + pie.setPosition(loc); + pie.setProgress(1); + if (graphics != null && loc != null) + { + pie.render(graphics); + } + } + + private int getChestOpacity(WorldPoint chestPos) + { + int chestId = plugin.getChestId(chestPos); + BatSolver solver = plugin.getSolver(); + if (solver != null && chestId != -1) + { + return (int) (255 * solver.relativeLikelihoodPoison(chestId)); + } + return 255; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java new file mode 100644 index 0000000000..0df80aeb65 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/InstancePoint.java @@ -0,0 +1,98 @@ +package net.runelite.client.plugins.raidsthieving; + +import lombok.Getter; +import net.runelite.api.Client; +import net.runelite.api.Point; +import net.runelite.api.coords.WorldPoint; + +import java.util.Objects; + +/** + * Represents a point in the instance chunk, invariant of rotation. + */ +@Getter +public class InstancePoint +{ + private static final int CHUNK_SIZE = 8; + private static final double CHUNK_OFFSET = 3.5; + + public InstancePoint(int x, int y, int rot) + { + this.x = x; + this.y = y; + this.rot = rot; + } + + public InstancePoint(int x, int y) + { + this.x = x; + this.y = y; + this.rot = 0; + } + + public static InstancePoint buildFromPoint(WorldPoint worldPoint, Client client) + { + Point point = new Point(worldPoint.getX(), worldPoint.getY()); + Point base = new Point(client.getBaseX(), client.getBaseY()); + int plane = worldPoint.getPlane(); + + int deltaX = point.getX() - base.getX(); + int deltaY = point.getY() - base.getY(); + int chunkIndexX = deltaX / CHUNK_SIZE; + int chunkIndexY = deltaY / CHUNK_SIZE; + + int chunkData = client.getInstanceTemplateChunks()[plane][chunkIndexX][chunkIndexY]; + int rotation = chunkData >> 1 & 0x3; + int y = (chunkData >> 3 & 0x7FF) * 8; + int x = (chunkData >> 14 & 0x3FF) * 8; + + return buildFromTile(base, point, rotation, new Point(x, y)); + } + + public static InstancePoint buildFromTile(Point base, Point tile, int rot, Point chunkOrigin) + { + int deltaX = tile.getX() - base.getX(); + int deltaY = tile.getY() - base.getY(); + + double chunkOffsetX = (deltaX % CHUNK_SIZE) - CHUNK_OFFSET; + double chunkOffsetY = (deltaY % CHUNK_SIZE) - CHUNK_OFFSET; + + for (int i = 0; i < rot; i++) + { + double temp = chunkOffsetX; + chunkOffsetX = -chunkOffsetY; + chunkOffsetY = temp; + } + + chunkOffsetX += CHUNK_OFFSET; + chunkOffsetY += CHUNK_OFFSET; + + int invariantChunkOffsetX = (int) chunkOffsetX; + int invariantChunkOffsetY = (int) chunkOffsetY; + + return new InstancePoint( + chunkOrigin.getX() + invariantChunkOffsetX, + chunkOrigin.getY() + invariantChunkOffsetY, + rot); + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InstancePoint that = (InstancePoint) o; + return x == that.x && + y == that.y; + } + + @Override + public int hashCode() + { + return Objects.hash(x, y); + } + + private int x; + private int y; + private int rot; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java new file mode 100644 index 0000000000..bb055edf4e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConfig.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017, Tim Lehner + * 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.raidsthieving; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; +import java.awt.Color; + +@ConfigGroup("raidsthievingplugin") +public interface RaidsThievingConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "hexColorPotentialBat", + name = "Potential Bat", + description = "Color of marker for chests which could have bat" + ) + default Color getPotentialBatColor() + { + return Color.YELLOW; + } + + @ConfigItem( + position = 2, + keyName = "hexColorPoison", + name = "Poison trap", + description = "Color of chest with poison" + ) + default Color getPoisonTrapColor() + { + return Color.GREEN; + } + + @ConfigItem( + position = 5, + keyName = "batNotify", + name = "Notify when found", + description = "Send notification if you see bats being found." + ) + default boolean batFoundNotify() + { + return false; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java new file mode 100644 index 0000000000..965934a01b --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingConstants.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017, Tim Lehner + * 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.raidsthieving; + +public class RaidsThievingConstants +{ + public static final int CLOSED_CHEST_ID = 29742; + public static final int OPEN_EMPTY_CHEST = 29743; + public static final int OPEN_FULL_CHEST_1 = 29744; + public static final int OPEN_FULL_CHEST_2 = 29745; + public static final int EMPTY_TROUGH = 29746; + public static final int[] STORAGE = {29769, 29770, 29771, 29772}; +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java new file mode 100644 index 0000000000..10873e02d8 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/RaidsThievingPlugin.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2017, Tim Lehner + * 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.raidsthieving; + +import com.google.inject.Provides; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameObject; +import net.runelite.api.GraphicsObject; +import net.runelite.api.Varbits; +import net.runelite.api.coords.WorldPoint; +import net.runelite.api.events.ConfigChanged; +import net.runelite.api.events.GameObjectSpawned; +import net.runelite.api.events.GraphicsObjectCreated; +import net.runelite.api.events.VarbitChanged; +import net.runelite.client.Notifier; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.plugins.raidsthieving.BatSolver.BatSolver; +import net.runelite.client.plugins.raidsthieving.BatSolver.ChestIdentifier; +import net.runelite.client.plugins.raidsthieving.BatSolver.ThievingRoomType; +import net.runelite.client.ui.overlay.OverlayManager; +import javax.inject.Inject; +import java.text.MessageFormat; +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@PluginDescriptor( + name = "Raids Bat Finder", + description = "Tracks which chests need to be searched for bats and which poison", + tags = {"overlay", "skilling", "raid"}, + type = "PVM" +) +public class RaidsThievingPlugin extends Plugin +{ + @Inject + private Client client; + + @Inject + private OverlayManager overlayManager; + + @Inject + private ChestOverlay overlay; + + @Inject + private Notifier notifier; + + @Inject + private RaidsThievingConfig config; + + @Getter + private final Map chests = new HashMap<>(); + + @Getter + private Instant lastActionTime = Instant.ofEpochMilli(0); + + private boolean inRaidChambers; + + @Getter + private boolean batsFound; + + @Getter + private BatSolver solver; + + @Getter + private ChestIdentifier mapper; + + + @Provides + RaidsThievingConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(RaidsThievingConfig.class); + } + + @Override + protected void startUp() + { + overlayManager.add(overlay); + overlay.updateConfig(); + reset(); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(overlay); + lastActionTime = Instant.ofEpochMilli(0); + chests.clear(); + } + + + @Subscribe + public void onGameObjectSpawned(GameObjectSpawned event) + { + GameObject obj = event.getGameObject(); + WorldPoint loc = obj.getWorldLocation(); + InstancePoint absLoc = InstancePoint.buildFromPoint(loc, client); + + if (obj.getId() == RaidsThievingConstants.EMPTY_TROUGH) + { + ThievingRoomType type = ThievingRoomType.IdentifyByInstancePoint(absLoc); + + if (type != null) + { + solver = new BatSolver(type); + mapper = new ChestIdentifier(type); + for (ThievingChest chest : chests.values()) + { + mapper.indentifyChest(chest); + } + } + else + { + log.error(MessageFormat.format("Unable to identify room type with: {0} {1} {2} {3} {4}.", + loc.getX(), loc.getY(), absLoc.getX(), absLoc.getY(), absLoc.getRot())); + log.error("Please report this @https://github.com/runelite/runelite/pull/4914!"); + } + } + if (obj.getId() == RaidsThievingConstants.CLOSED_CHEST_ID) + { + if (!chests.containsKey(loc)) + { + ThievingChest chest = new ThievingChest(obj, absLoc); + + if (mapper != null) + { + mapper.indentifyChest(chest); + } + + chests.put(loc, chest); + } + else + { + checkForBats(); + } + } + + if (obj.getId() == RaidsThievingConstants.OPEN_FULL_CHEST_1 || + obj.getId() == RaidsThievingConstants.OPEN_FULL_CHEST_2) + { + ThievingChest chest = chests.get(obj.getWorldLocation()); + // We found a chest that has grubs + log.info(MessageFormat.format("Found grubs at {0}, {1} chestId: {2}", loc.getX(), loc.getY(), chest.getChestId())); + if (solver != null && chest.getChestId() != -1) + { + chest.setEverOpened(true); + solver.addGrubsChest(chest.getChestId()); + } + checkForBats(); + } + + if (obj.getId() == RaidsThievingConstants.OPEN_EMPTY_CHEST) + { + ThievingChest chest = chests.get(obj.getWorldLocation()); + // We found a chest that could have poison + if (solver != null && chest.getChestId() != -1) + { + chest.setEmpty(true); + chest.setEverOpened(true); + solver.addEmptyChest(chest.getChestId()); + } + } + } + + + @Subscribe + public void onGraphicsObjectCreated(GraphicsObjectCreated event) + { + GraphicsObject obj = event.getGraphicsObject(); + if (obj.getId() == 184) + { + log.debug("Found poison splat"); + WorldPoint loc = WorldPoint.fromLocal(client, obj.getLocation()); + chests.get(loc).setPoison(true); + } + } + + @Subscribe + public void onVarbitChanged(VarbitChanged event) + { + boolean setting = client.getVar(Varbits.IN_RAID) == 1; + + if (inRaidChambers != setting) + { + inRaidChambers = setting; + reset(); + } + + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals("raidsthievingplugin")) + { + overlay.updateConfig(); + } + } + + private void reset() + { + chests.clear(); + batsFound = false; + solver = null; + mapper = null; + } + + public int numberOfEmptyChestsFound() + { + int total = 0; + for (ThievingChest chest : chests.values()) + { + if (chest.isEmpty()) + { + total++; + } + } + return total; + } + + + private boolean checkForBats() + { + for (ThievingChest chest : chests.values()) + { + if (chest.isEmpty() && !chest.isPoison()) + { + batsFound = true; + if (config.batFoundNotify()) + { + notifier.notify("Bats have been found!"); + } + return true; + } + } + return false; + } + + public int getChestId(WorldPoint worldPoint) + { + return chests.get(worldPoint).getChestId(); + } +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java new file mode 100644 index 0000000000..05a58d554e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raidsthieving/ThievingChest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2019, Tim Lehner + * 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.raidsthieving; + +import lombok.Getter; +import lombok.Setter; +import net.runelite.api.GameObject; +import net.runelite.api.coords.WorldPoint; + +/** + * Wrapper class for a GameObject that represents a chest in the thieving room of Chambers of Xeric. + */ +@Getter +public class ThievingChest +{ + /** + * If the chest has never been opened, it could have bats. + */ + @Setter + private boolean everOpened; + + /** + * If the chest is empty, it could have bats. + */ + @Setter + private boolean empty; + + /** + * If the chest contains a poison trap instead. + */ + @Setter + private boolean poison; + + + @Setter + private int chestId; + + private final WorldPoint localPoint; + private final InstancePoint instancePoint; + + /** + * Constructor for a ThievingChest object + * + * @param gameObject The gameobject thats corresponds with this trap. + */ + ThievingChest(GameObject gameObject, InstancePoint instancePoint) + { + this.everOpened = false; + this.poison = false; + this.empty = false; + localPoint = gameObject.getWorldLocation(); + this.instancePoint = instancePoint; + this.chestId = -1; + } + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java new file mode 100644 index 0000000000..20775b1d35 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, Infinitay + * Copyright (c) 2018, Shaun Dreclin + * + * 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.rememberclan; + +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("rememberclan") +public interface RememberClanConfig extends Config +{ + @ConfigItem( + position = 1, + keyName = "clanname", + name = "Clan Name", + description = "Clanname to always remember" + ) + default String clanname() + { + return ""; + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java new file mode 100644 index 0000000000..2b5dd54b35 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanPlugin.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, Infinitay + * Copyright (c) 2018, Shaun Dreclin + * 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.rememberclan; + +import com.google.inject.Provides; +import javax.inject.Inject; + +import net.runelite.api.*; +import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GameTick; +import net.runelite.api.vars.AccountType; +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.ConfigManager; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; + +@PluginDescriptor( + name = "Remember Clan", + description = "Remember a specific clan!", + type = "utility", + enabledByDefault = false +) +public class RememberClanPlugin extends Plugin +{ + + @Inject + private Client client; + + @Inject + private RememberClanConfig config; + + @Inject + private ChatMessageManager chatMessageManager; + + private boolean loggingIn; + + @Provides + RememberClanConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(RememberClanConfig.class); + } + + @Subscribe + public void onGameTick(GameTick event) + { + client.setVar(VarClientStr.RECENT_CLAN_CHAT,config.clanname()); + + } + + +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java new file mode 100644 index 0000000000..2146cd8708 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdAnswer.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019, FlaxOnEm + * 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.stronghold; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import net.runelite.api.widgets.Widget; + +import java.util.HashMap; +import java.util.Map; + +@Getter +@RequiredArgsConstructor +enum StrongholdAnswer { + PAIR_0("To pass you must answer me this: Hey adventurer!
You've been randomly selected for a prize of 1 year of
free membership! I'm just going to need some of your
account details so I can put it on your account!", "No way! I'm reporting you to Jagex!"), + PAIR_1("To pass you must answer me this: Can I leave my
account logged in while I'm out of the room?", "No."), + PAIR_2("To pass you must answer me this: How do I remove a
hijacker from my account?", "Use the Account Recovery System."), + PAIR_3("To pass you must answer me this: What do you do if
someone asks you for your password or bank PIN to
make you a player moderator?", "Don't give them the information and send an 'Abuse report'."), + PAIR_4("To pass you must answer me this: You're watching a
stream by someone claiming to be Jagex offering double
xp. What do you do?", "Report the stream as a scam. Real Jagex streams have a 'verified' mark."), + PAIR_5("To pass you must answer me this: My friend asks me
for my password so that he can do a difficult quest for
me. Do I give it to them?", "Don't give them my password."), + PAIR_6("To pass you must answer me this: Who can I give my
password to?", "Nobody."), + PAIR_7("To pass you must answer me this: How do I set up
two-factor authentication for my Old School RuneScape
account?", "Through account settings on oldschool.runescape.com."), + PAIR_8("To pass you must answer me this: What is an example
of a good bank PIN?", "The birthday of a famous person or event."), + PAIR_9("To pass you must answer me this: What should you do
if your real-life friend asks for your password so he
can check your stats?", "Don't give out your password to anyone. Not even close friends."), + PAIR_A("To pass you must answer me this: A player tells you to
search for a video online, click the link in the description
and comment on the forum post to win a cash prize.
What do you do?", "Report the player for phishing."), + PAIR_B("To pass you must answer me this: You have been
offered an opportunity to check out a free giveaway or
double XP signup via email or in game chat. What
should I do?", "Report the incident and do not click any links."), + PAIR_C("To pass you must answer me this: How do I set a
bank PIN?", "Talk to any banker."), + PAIR_D("To pass you must answer me this: What do I do if a
moderator asks me for my account details?", "Politely tell them no and then use the 'Report Abuse' button."), + PAIR_E("To pass you must answer me this: You are part way
through the Stronghold of Security when you have to
answer another question. After you answer the question,
you should...", "Read the text and follow the advice given."), + PAIR_F("To pass you must answer me this: Will Jagex prevent
me from saying my PIN in game?", "No."), + PAIR_G("that sound?", "No way! You'll just take my gold for your own! Reported!"), + PAIR_H("To pass you must answer me this: What should I do if
I receive an email asking me to verify my identity or
Account details due to suspicious activity?", "Don't click any links, forward the email to reportphishing@jagex.com."), + PAIR_I("To pass you must answer me this: A website claims that
they can make me a player moderator. What should I
do?", "Inform Jagex by emailing reportphishing@jagex.com."), + PAIR_J("react?", "Don't share your information and report the player."), + PAIR_K("To pass you must answer me this: What do you do if
someone asks you for your password or bank PIN to
make you a member for free?", "Don't tell them anything and click the 'Report Abuse' button."), + PAIR_L("To pass you must answer me this: Is it OK to buy an
Old School RuneScape account?", "No, you should never buy an account."), + PAIR_M("To pass you must answer me this: You have been
offered an opportunity to check out a free giveaway or
double XP signup via social media or stream. What
should I do?", "Report the incident and do not click any links."), + PAIR_N("To pass you must answer me this: Where is it safe to
use my Old School RuneScape password?", "Only on the Old School RuneScape website."), + PAIR_O("To pass you must answer me this: What is the best
way to secure your account?", "Authenticator and two-step login on my registered email."), + PAIR_P("To pass you must answer me this: Who is it ok to
share my account with?", "Nobody."), + PAIR_Q("To pass you must answer me this: What should you do
if another player messages you recommending a website
to purchase items and/or gold?", "Do not visit the website and report the player who messaged you."), + PAIR_R("To pass you must answer me this: Whose responsibility
is it to keep your account secure?", "Me."), + PAIR_S("To pass you must answer me this: Is it safe to pay
someone to level your account?", "No, you should never allow anyone to level your account."), + PAIR_T("To pass you must answer me this: What do I do if my
account is compromised?", "Secure my device and reset my password."), + PAIR_U("respond?", "Decline the offer and report that player."), + PAIR_V("To pass you must answer me this: A player says that
Jagex prevents you from saying your password
backwards in game. What do you do?", "Don't type in my password backwards and report the player."), + PAIR_W("To pass you must answer me this: What do I do if I
think I have a keylogger or virus?", "Virus scan my device then change my password."), + PAIR_X("To pass you must answer me this: What is the best
security step you can take to keep your registered
email secure?", "Set up 2 step authentication with my email provider."); + + static final Map MATCHES = new HashMap<>(); + + static { + for (StrongholdAnswer strongholdAnswer : StrongholdAnswer.values()) { + MATCHES.put(strongholdAnswer.question, strongholdAnswer.answer); + } + } + + private final String question; + private final String answer; + + static Widget findCorrect(final String question, final Widget[] widgets) { + final String s = MATCHES.get(question); + + for (Widget widget: widgets) { + if (widget != null && widget.getText().equals(s)) + return widget; + } + + return null; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java new file mode 100644 index 0000000000..cae099dc1e --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/stronghold/StrongholdPlugin.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2019, FlaxOnEm + * 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.stronghold; + +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.events.ClientTick; +import net.runelite.api.events.WidgetLoaded; +import net.runelite.api.widgets.Widget; +import net.runelite.api.widgets.WidgetID; +import net.runelite.api.widgets.WidgetInfo; +import net.runelite.client.eventbus.Subscribe; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.util.ColorUtil; + +import javax.inject.Inject; +import java.awt.Color; + +@PluginDescriptor( + name = "Stronghold", + description = "Highlights the correct answer to Stronghold of Security questions", + tags = {"stronghold", "security", "overlay", "answer", "highlight"}, + type = "utility" +) +@Slf4j +public class StrongholdPlugin extends Plugin { + private static final Color ANSWER_COLOR = new Color(230, 0, 230); + + @Inject + private Client client; + + private boolean queueNPCDialogue; + private boolean queueNPCOption; + private String questionCache; + + @Subscribe + public void onWidgetLoaded(WidgetLoaded widgetLoaded) { + switch (widgetLoaded.getGroupId()) { + case WidgetID.DIALOG_NPC_GROUP_ID: + queueNPCDialogue = true; + break; + case WidgetID.DIALOG_OPTION_GROUP_ID: + queueNPCOption = true; + break; + } + } + + @Subscribe + public void onClientTick(ClientTick t) { + if (queueNPCDialogue) { + queueNPCDialogue = false; + onNPCDialogue(); + } + if (queueNPCOption) { + queueNPCOption = false; + onNPCOption(); + } + } + + private void onNPCDialogue() { + final Widget debugWidget = client.getWidget(WidgetInfo.DIALOG_NPC_TEXT); + final String npcText = debugWidget.getText(); + if (StrongholdAnswer.MATCHES.containsKey(npcText)) + questionCache = npcText; + } + + private void onNPCOption() { + if (questionCache == null) + return; + + final Widget optionsWidget = client.getWidget(WidgetInfo.DIALOG_OPTION); + if (optionsWidget == null) + return; + + final Widget[] widgets = optionsWidget.getParent().getChildren(); + + final Widget answerWidget = StrongholdAnswer.findCorrect(questionCache, widgets); + questionCache = null; + if (answerWidget == null) + return; + + final String answerText = answerWidget.getText(); + answerWidget.setText(ColorUtil.wrapWithColorTag(answerText, ANSWER_COLOR)); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java new file mode 100644 index 0000000000..c665baaa70 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorConfig.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +import java.awt.Color; +import net.runelite.client.config.Config; +import net.runelite.client.config.ConfigGroup; +import net.runelite.client.config.ConfigItem; + +@ConfigGroup("warIndicators") + +public interface WarIndicatorConfig extends Config +{ + @ConfigItem( + position = 0, + keyName = "highLightCallers", + name = "Highlight Callers", + description = "Highlight listed caller(s)" + ) + default boolean highLightCallers() + { + return true; + } + + @ConfigItem( + position = 1, + keyName = "callerColor", + name = "Caller(s) Color", + description = "Color to highlight caller's name" + ) + default Color getCallerColor() + { + return new Color(36, 255, 237); + } + + @ConfigItem( + position = 2, + keyName = "callerMinimap", + name = "Callers on Minimap", + description = "Show your caller(s) on the minimap" + ) + default boolean callerMinimap() + { + return false; + } + + + @ConfigItem( + position = 3, + keyName = "callerTile", + name = "Show Caller's Tile", + description = "Show the tile your target is standing on" + ) + default boolean callerTile() + { + return false; + } + + @ConfigItem( + position = 4, + keyName = "activeCallers", + name = "Callers", + description = "Adds a user to your caller list. Format: (caller), (caller)" + ) + default String getActiveCallers() + { + return ""; + } + + @ConfigItem( + position = 5, + keyName = "activeCallers", + name = "", + description = "" + ) + void setActiveCallers(String key); + + + @ConfigItem( + position = 6, + keyName = "highlightSnipes", + name = "Highlight Targets", + description = "Highlight listed target(s)" + ) + default boolean highlightSnipes() + { + return true; + } + + @ConfigItem( + position = 7, + keyName = "snipeColor", + name = "Target(s) Color", + description = "Color to highlight target name" + ) + default Color getSnipeColor() + { + return new Color(255, 0, 0); + } + + @ConfigItem( + position = 8, + keyName = "snipeMinimap", + name = "Targets on Minimap", + description = "Show your target on the minimap" + ) + default boolean snipeMinimap() + { + return false; + } + + @ConfigItem( + position = 9, + keyName = "snipeTile", + name = "Show Target's Tile", + description = "Show the tile your target is standing on" + ) + default boolean snipeTile() + { + return false; + } + + @ConfigItem( + position = 10, + keyName = "targetedSnipes", + name = "Targets", + description = "Adds a user to your snipe list. Format: (target), (target)" + ) + default String getTargetedSnipes() + { + return ""; + } + + @ConfigItem( + position = 11, + keyName = "targetedSnipes", + name = "", + description = "" + ) + + void setTargetedSnipe(String key); +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java new file mode 100644 index 0000000000..d7fa0cc92a --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorMiniMapOverlay.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import javax.inject.Inject; +import javax.inject.Singleton; +import net.runelite.api.Player; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.OverlayUtil; +import org.apache.commons.lang3.ArrayUtils; + +@Singleton +public class WarIndicatorMiniMapOverlay extends Overlay +{ + private final WarIndicatorService warIndicatorService; + private final WarIndicatorConfig config; + + @Inject + private WarIndicatorMiniMapOverlay(WarIndicatorConfig config, WarIndicatorService warIndicatorService) + { + this.config = config; + this.warIndicatorService = warIndicatorService; + setLayer(OverlayLayer.ABOVE_WIDGETS); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + warIndicatorService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); + return null; + } + + private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) + { + final String name = actor.getName().replace('\u00A0', ' '); + final net.runelite.api.Point minimapLocation = actor.getMinimapLocation(); + + String[] callers = config.getActiveCallers().split(", "); + String[] targets = config.getTargetedSnipes().split(", "); + + if (config.callerMinimap() && ArrayUtils.contains(callers, actor.getName())) + { + if (minimapLocation != null) + { + OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); + } + } + + if (config.snipeMinimap() && ArrayUtils.contains(targets, actor.getName())) + { + if (minimapLocation != null) + { + OverlayUtil.renderTextLocation(graphics, minimapLocation, name, color); + } + } + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java new file mode 100644 index 0000000000..7ca7cc20c0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorOverlay.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Polygon; +import javax.inject.Inject; +import javax.inject.Singleton; +import org.apache.commons.lang3.ArrayUtils; +import net.runelite.api.Player; +import net.runelite.api.Point; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayLayer; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.OverlayPriority; +import net.runelite.client.ui.overlay.OverlayUtil; + +@Singleton +public class WarIndicatorOverlay extends Overlay +{ + private final WarIndicatorService warIndicatorService; + private final WarIndicatorConfig config; + + @Inject + private WarIndicatorOverlay(WarIndicatorConfig config, WarIndicatorService warIndicatorService) + { + this.config = config; + this.warIndicatorService = warIndicatorService; + setLayer(OverlayLayer.ABOVE_SCENE); + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + } + + @Override + public Dimension render(Graphics2D graphics) + { + warIndicatorService.forEachPlayer((player, color) -> renderPlayerOverlay(graphics, player, color)); + return null; + } + + private void renderPlayerOverlay(Graphics2D graphics, Player actor, Color color) + { + if (!config.highlightSnipes() && !config.highLightCallers()) + { + return; + } + + Polygon poly = actor.getCanvasTilePoly(); + String[] callers = config.getActiveCallers().split(", "); + String[] targets = config.getTargetedSnipes().split(", "); + + if (config.callerTile() && ArrayUtils.contains(callers, actor.getName())) + { + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, color); + } + } + + if (config.snipeTile() && ArrayUtils.contains(targets, actor.getName())) + { + if (poly != null) + { + OverlayUtil.renderPolygon(graphics, poly, color); + } + } + + String name = actor.getName().replace('\u00A0', ' '); + int offset = actor.getLogicalHeight() + 40; + Point textLocation = actor.getCanvasTextLocation(graphics, name, offset); + + if (textLocation != null) + { + OverlayUtil.renderTextLocation(graphics, textLocation, name, color); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java new file mode 100644 index 0000000000..9dc378547c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorPlugin.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +import com.google.common.collect.Sets; +import com.google.common.eventbus.Subscribe; +import com.google.inject.Provides; +import java.awt.Color; +import java.util.Collection; +import javax.inject.Inject; +import org.apache.commons.lang3.ArrayUtils; +import net.runelite.api.Client; +import static net.runelite.api.MenuAction.FOLLOW; +import static net.runelite.api.MenuAction.ITEM_USE_ON_PLAYER; +import static net.runelite.api.MenuAction.PLAYER_EIGTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_FIFTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_FIRST_OPTION; +import static net.runelite.api.MenuAction.PLAYER_FOURTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_SECOND_OPTION; +import static net.runelite.api.MenuAction.PLAYER_SEVENTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_SIXTH_OPTION; +import static net.runelite.api.MenuAction.PLAYER_THIRD_OPTION; +import static net.runelite.api.MenuAction.SPELL_CAST_ON_PLAYER; +import static net.runelite.api.MenuAction.TRADE; +import net.runelite.api.MenuEntry; +import net.runelite.api.Player; +import net.runelite.api.events.MenuEntryAdded; +import net.runelite.client.config.ConfigManager; +import net.runelite.client.plugins.Plugin; +import net.runelite.client.plugins.PluginDescriptor; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayManager; + +@PluginDescriptor( + name = "War calling indicators", + description = "War War War.", + tags = {"skill", "total", "max", "PVP"}, + type = "PVP", + enabledByDefault = false +) +public class WarIndicatorPlugin extends Plugin +{ + @Inject + private OverlayManager overlayManager; + + @Inject + private WarIndicatorConfig config; + + @Inject + private WarIndicatorOverlay warIndicatorOverlay; + + @Inject + private WarIndicatorMiniMapOverlay warIndicatorMiniMapOverlay; + + @Inject + private Client client; + + @Provides + WarIndicatorConfig provideConfig(ConfigManager configManager) + { + return configManager.getConfig(WarIndicatorConfig.class); + } + + @Override + protected void startUp() throws Exception + { + overlayManager.add(warIndicatorOverlay); + overlayManager.add(warIndicatorMiniMapOverlay); + } + + @Override + protected void shutDown() throws Exception + { + overlayManager.remove(warIndicatorOverlay); + overlayManager.remove(warIndicatorMiniMapOverlay); + } + + @Subscribe + public void onMenuEntryAdd(MenuEntryAdded menuEntryAdded) + { + int type = menuEntryAdded.getType(); + + if (type >= 2000) + { + type -= 2000; + } + + int identifier = menuEntryAdded.getIdentifier(); + if (type == FOLLOW.getId() || type == TRADE.getId() + || type == SPELL_CAST_ON_PLAYER.getId() + || type == ITEM_USE_ON_PLAYER.getId() + || type == PLAYER_FIRST_OPTION.getId() + || type == PLAYER_SECOND_OPTION.getId() + || type == PLAYER_THIRD_OPTION.getId() + || type == PLAYER_FOURTH_OPTION.getId() + || type == PLAYER_FIFTH_OPTION.getId() + || type == PLAYER_SIXTH_OPTION.getId() + || type == PLAYER_SEVENTH_OPTION.getId() + || type == PLAYER_EIGTH_OPTION.getId()) + { + Player[] players = client.getCachedPlayers(); + Player player = null; + String player2 = null; + + String[] callers = config.getActiveCallers().split(", "); + String[] targets = config.getTargetedSnipes().split(", "); + + if (identifier >= 0 && identifier < players.length) + { + player = players[identifier]; + player2 = players[identifier].getName(); + } + + if (player == null) + { + return; + } + + Color color = null; + + if (config.highLightCallers() && ArrayUtils.contains(callers, player2)) + { + color = config.getCallerColor(); + } + + if (config.highlightSnipes() && ArrayUtils.contains(targets, player2)) + { + color = config.getSnipeColor(); + } + + if (color != null) + { + MenuEntry[] menuEntries = client.getMenuEntries(); + MenuEntry lastEntry = menuEntries[menuEntries.length - 1]; + String target = lastEntry.getTarget(); + + int idx = target.indexOf('>'); + if (idx != -1) + { + target = target.substring(idx + 1); + } + + lastEntry.setTarget("" + target); + client.setMenuEntries(menuEntries); + } + + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java new file mode 100644 index 0000000000..cb6c8127b5 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/warindicators/WarIndicatorService.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018, Andrew EP | ElPinche256 + * 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.warindicators; + +import net.runelite.api.Client; +import net.runelite.api.Player; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.awt.*; +import java.util.function.BiConsumer; + +@Singleton +public class WarIndicatorService +{ + private final Client client; + private final WarIndicatorConfig config; + + @Inject + private WarIndicatorService(Client client, WarIndicatorConfig config) + { + this.config = config; + this.client = client; + } + + public void forEachPlayer(final BiConsumer consumer) + { + if (!config.highlightSnipes() && !config.highLightCallers()) + { + return; + } + + if (config.highlightSnipes()) + { + for (Player player : client.getPlayers()) + { + if (player == null || player.getName() == null) + { + continue; + } + + String[] targets = config.getTargetedSnipes().split(", "); + + if (targets == null) + { + return; + } + + for (int i = 0; i < targets.length; i++) + { + if (player.getName().equalsIgnoreCase(targets[i])) + { + consumer.accept(player, config.getSnipeColor()); + } + } + } + } + + if (config.highLightCallers()) + { + for (Player player : client.getPlayers()) + { + if (player == null || player.getName() == null) + { + continue; + } + + String[] callers = config.getActiveCallers().split(", "); + + if (callers == null) + { + return; + } + + for (int i = 0; i < callers.length; i++) + { + if (player.getName().equalsIgnoreCase(callers[i])) + { + consumer.accept(player, config.getCallerColor()); + } + } + } + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java new file mode 100644 index 0000000000..fec801ab51 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/BloatTimerOverlay.java @@ -0,0 +1,83 @@ +package net.runelite.client.plugins.ztob; + +import net.runelite.api.Client; +import net.runelite.api.Perspective; +import net.runelite.api.Point; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.*; + +import javax.inject.Inject; +import java.awt.*; + +public class BloatTimerOverlay extends Overlay { + + private final Client client; + private final TheatrePlugin plugin; + private final TheatreConfig config; + + @Inject + private BloatTimerOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) { + this.client = client; + this.plugin = plugin; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + public Dimension render(Graphics2D graphics) { + + if (config.bloatTimer()) { + final String tickCounter = String.valueOf(plugin.bloatTimer); + int secondConversion = (int) (plugin.bloatTimer * .6); + if (plugin.getBloat_NPC() != null) { + Point canvasPoint = plugin.getBloat_NPC().getCanvasTextLocation(graphics, tickCounter, 60); + if (plugin.bloatTimer <= 37) { + renderTextLocation(graphics, tickCounter + "( " + secondConversion + " )", 15, Font.BOLD, Color.WHITE, canvasPoint); + } else { + renderTextLocation(graphics, tickCounter + "( " + secondConversion + " )", 15, Font.BOLD, Color.RED, canvasPoint); + } + } + } + + + return null; + } + + private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha) { + WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation(); + if (point.distanceTo(playerLocation) >= 32) { + return; + } + LocalPoint lp = LocalPoint.fromWorld(client, point); + if (lp == null) { + return; + } + + Polygon poly = Perspective.getCanvasTilePoly(client, lp); + if (poly == null) { + return; + } + //OverlayUtil.renderPolygon(graphics, poly, color); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); + graphics.setStroke(new BasicStroke(strokeWidth)); + graphics.draw(poly); + graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha)); + graphics.fill(poly); + } + + private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, net.runelite.api.Point canvasPoint) { + graphics.setFont(new Font("Arial", fontStyle, fontSize)); + if (canvasPoint != null) { + final net.runelite.api.Point canvasCenterPoint = new net.runelite.api.Point( + canvasPoint.getX(), + canvasPoint.getY()); + final net.runelite.api.Point canvasCenterPoint_shadow = new Point( + canvasPoint.getX() + 1, + canvasPoint.getY() + 1); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); + } + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java index 6f63951785..0a0a33d982 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreConfig.java @@ -14,15 +14,16 @@ import net.runelite.client.config.ConfigItem; @ConfigGroup("Theatre") -public interface TheatreConfig extends Config -{ +public interface TheatreConfig extends Config { @ConfigItem( position = 0, keyName = "MaidenBlood", name = "Maiden blood attack", description = "" ) - default boolean MaidenBlood(){ return false; } + default boolean MaidenBlood() { + return true; + } @ConfigItem( position = 1, @@ -30,109 +31,181 @@ public interface TheatreConfig extends Config name = "Maiden blood spawns", description = "" ) - default boolean MaidenSpawns(){ return false; } + default boolean MaidenSpawns() { + return true; + } @ConfigItem( position = 2, keyName = "BloatIndicator", - name = "Bloat indicator", + name = "Bloat Indicator", description = "" ) - default boolean BloatIndicator(){ return false; } + default boolean BloatIndicator() { + return true; + } @ConfigItem( position = 3, - keyName = "BloatHands", - name = "Bloat Falling Hands", + keyName = "bloat Timer", + name = "Bloat Timer", description = "" ) - default boolean BloatHands(){ return false; } + default boolean bloatTimer() { + return true; + } @ConfigItem( position = 4, + keyName = "bloatFeet", + name = "Bloat Feet", + description = "" + ) + default boolean bloatFeetIndicator() { + return true; + } + + @ConfigItem( + position = 5, keyName = "NyloPillars", name = "Nylocas pillar health", description = "" ) - default boolean NyloPillars(){ return false; } + default boolean NyloPillars() { + return true; + } + @ConfigItem( - position = 5, + position = 6, keyName = "NyloBlasts", name = "Nylocas explosions", description = "" ) - default boolean NyloBlasts(){ return false; } + default boolean NyloBlasts() { + return true; + } @ConfigItem( - position = 6, + position = 7, + keyName = "NyloMenu", + name = "Hide Attack options for Nylocas", + description = "" + ) + + default boolean NyloMenu() { + return true; + } + + @ConfigItem( + position = 8, keyName = "SotetsegMaze1", name = "Sotetseg maze", description = "" ) - default boolean SotetsegMaze1(){ return false; } + default boolean SotetsegMaze1() { + return true; + } @ConfigItem( - position = 7, + position = 9, keyName = "SotetsegMaze2", name = "Sotetseg maze (solo mode)", description = "" ) - default boolean SotetsegMaze2(){ return false; } - - @ConfigItem( - position = 8, - keyName = "SotetsegTick", - name = "Sotetseg tick eat", - description = "" - ) - default boolean SotetsegTick(){ return false; } - - @ConfigItem( - position = 9, - keyName = "XarpusExhumed", - name = "Xarpus exhumed", - description = "" - ) - default boolean XarpusExhumed(){ return false; } + default boolean SotetsegMaze2() { + return true; + } @ConfigItem( position = 10, - keyName = "XarpusTick", - name = "Xarpus tick", + keyName = "XarpusExhumed", + name = "Xarpus Exhumed", description = "" ) - default boolean XarpusTick(){ return false; } + default boolean XarpusExhumed() { + return true; + } @ConfigItem( position = 11, - keyName = "VerzikCupcakes", - name = "Verzik cupcakes", - description = " " + keyName = "XarpusTick", + name = "Xarpus Tick", + description = "" ) - default boolean VerzikCupcakes(){ return false; } + default boolean XarpusTick() { + return false; + } @ConfigItem( position = 12, - keyName = "VerzikTick", - name = "Verzik p3 tick", + keyName = "xarpusExhumes", + name = "Xarpus Exhume Counter", description = "" ) - default boolean VerzikTick(){ return false; } + default boolean XarpusExhumeOverlay() { + return false; + } @ConfigItem( position = 13, - keyName = "VerzikMelee", - name = "Verzik p3 melee range", + keyName = "VerzikCupcakes", + name = "Verzik Projectile Markers", description = "" ) - default boolean VerzikMelee(){ return false; } + default boolean VerzikCupcakes() { + return false; + } @ConfigItem( position = 14, - keyName = "VerzikYellow", - name = "Verzik yellow timing", + keyName = "VerzikTick", + name = "Verzik P3 Tick", description = "" ) - default boolean VerzikYellow(){ return false; } -} + default boolean VerzikTick() { + return false; + } + + @ConfigItem( + position = 15, + keyName = "VerzikMelee", + name = "Verzik P3 Melee Range", + description = "" + ) + default boolean VerzikMelee() { + return false; + } + + @ConfigItem( + position = 16, + keyName = "VerzikYellow", + name = "Verzik Yellow Timing", + description = "" + ) + default boolean VerzikYellow() { + return false; + } + + @ConfigItem( + position = 17, + keyName = "Verzik Nylo", + name = "Verzik Nylo Overlay", + description = "" + ) + default boolean NyloTargetOverlay() { + return false; + } + + @ConfigItem( + position = 18, + keyName = "VerzikTankTile", + name = "Verzik P3 Tile Overlay", + description = "" + ) + default boolean verzikTankTile() { + return true; + } + + +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java index 07f8e2f7b4..8e650295a7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreOverlay.java @@ -8,27 +8,21 @@ package net.runelite.client.plugins.ztob; +import net.runelite.api.Point; +import net.runelite.api.*; +import net.runelite.api.coords.LocalPoint; +import net.runelite.api.coords.WorldArea; +import net.runelite.api.coords.WorldPoint; +import net.runelite.client.ui.overlay.*; + +import javax.inject.Inject; import java.awt.*; import java.util.Iterator; import java.util.List; import java.util.Map; -import javax.inject.Inject; - -import net.runelite.api.*; -import net.runelite.api.Point; -import net.runelite.api.coords.LocalPoint; -import net.runelite.api.coords.WorldArea; -import net.runelite.api.coords.WorldPoint; -import net.runelite.client.ui.overlay.Overlay; -import net.runelite.client.ui.overlay.OverlayLayer; -import net.runelite.client.ui.overlay.OverlayPosition; -import net.runelite.client.ui.overlay.OverlayPriority; -import net.runelite.client.ui.overlay.OverlayUtil; public class TheatreOverlay extends Overlay { private final Client client; - - private final TheatrePlugin plugin; private final TheatreConfig config; @@ -43,69 +37,71 @@ public class TheatreOverlay extends Overlay { } @Override - public Dimension render(Graphics2D graphics) - { - if (plugin.isRunMaiden()) - { - if (config.MaidenBlood()) - { - for (WorldPoint point : plugin.getMaiden_BloodSpatters()) - { - drawTile(graphics, point, new Color(0,150,200), 2, 150, 10); + public Dimension render(Graphics2D graphics) { + if (plugin.isRunMaiden()) { + if (config.MaidenBlood()) { + for (WorldPoint point : plugin.getMaiden_BloodSpatters()) { + drawTile(graphics, point, new Color(36, 248, 229), 2, 150, 10); } } - if (config.MaidenSpawns()) - { - for (WorldPoint point : plugin.getMaiden_SpawnLocations()) - { - drawTile(graphics, point, new Color(0,150,200), 2, 180, 20); + if (config.MaidenSpawns()) { + for (WorldPoint point : plugin.getMaiden_SpawnLocations()) { + drawTile(graphics, point, new Color(36, 248, 229), 2, 180, 20); } - for (WorldPoint point : plugin.getMaiden_SpawnLocations2()) - { - drawTile(graphics, point, new Color(0,150,200), 1,120, 10); + for (WorldPoint point : plugin.getMaiden_SpawnLocations2()) { + drawTile(graphics, point, new Color(36, 248, 229), 1, 120, 10); } } } - if (plugin.isRunBloat()) - { + if (plugin.isRunBloat() && config.BloatIndicator()) { + if (config.bloatFeetIndicator()) { + if (plugin.getTemp().size() > 0) { + if (plugin.isTempFlag()) { + for (WorldPoint point : plugin.getTemp()) { - if (config.BloatHands()) - { - for (WorldPoint p : plugin.getBloat_Hands()) - { - drawTile(graphics, p, Color.BLACK,3,255,0); + drawTile(graphics, point, Color.black, 4, 255, 0); + + } + + } + } else if (plugin.getTemp2().size() > 0) { + if (plugin.isTemp2Flag()) { + for (WorldPoint point : plugin.getTemp2()) { + + drawTile(graphics, point, Color.black, 4, 255, 0); + + + } + + } } } - if(config.BloatIndicator()) { - NPC bloat = plugin.getBloat_NPC(); - int state = plugin.getBloat_State(); - if (bloat == null) { - return null; - } - switch (state) { - case 2: - renderNpcOverlay(graphics, bloat, Color.GREEN, 3, 150, 0); - break; - case 3: - renderNpcOverlay(graphics, bloat, Color.YELLOW, 3, 150, 0); - break; - default: - renderNpcOverlay(graphics, bloat, new Color(223, 109, 255), 3, 150, 0); - break; - } + NPC bloat = plugin.getBloat_NPC(); + int state = plugin.getBloat_State(); + if (bloat == null) { + return null; + } + switch (state) { + case 2: + renderNpcOverlay(graphics, bloat, Color.GREEN, 3, 150, 0); + break; + case 3: + renderNpcOverlay(graphics, bloat, Color.YELLOW, 3, 150, 0); + break; + default: + renderNpcOverlay(graphics, bloat, new Color(223, 109, 255), 3, 150, 0); + break; } } - if (plugin.isRunNylocas()) - { - if (config.NyloPillars()) - { + if (plugin.isRunNylocas()) { + if (config.NyloPillars()) { Map pillars = plugin.getNylocas_Pillars(); for (NPC npc : pillars.keySet()) { final int health = pillars.get(npc); - final String healthStr = String.valueOf(health) + "%"; + final String healthStr = health + "%"; WorldPoint p = npc.getWorldLocation(); LocalPoint lp = LocalPoint.fromWorld(client, p.getX() + 1, p.getY() + 1); final double rMod = 130.0 * health / 100.0; @@ -118,41 +114,34 @@ public class TheatreOverlay extends Overlay { } } - if (config.NyloBlasts()) - { + if (config.NyloBlasts()) { final Map npcMap = plugin.getNylocas_Map(); - for (NPC npc : npcMap.keySet()) - { + for (NPC npc : npcMap.keySet()) { int ticksLeft = npcMap.get(npc); if (ticksLeft > -1) { if (ticksLeft <= 6) { - Color color = new Color(255, 255,0 ,180); + Color color = new Color(255, 255, 0, 180); int outlineWidth = 2; int outlineAlpha = 150; - renderNpcOverlay(graphics, npc, color, outlineWidth, outlineAlpha, 0); + renderNpcOverlay(graphics, npc, color, outlineWidth, outlineAlpha, 15); } } } } } - if (plugin.isRunSotetseg()) - { - if (config.SotetsegMaze1()) - { + if (plugin.isRunSotetseg()) { + if (config.SotetsegMaze1()) { int i = 1; - for (GroundObject z : plugin.getRedTiles().keySet()) - { - Polygon poly = z.getCanvasTilePoly(); - if (poly != null) - { + for (GroundObject o : plugin.getRedTiles().keySet()) { + Polygon poly = o.getCanvasTilePoly(); + if (poly != null) { graphics.setColor(Color.WHITE); graphics.setStroke(new BasicStroke(2)); graphics.draw(poly); } - Point textLocation = z.getCanvasTextLocation(graphics, String.valueOf(i), 0); - if (textLocation != null) - { + Point textLocation = o.getCanvasTextLocation(graphics, String.valueOf(i), 0); + if (textLocation != null) { OverlayUtil.renderTextLocation(graphics, textLocation, String.valueOf(i), Color.WHITE); } @@ -160,111 +149,111 @@ public class TheatreOverlay extends Overlay { } } - if (config.SotetsegMaze2()) - { - for (WorldPoint p : plugin.getRedTilesOverworld()) - { + if (config.SotetsegMaze2()) { + for (WorldPoint p : plugin.getRedTilesOverworld()) { drawTile(graphics, p, Color.WHITE, 2, 255, 10); } } - if (config.SotetsegTick()) { - NPC boss = plugin.getSotetseg_NPC(); - int eattick = plugin.getTickTillEat(); - if (eattick > -1) - { - final String eatTicksStr = String.valueOf(eattick); - Point canvasPoint = boss.getCanvasTextLocation(graphics, eatTicksStr, 130); - renderTextLocation(graphics, eatTicksStr, 12, Font.BOLD, Color.WHITE, canvasPoint); - - } - } } - - if (plugin.isRunXarpus()) - { + if (plugin.isRunXarpus()) { NPC boss = plugin.getXarpus_NPC(); - if (boss.getId() == NpcID.XARPUS_8340 && !plugin.isXarpus_Stare() && config.XarpusTick()) - { + if (boss.getId() == NpcID.XARPUS_8340 && !plugin.isXarpus_Stare() && config.XarpusTick()) { int tick = plugin.getXarpus_TicksUntilShoot(); - if (tick < 1) - { + if (tick < 1) { tick = tick % 4 + 4; } final String ticksLeftStr = String.valueOf(tick); Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 130); renderTextLocation(graphics, ticksLeftStr, 12, Font.BOLD, Color.WHITE, canvasPoint); } - if (boss.getId() == NpcID.XARPUS_8339 && config.XarpusExhumed()) - { - for (GroundObject o : plugin.getXarpus_Exhumeds().keySet()) - { + if (boss.getId() == NpcID.XARPUS_8339 && config.XarpusExhumed()) { + for (GroundObject o : plugin.getXarpus_Exhumeds().keySet()) { + + Polygon poly = o.getCanvasTilePoly(); - if (poly != null) - { + if (poly != null) { graphics.setColor(new Color(0, 255, 0, 130)); graphics.setStroke(new BasicStroke(1)); graphics.draw(poly); } } + for (Map.Entry exhumes : plugin.getXarpusExhumedsTimer().entrySet()) { + final String ticksremaining = String.valueOf(exhumes.getValue()); + if (Integer.valueOf(ticksremaining) > 0) { + GroundObject ex = exhumes.getKey(); + Point point = ex.getCanvasTextLocation(graphics, ticksremaining, 0); + renderTextLocation(graphics, ticksremaining, 12, Font.BOLD, Color.white, point); + } + + } + + } + } - if (plugin.isRunVerzik()) - { - if (config.VerzikCupcakes()) - { - for (WorldPoint p : plugin.getVerzik_RangeProjectiles().values()) - { + + if (plugin.isRunVerzik()) { + + + if (config.VerzikCupcakes()) { + for (WorldPoint p : plugin.getVerzik_RangeProjectiles().values()) { drawTile(graphics, p, Color.RED, 2, 180, 50); } } - if (config.VerzikYellow()) - { - for (WorldPoint p : plugin.getVerzik_YellowTiles()) - { - drawTile(graphics, p, Color.YELLOW,3,255,0); - + if (config.VerzikYellow()) { + for (WorldPoint p : plugin.getVerzik_YellowTiles()) { + drawTile(graphics, p, Color.YELLOW, 3, 255, 0); Projectile yellowBall = plugin.getVerzik_YellowBall(); - if (yellowBall != null) - { - final int ticksToImpact = yellowBall.getRemainingCycles()/30; + if (yellowBall != null) { + final int ticksToImpact = yellowBall.getRemainingCycles() / 30; final String countdownStr = String.valueOf(ticksToImpact); Point canvasPoint = Perspective.getCanvasTextLocation(client, graphics, LocalPoint.fromWorld(client, p), countdownStr, 0); renderTextLocation(graphics, countdownStr, 12, Font.BOLD, Color.WHITE, canvasPoint); + } } } - if (plugin.getVerzik_NPC_P3() != null) { - final NPC boss = plugin.getVerzik_NPC_P3(); - if (boss.getId() == NpcID.VERZIK_VITUR_8374) - { - if (config.VerzikTick()) - { - final int ticksLeft = plugin.getP3_TicksUntilAttack(); - if (ticksLeft > 0 && ticksLeft < 8) - { - final String ticksLeftStr = String.valueOf(ticksLeft); - Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); - renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); - } + + final NPC boss = plugin.getVerzik_NPC(); + if (boss.getId() == NpcID.VERZIK_VITUR_8374) { + if (config.verzikTankTile()) { + renderNpcOverlay(graphics, boss, new Color(75, 0, 130), 1, 255, 0); + } + + if (config.VerzikTick()) { + final int ticksLeft = plugin.getP3_TicksUntilAttack(); + if (ticksLeft > 0 && ticksLeft < 8) { + final String ticksLeftStr = String.valueOf(ticksLeft); + Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); + renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); } + } - if (config.VerzikMelee() && boss.getAnimation() != 8127) - { - List meleeRange = getHitSquares(boss.getWorldLocation(), 7, 1, false); + if (config.VerzikMelee()) { + List meleeRange = getHitSquares(boss.getWorldLocation(), 7, 1, false); - for (WorldPoint p : meleeRange) - { - drawTile(graphics, p, Color.WHITE, 1,155, 10); - } + for (WorldPoint p : meleeRange) { + drawTile(graphics, p, Color.WHITE, 1, 155, 10); } } } + + if (boss.getAnimation() == 8117) { + final int ticksLeft = plugin.getRedCrabsTimer(); + if (ticksLeft > 0) { + final String ticksLeftStr = String.valueOf(ticksLeft); + Point canvasPoint = boss.getCanvasTextLocation(graphics, ticksLeftStr, 60); + renderTextLocation(graphics, ticksLeftStr, 15, Font.BOLD, Color.WHITE, canvasPoint); + } + } + } + return null; } @@ -290,19 +279,16 @@ public class TheatreOverlay extends Overlay { graphics.fill(poly); } - private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha) - { + private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha) { int size = 1; NPCComposition composition = actor.getTransformedComposition(); - if (composition != null) - { + if (composition != null) { size = composition.getSize(); } LocalPoint lp = actor.getLocalLocation(); Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size); - if (tilePoly != null) - { + if (tilePoly != null) { graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha)); graphics.setStroke(new BasicStroke(outlineWidth)); graphics.draw(tilePoly); @@ -311,37 +297,31 @@ public class TheatreOverlay extends Overlay { } } - private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) - { + private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) { graphics.setFont(new Font("Arial", fontStyle, fontSize)); - if (canvasPoint != null) - { + if (canvasPoint != null) { final Point canvasCenterPoint = new Point( canvasPoint.getX(), canvasPoint.getY()); final Point canvasCenterPoint_shadow = new Point( canvasPoint.getX() + 1, - canvasPoint.getY() + 1) ; + canvasPoint.getY() + 1); OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); } } - private List getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder) - { + private List getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder) { List little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList(); - List big = new WorldArea(npcLoc.getX()-thickness, npcLoc.getY()-thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList(); - if (!includeUnder) - { - for (Iterator it = big.iterator(); it.hasNext();) - { + List big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList(); + if (!includeUnder) { + for (Iterator it = big.iterator(); it.hasNext(); ) { WorldPoint p = it.next(); - if (little.contains(p)) - { + if (little.contains(p)) { it.remove(); } } } return big; } -} +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java index ee7cee5f4a..3eb223c0c6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatrePlugin.java @@ -8,29 +8,30 @@ package net.runelite.client.plugins.ztob; -import java.util.*; -import java.util.Iterator; -import javax.inject.Inject; - -import net.runelite.client.chat.ChatMessageManager; -import net.runelite.client.eventbus.Subscribe; import com.google.inject.Provides; import lombok.AccessLevel; import lombok.Getter; import net.runelite.api.*; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.*; +import net.runelite.api.kit.KitType; +import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.config.ConfigManager; +import net.runelite.client.eventbus.Subscribe; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.Text; + +import javax.inject.Inject; +import java.util.*; @PluginDescriptor( - name = "Theatre of Blood", + name = "Theater of Blood", description = "All-in-one plugin for Theatre of Blood", tags = {"ToB"}, - type = "PVM", - enabledByDefault = false + enabledByDefault = false, + type = "PVM" ) public class TheatrePlugin extends Plugin { @@ -41,11 +42,6 @@ public class TheatrePlugin extends Plugin { private static final int GROUNDOBJECT_ID_EXHUMED = 32743; private static final int ANIMATION_ID_XARPUS = 8059; private static final int GRAPHICSOBJECT_ID_YELLOW = 1595; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND1 = 1570; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND2 = 1571; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND3 = 1572; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND4 = 1573; - private static final int GRAPHICSOBJECT_ID_BLOAT_HAND5 = 1576; private static final int PROJECTILE_ID_P2RANGE = 1583; private static final int PROJECTILE_ID_YELLOW = 1596; private static final int ANIMATION_ID_P3_WEB = 8127; @@ -56,11 +52,30 @@ public class TheatrePlugin extends Plugin { private static final int VERZIK_ID_P3 = NpcID.VERZIK_VITUR_8374; private static final int NPC_ID_TORNADO = 8386; private static final int PROJECTILE_ID_P3_GREEN = 1598; - private static final String sotmsg = "A large ball of energy is shot your way..."; - private static final String sotmsg1 = "A large ball of energy is shot your way..."; - @Inject - private ChatMessageManager chatMessageManager; + + @Getter(AccessLevel.PACKAGE) + private final Map xarpusExhumedsTimer = new HashMap<>(); + @Getter + int exhumecount; + @Getter + int bloatTimer = 0; + + int bloatFeetTimer = 0; + NPC BossNylo = null; + private boolean bloatFlag = false; + @Getter + private Set bloatTiles = new HashSet<>(); + @Getter + private Set temp = new HashSet<>(); + @Getter + private Set temp2 = new HashSet<>(); + @Getter + private Set localTemp = new HashSet<>(); + + //@Getter + //private List bloatTiles = new ArrayList<>(); + @Getter(AccessLevel.PACKAGE) private boolean runMaiden; @@ -80,9 +95,6 @@ public class TheatrePlugin extends Plugin { @Getter(AccessLevel.PACKAGE) private boolean runBloat; - @Getter(AccessLevel.PACKAGE) - private int TickTillEat = 20; - @Getter(AccessLevel.PACKAGE) private NPC Bloat_NPC; @@ -112,12 +124,13 @@ public class TheatrePlugin extends Plugin { private List RedTilesOverworld = new ArrayList<>(); private List BlackTilesOverworld = new ArrayList<>(); - - private List BlackTilesUnderworld= new ArrayList<>(); - - private List RedTilesUnderworld= new ArrayList<>(); + @Getter + private boolean tempFlag = false; + @Getter + private boolean temp2Flag = false; private List GridPath = new ArrayList<>(); + private List BlackTilesUnderworld = new ArrayList<>(); @Getter(AccessLevel.PACKAGE) private boolean runXarpus; @@ -129,6 +142,7 @@ public class TheatrePlugin extends Plugin { @Getter(AccessLevel.PACKAGE) private final Map Xarpus_Exhumeds = new HashMap<>(); + private List RedTilesUnderworld = new ArrayList<>(); @Getter(AccessLevel.PACKAGE) private int Xarpus_TicksUntilShoot = 9; @@ -136,9 +150,6 @@ public class TheatrePlugin extends Plugin { @Getter(AccessLevel.PACKAGE) private NPC Xarpus_NPC; - @Getter(AccessLevel.PACKAGE) - private NPC Sotetseg_NPC; - @Getter(AccessLevel.PACKAGE) private boolean runVerzik; @@ -154,17 +165,16 @@ public class TheatrePlugin extends Plugin { @Getter(AccessLevel.PACKAGE) private List Verzik_YellowTiles = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) - private List Bloat_Hands = new ArrayList<>(); - @Getter(AccessLevel.PACKAGE) private NPC Verzik_NPC; + @Getter(AccessLevel.PACKAGE) + private List tornadoList; @Getter(AccessLevel.PACKAGE) - private NPC Verzik_NPC_P3; + private List crabList; - @Getter(AccessLevel.PACKAGE) - private NPC Verzik_NPC_P2; + @Getter + private int redCrabsTimer; private int P3_attacksLeft; @@ -180,6 +190,18 @@ public class TheatrePlugin extends Plugin { @Inject private TheatreConfig config; + @Inject + private TheatreXarpusOverlay xarpusOverlay; + + @Inject + private ChatMessageManager chatMessageManager; + + @Inject + private VerzikNyloOverlay verzikNyloOverlay; + + @Inject + private BloatTimerOverlay bloatTimerOverlay; + @Provides TheatreConfig getConfig(ConfigManager configManager) { return configManager.getConfig(TheatreConfig.class); @@ -188,19 +210,116 @@ public class TheatrePlugin extends Plugin { @Override protected void startUp() { overlayManager.add(overlay); + overlayManager.add(xarpusOverlay); + overlayManager.add(verzikNyloOverlay); + overlayManager.add(bloatTimerOverlay); } @Override protected void shutDown() { overlayManager.remove(overlay); + overlayManager.remove(xarpusOverlay); + overlayManager.remove(xarpusOverlay); + overlayManager.remove(bloatTimerOverlay); + } + + + @Subscribe + public void onMenuEntryAdded(MenuEntryAdded event) { + if (client.getGameState() != GameState.LOGGED_IN || !config.NyloMenu() || !runNylocas) { + return; + } + + final String pOptionToReplace = Text.removeTags(event.getOption()).toUpperCase(); + Map playerEquipment = new HashMap<>(); + + int attackType = 0; //0=idk 1= melee 2= range 3= mage + + for (KitType kitType : KitType.values()) { + + int itemId = client.getLocalPlayer().getPlayerComposition().getEquipmentId(kitType); + switch (itemId) { + case ItemID.DRAGON_CLAWS: + case ItemID.SCYTHE_OF_VITUR: + case ItemID.SCYTHE_OF_VITUR_UNCHARGED: + case ItemID.SCYTHE_10735: + case ItemID.SCYTHE_OF_VITUR_22664: + case ItemID.HAM_JOINT: + case ItemID.EVENT_RPG: + case ItemID.ABYSSAL_WHIP: + case ItemID.ABYSSAL_TENTACLE: + case ItemID.FROZEN_ABYSSAL_WHIP: + case ItemID.VOLCANIC_ABYSSAL_WHIP: + case ItemID.GHRAZI_RAPIER: + case ItemID.DRAGON_WARHAMMER: + case ItemID.DRAGON_WARHAMMER_20785: + case ItemID.BANDOS_GODSWORD: + case ItemID.BANDOS_GODSWORD_OR: + case ItemID.BANDOS_GODSWORD_20782: + case ItemID.BANDOS_GODSWORD_21060: + case ItemID.CRYSTAL_HALBERD_510: + case ItemID.CRYSTAL_HALBERD_510_I: + case ItemID.CRYSTAL_HALBERD_610: + case ItemID.CRYSTAL_HALBERD_610_I: + case ItemID.CRYSTAL_HALBERD_710_I: + case ItemID.CRYSTAL_HALBERD_710: + case ItemID.CRYSTAL_HALBERD_110: + case ItemID.CRYSTAL_HALBERD_110_I: + case ItemID.CRYSTAL_HALBERD_210: + case ItemID.CRYSTAL_HALBERD_310: + case ItemID.CRYSTAL_HALBERD_310_I: + case ItemID.CRYSTAL_HALBERD_410: + case ItemID.CRYSTAL_HALBERD_410_I: + case ItemID.CRYSTAL_HALBERD_810: + case ItemID.CRYSTAL_HALBERD_810_I: + case ItemID.CRYSTAL_HALBERD_910: + case ItemID.CRYSTAL_HALBERD_910_I: + attackType = 1; + break; + case ItemID.TOXIC_BLOWPIPE: + case ItemID.TOXIC_BLOWPIPE_EMPTY: + case ItemID.RED_CHINCHOMPA_10034: + case ItemID.BLACK_CHINCHOMPA: + case ItemID.CHINCHOMPA_10033: + case ItemID.TWISTED_BOW: + attackType = 2; + break; + case ItemID.SANGUINESTI_STAFF: + case ItemID.TOXIC_STAFF_OF_THE_DEAD: + case ItemID.TRIDENT_OF_THE_SWAMP: + case ItemID.TRIDENT_OF_THE_SEAS_E: + case ItemID.TRIDENT_OF_THE_SEAS: + case ItemID.TRIDENT_OF_THE_SWAMP_E: + case ItemID.KODAI_WAND: + case ItemID.MASTER_WAND: + case ItemID.MASTER_WAND_20560: + attackType = 3; + break; + } + if (attackType != 0) { + break; + } + + } + if (pOptionToReplace.equals("CANCEL") || pOptionToReplace.equals("WALK HERE") || pOptionToReplace.equals("PASS")) { + return; + } + int Id = 0; + if (BossNylo != null) { + Id = BossNylo.getId(); + } + String target = Text.removeTags(event.getTarget()).toLowerCase(); + if (attackType != 0) { + stripEntries(attackType, target, Id); + } + } @Subscribe - public void onNpcSpawned(NpcSpawned npcSpawned) - { + public void onNpcSpawned(NpcSpawned npcSpawned) { + NPC npc = npcSpawned.getNpc(); - switch (npc.getId()) - { + switch (npc.getId()) { case NpcID.THE_MAIDEN_OF_SUGADINTI: case NpcID.THE_MAIDEN_OF_SUGADINTI_8361: case NpcID.THE_MAIDEN_OF_SUGADINTI_8362: @@ -215,25 +334,40 @@ public class TheatrePlugin extends Plugin { case NpcID.PESTILENT_BLOAT: runBloat = true; Bloat_NPC = npc; + bloatTimer = 0; + bloatFlag = false; + break; + case NpcID.NYLOCAS_VASILIAS: + case NpcID.NYLOCAS_VASILIAS_8355: + case NpcID.NYLOCAS_VASILIAS_8356: + case NpcID.NYLOCAS_VASILIAS_8357: + BossNylo = npc; break; case NPCID_NYLOCAS_PILLAR: runNylocas = true; - if (!Nylocas_Pillars.keySet().contains(npc)) - { + if (!Nylocas_Pillars.keySet().contains(npc)) { Nylocas_Pillars.put(npc, 100); } break; - case 8342: case 8343: case 8344: case 8345: case 8346: case 8347: - case 8348: case 8349: case 8350: case 8351: case 8352: case 8353: - if (runNylocas) - { + case 8342: + case 8343: + case 8344: + case 8345: + case 8346: + case 8347: + case 8348: + case 8349: + case 8350: + case 8351: + case 8352: + case 8353: + if (runNylocas) { Nylocas_Map.put(npc, 52); } break; case NpcID.SOTETSEG: case NpcID.SOTETSEG_8388: runSotetseg = true; - Sotetseg_NPC = npc; RedTiles.clear(); break; case NpcID.XARPUS: @@ -241,6 +375,7 @@ public class TheatrePlugin extends Plugin { case NpcID.XARPUS_8340: case NpcID.XARPUS_8341: runXarpus = true; + exhumecount = 25; Xarpus_NPC = npc; Xarpus_Stare = false; Xarpus_TicksUntilShoot = 9; @@ -249,22 +384,17 @@ public class TheatrePlugin extends Plugin { case NpcID.VERZIK_VITUR_8369: case NpcID.VERZIK_VITUR_8370: case NpcID.VERZIK_VITUR_8371: + case NpcID.VERZIK_VITUR_8372: case NpcID.VERZIK_VITUR_8373: + case NpcID.VERZIK_VITUR_8374: case NpcID.VERZIK_VITUR_8375: + P3_TicksUntilAttack = -1; + P3_attacksLeft = 9; + redCrabsTimer = 13; Verzik_NPC = npc; runVerzik = true; - break; - - case NpcID.VERZIK_VITUR_8372:/*p2 spider*/ - Verzik_NPC_P2 = npc; - runVerzik = true; - break; - - case NpcID.VERZIK_VITUR_8374:/*p3 spider*/ - P3_TicksUntilAttack = 0; - P3_attacksLeft = 9; - Verzik_NPC_P3 = npc; - runVerzik = true; + tornadoList = new ArrayList<>(); + crabList = new ArrayList<>(); break; } } @@ -288,28 +418,35 @@ public class TheatrePlugin extends Plugin { case NpcID.PESTILENT_BLOAT: runBloat = false; Bloat_NPC = null; + bloatTimer = 0; break; case NPCID_NYLOCAS_PILLAR: - if (Nylocas_Pillars.keySet().contains(npc)) - { + if (Nylocas_Pillars.keySet().contains(npc)) { Nylocas_Pillars.remove(npc); } break; - case 8342: case 8343: case 8344: case 8345: case 8346: case 8347: - case 8348: case 8349: case 8350: case 8351: case 8352: case 8353: - if (Nylocas_Map.keySet().contains(npc)) - { + case 8342: + case 8343: + case 8344: + case 8345: + case 8346: + case 8347: + case 8348: + case 8349: + case 8350: + case 8351: + case 8352: + case 8353: + if (Nylocas_Map.keySet().contains(npc)) { Nylocas_Map.remove(npc); } break; case NpcID.SOTETSEG: case NpcID.SOTETSEG_8388: RedTiles.clear(); - if (client.getPlane() != 3) - { + if (client.getPlane() != 3) { runSotetseg = false; } - Sotetseg_NPC = null; break; case NpcID.XARPUS: case NpcID.XARPUS_8339: @@ -321,117 +458,119 @@ public class TheatrePlugin extends Plugin { Xarpus_TicksUntilShoot = 9; Xarpus_previousAnimation = -1; Xarpus_Exhumeds.clear(); + exhumecount = 0; break; case NpcID.VERZIK_VITUR_8369: case NpcID.VERZIK_VITUR_8370: - case NpcID.VERZIK_VITUR_8371:/*p2*/ - + case NpcID.VERZIK_VITUR_8371: + case NpcID.VERZIK_VITUR_8372: case NpcID.VERZIK_VITUR_8373: - + case NpcID.VERZIK_VITUR_8374: case NpcID.VERZIK_VITUR_8375: + runVerzik = false; + redCrabsTimer = 0; Verzik_NPC = null; break; - case NpcID.VERZIK_VITUR_8372: - Verzik_NPC_P2 = null; - break; - case NpcID.VERZIK_VITUR_8374:/*p3 spider*/ - Verzik_NPC_P3 = null; - break; - } } @Subscribe - public void onGroundObjectSpawned(GroundObjectSpawned event) - { - if (runSotetseg) - { + public void onGroundObjectSpawned(GroundObjectSpawned event) { + if (runSotetseg) { GroundObject o = event.getGroundObject(); - if (o.getId() == GROUNDOBJECT_ID_BLACKMAZE) - { + if (o.getId() == GROUNDOBJECT_ID_BLACKMAZE) { Tile t = event.getTile(); WorldPoint p = t.getWorldLocation(); - if (t.getPlane() == 0) - { + if (t.getPlane() == 0) { if (!BlackTilesOverworld.contains(p)) BlackTilesOverworld.add(p); - } - else - { + } else { if (!BlackTilesUnderworld.contains(p)) BlackTilesUnderworld.add(p); } } - if (o.getId() == GROUNDOBJECT_ID_REDMAZE) - { + if (o.getId() == GROUNDOBJECT_ID_REDMAZE) { Tile t = event.getTile(); WorldPoint p = t.getWorldLocation(); - if (p.getPlane() == 0) - { - if (!RedTiles.containsValue(t)) - { - RedTiles.put(o,t); + if (p.getPlane() == 0) { + if (!RedTiles.containsValue(t)) { + RedTiles.put(o, t); } - } - else - { + } else { if (!RedTilesUnderworld.contains(p)) RedTilesUnderworld.add(p); } } } - if (runXarpus) - { + if (runXarpus) { GroundObject o = event.getGroundObject(); - if (o.getId() == GROUNDOBJECT_ID_EXHUMED) - { + if (o.getId() == GROUNDOBJECT_ID_EXHUMED) { + + xarpusExhumedsTimer.put(o, 18); + Xarpus_Exhumeds.put(o, 18); + } + } } @Subscribe - public void onProjectileMoved(ProjectileMoved event) - { - if (runVerzik) - { + public void onProjectileMoved(ProjectileMoved event) { + if (runVerzik) { Projectile projectile = event.getProjectile(); - if (projectile.getId() == PROJECTILE_ID_P2RANGE) - { - WorldPoint p = WorldPoint.fromLocal(client,event.getPosition()); + if (projectile.getId() == PROJECTILE_ID_P2RANGE) { + WorldPoint p = WorldPoint.fromLocal(client, event.getPosition()); Verzik_RangeProjectiles.put(projectile, p); } } } @Subscribe - public void onChatMessage(ChatMessage chatMessage) - { - MessageNode messageNode = chatMessage.getMessageNode(); - - if (messageNode.getValue().toLowerCase().contains(sotmsg.toLowerCase())) - { - TickTillEat = 20; - /*20 ticks*/ - + public void onAnimationChanged(AnimationChanged event) { + if (runVerzik) { + if (event.getActor().getAnimation() == 8117) { + redCrabsTimer = 11; + } } - - } @Subscribe - public void onGameTick(GameTick event) - { - if (runMaiden) - { + public void onVarbitChanged(VarbitChanged event) { + if (runBloat) { + + if (client.getVar(Varbits.BLOAT_ENTERED_ROOM) == 1) { + if (!bloatFlag) { + bloatTimer = 0; + bloatFlag = true; + } + } + } + } + + @Subscribe + public void onGraphicsObjectCreated(GraphicsObjectCreated event) { + GraphicsObject obj = event.getGraphicsObject(); + if (obj.getId() == 1570 || obj.getId() == 1571 || obj.getId() == 1572 || obj.getId() == 1573 || obj.getId() == 1574 || obj.getId() == 1575 || obj.getId() == 1576) { + WorldPoint p = WorldPoint.fromLocal(client, obj.getLocation()); + if (temp.size() == 0) { + + } else { + + } + } + } + + + @Subscribe + public void onGameTick(GameTick event) { + if (runMaiden) { Maiden_BloodSpatters.clear(); - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_MAIDEN) - { + for (GraphicsObject o : client.getGraphicsObjects()) { + if (o.getId() == GRAPHICSOBJECT_ID_MAIDEN) { Maiden_BloodSpatters.add(WorldPoint.fromLocal(client, o.getLocation())); } } @@ -439,98 +578,117 @@ public class TheatrePlugin extends Plugin { Maiden_SpawnLocations2.clear(); Maiden_SpawnLocations2.addAll(Maiden_SpawnLocations); Maiden_SpawnLocations.clear(); - for (NPC spawn : Maiden_Spawns) - { + for (NPC spawn : Maiden_Spawns) { Maiden_SpawnLocations.add(spawn.getWorldLocation()); } } - if (runBloat) - { + if (runBloat) { + + localTemp.clear(); + + //System.out.println("Temp flag" + tempFlag); + //System.out.println("Temp2 flag" + temp2Flag); + + + for (GraphicsObject obj : client.getGraphicsObjects()) { + if (obj.getId() == 1570 || obj.getId() == 1571 || obj.getId() == 1572 || obj.getId() == 1573 || obj.getId() == 1574 || obj.getId() == 1575 || obj.getId() == 1576) { + WorldPoint p = WorldPoint.fromLocal(client, obj.getLocation()); + //Already have some feet in temp Set + if (temp.size() > 0) { + //System.out.println("temp size > 0, tempflag set false, tempflag2 set true"); + tempFlag = false; + temp2Flag = true; + } else { + //System.out.println("temp size 0, tempflag set true, tempflag2 set false"); + tempFlag = true; + temp2Flag = false; + + } + localTemp.add(p); + } + } + + if (tempFlag) { + temp2.clear(); + temp2Flag = false; + temp.addAll(localTemp); + + + //System.out.println("temp2 cleared, temp2flag set false, added to temp set"); + } else if (temp2Flag) { + temp.clear(); + tempFlag = false; + temp2.addAll(localTemp); + //System.out.println("temp cleared, tempflag set false, added to temp2 set"); + + } Bloat_downCount++; - Bloat_Hands.clear(); - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND1 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND2 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND3 || o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND4|| o.getId() == GRAPHICSOBJECT_ID_BLOAT_HAND5) - { - Bloat_Hands.add(WorldPoint.fromLocal(client, o.getLocation())); - } - } - - if (Bloat_NPC.getAnimation() == -1) //1 = up; 2 = down; 3 = warn; { + bloatTimer++; Bloat_downCount = 0; - if (Bloat_NPC.getHealth() == 0) - { + if (Bloat_NPC.getHealth() == 0) { Bloat_State = 2; - } - else + } else Bloat_State = 1; - } - else - { - if (25 it = Nylocas_Map.keySet().iterator(); it.hasNext();) - { + if (runNylocas) { + for (Iterator it = Nylocas_Map.keySet().iterator(); it.hasNext(); ) { NPC npc = it.next(); int ticksLeft = Nylocas_Map.get(npc); - if (ticksLeft < 0) - { + if (ticksLeft < 0) { it.remove(); continue; } Nylocas_Map.replace(npc, ticksLeft - 1); } - for (NPC pillar : Nylocas_Pillars.keySet()) - { + for (NPC pillar : Nylocas_Pillars.keySet()) { int healthPercent = pillar.getHealthRatio(); - if (healthPercent > -1) - { + if (healthPercent > -1) { Nylocas_Pillars.replace(pillar, healthPercent); } } - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == 8358) - { + for (NPC npc : client.getNpcs()) { + if (npc.getId() == 8358) { runNylocas = true; break; } runNylocas = false; + BossNylo = null; } } - if (runSotetseg) - { - TickTillEat--; + if (runSotetseg) { boolean sotetsegFighting = false; - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == NpcID.SOTETSEG_8388) - { + for (NPC npc : client.getNpcs()) { + if (npc.getId() == NpcID.SOTETSEG_8388) { BlackTilesUnderworld.clear(); BlackTilesOverworld.clear(); RedTilesOverworld.clear(); @@ -542,42 +700,33 @@ public class TheatrePlugin extends Plugin { } } - if (!sotetsegFighting) - { - if (!BlackTilesUnderworld.isEmpty() && !RedTilesUnderworld.isEmpty() && GridPath.isEmpty()) - { + if (!sotetsegFighting) { + if (!BlackTilesUnderworld.isEmpty() && !RedTilesUnderworld.isEmpty() && GridPath.isEmpty()) { int minX = 99999; int minY = 99999; - for (WorldPoint p : BlackTilesUnderworld) - { + for (WorldPoint p : BlackTilesUnderworld) { int x = p.getX(); int y = p.getY(); - if (x < minX) - { + if (x < minX) { minX = x; } - if (y < minY) - { + if (y < minY) { minY = y; } } - boolean messageSent = false; - for (WorldPoint p : RedTilesUnderworld) - { + for (WorldPoint p : RedTilesUnderworld) { WorldPoint pN = new WorldPoint(p.getX(), p.getY() + 1, p.getPlane()); WorldPoint pS = new WorldPoint(p.getX(), p.getY() - 1, p.getPlane()); WorldPoint pE = new WorldPoint(p.getX() + 1, p.getY(), p.getPlane()); WorldPoint pW = new WorldPoint(p.getX() - 1, p.getY(), p.getPlane()); - if ( !( (RedTilesUnderworld.contains(pN) && RedTilesUnderworld.contains(pS)) || - (RedTilesUnderworld.contains(pE) && RedTilesUnderworld.contains(pW)) ) ) - { + if (!((RedTilesUnderworld.contains(pN) && RedTilesUnderworld.contains(pS)) || + (RedTilesUnderworld.contains(pE) && RedTilesUnderworld.contains(pW)))) { GridPath.add(new Point(p.getX() - minX, p.getY() - minY)); - if (!messageSent) - { + if (!messageSent) { //client.addChatMessage(ChatMessageType.SERVER, "", "Maze path acquired.", null); messageSent = true; } @@ -586,71 +735,74 @@ public class TheatrePlugin extends Plugin { } } - if (!BlackTilesOverworld.isEmpty() && !GridPath.isEmpty() && RedTilesOverworld.isEmpty()) - { + if (!BlackTilesOverworld.isEmpty() && !GridPath.isEmpty() && RedTilesOverworld.isEmpty()) { int minX = 99999; int minY = 99999; - for (WorldPoint p : BlackTilesOverworld) - { + for (WorldPoint p : BlackTilesOverworld) { int x = p.getX(); int y = p.getY(); - if (x < minX) - { + if (x < minX) { minX = x; } - if (y < minY) - { + if (y < minY) { minY = y; } } - for (Point p : GridPath) - { + for (Point p : GridPath) { RedTilesOverworld.add(new WorldPoint(minX + p.getX(), minY + p.getY(), 0)); } } } } - if (runXarpus) - { - for (Iterator it = Xarpus_Exhumeds.keySet().iterator(); it.hasNext();) - { + if (runXarpus) { + int size = xarpusExhumedsTimer.size(); + for (Map.Entry exhumes : xarpusExhumedsTimer.entrySet()) { + if (size > 0) { + exhumes.setValue(exhumes.getValue() - 1); + } + + } + for (Iterator it = Xarpus_Exhumeds.keySet().iterator(); it.hasNext(); ) { GroundObject key = it.next(); Xarpus_Exhumeds.replace(key, Xarpus_Exhumeds.get(key) - 1); - if (Xarpus_Exhumeds.get(key) < 0) - { + if (Xarpus_Exhumeds.get(key) < 0) { it.remove(); + exhumecount--; } } - if (Xarpus_NPC.getOverheadText() != null ) - { + if ((Xarpus_NPC.getComposition().getOverheadIcon() != null)) { Xarpus_Stare = true; } - if (Xarpus_Stare) - { + if (Xarpus_Stare) { //dont hit xarpus if it looking at u - } - else if (Xarpus_NPC.getId() == NpcID.XARPUS_8340) - { + } else if (Xarpus_NPC.getId() == NpcID.XARPUS_8340) { Xarpus_TicksUntilShoot--; - if (Xarpus_NPC.getAnimation() == ANIMATION_ID_XARPUS && Xarpus_previousAnimation != ANIMATION_ID_XARPUS) - { - Xarpus_TicksUntilShoot = 3; - } - Xarpus_previousAnimation = Xarpus_NPC.getAnimation(); + //if (Xarpus_NPC.getAnimation() == ANIMATION_ID_XARPUS && Xarpus_previousAnimation != ANIMATION_ID_XARPUS) + //{ + //Xarpus_TicksUntilShoot = 3; + //} + //Xarpus_previousAnimation = Xarpus_NPC.getAnimation(); } } - if (runVerzik) - { - if (!Verzik_RangeProjectiles.isEmpty()) - { - for (Iterator it = Verzik_RangeProjectiles.keySet().iterator(); it.hasNext();) - { + if (runVerzik) { + crabList.clear(); + for (NPC npc : client.getNpcs()) { + + if (npc.getName().toLowerCase().contains("nylo")) { + crabList.add(npc); + } + } + + if (Verzik_NPC.getAnimation() == 8117) { + redCrabsTimer = redCrabsTimer - 1; + } + if (!Verzik_RangeProjectiles.isEmpty()) { + for (Iterator it = Verzik_RangeProjectiles.keySet().iterator(); it.hasNext(); ) { Projectile projectile = it.next(); - if (projectile.getRemainingCycles() < 1) - { + if (projectile.getRemainingCycles() < 1) { it.remove(); } } @@ -659,55 +811,40 @@ public class TheatrePlugin extends Plugin { Verzik_YellowBall = null; Verzik_YellowTiles.clear(); - for (Projectile projectile : client.getProjectiles()) - { - if (projectile.getId() == PROJECTILE_ID_YELLOW) - { + for (Projectile projectile : client.getProjectiles()) { + if (projectile.getId() == PROJECTILE_ID_YELLOW) { Verzik_YellowBall = projectile; break; } } - for (GraphicsObject o : client.getGraphicsObjects()) - { - if (o.getId() == GRAPHICSOBJECT_ID_YELLOW) - { + for (GraphicsObject o : client.getGraphicsObjects()) { + if (o.getId() == GRAPHICSOBJECT_ID_YELLOW) { + Verzik_YellowTiles.add(WorldPoint.fromLocal(client, o.getLocation())); } } - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == 8379) - { - runVerzik = true; - break; - } - runVerzik = false; - } - - - if (Verzik_NPC_P3 != null) { + if (Verzik_NPC.getId() == VERZIK_ID_P3) { boolean tornadosActive = false; - for (NPC npc : client.getNpcs()) - { - if (npc.getId() == NPC_ID_TORNADO) - { + for (NPC npc : client.getNpcs()) { + if (npc.getId() == NPC_ID_TORNADO) { + tornadoList.add(npc); tornadosActive = true; break; } } boolean isGreenBall = false; - for (Projectile projectile : client.getProjectiles()) - { + for (Projectile projectile : client.getProjectiles()) { if (projectile.getId() == PROJECTILE_ID_P3_GREEN) { isGreenBall = projectile.getRemainingCycles() > 210; break; } } + P3_TicksUntilAttack--; - switch (Verzik_NPC_P3.getAnimation()) { + switch (Verzik_NPC.getAnimation()) { case ANIMATION_ID_P3_MAGE: if (P3_TicksUntilAttack < 2) { P3_attacksLeft--; @@ -762,6 +899,90 @@ public class TheatrePlugin extends Plugin { } } + + } -} + private void stripEntries(int style, String target, int NyloID) { + String Keep = null; + if (NyloID == 0) { + switch (style) { + case 1: + Keep = "Nylocas Ischyros"; + break; + case 2: + Keep = "Nylocal Toxobolos"; + break; + case 3: + Keep = "Nylocas Hagios"; + break; + } + } else { + Keep = "fuckaadamhypocrticalpos"; + switch (NyloID) { + case 8356://0=idk 1= melee 2= range 3= mage + if (style == 3) { + + Keep = "Nylocas Vasilias"; + } + break; + case 8357: + if (style == 2) { + Keep = "Nylocas Vasilias"; + } + break; + default: + if (style == 1) { + Keep = "Nylocas Vasilias"; + } + } + + } + int entryLength = 0; + List entryList = new ArrayList<>(); + for (MenuEntry entry : client.getMenuEntries()) { + if (Text.removeTags(entry.getTarget()).contains(Keep) && entry.getOption().equals("Attack")) { + + entryList.add(entry); + entryLength++; + } + if (entry.getOption().equalsIgnoreCase("walk here") || entry.getOption().equalsIgnoreCase("pass") || entry.getOption().equalsIgnoreCase("take")) { + entryList.add(entry); + entryLength++; + } + } + + //System.out.println("i see " + entryLength + " good options using style" + style); + if (entryLength != 0) { + MenuEntry[] newEntries = new MenuEntry[entryLength]; + + + for (int i = 0; i < (entryLength); i++) { + newEntries[i] = entryList.get(i); + } + client.setMenuEntries(newEntries); + } + + + } + + private int searchIndex(MenuEntry[] entries, String option, String target, boolean strict) { + for (int i = entries.length - 1; i >= 0; i--) { + MenuEntry entry = entries[i]; + String entryOption = Text.removeTags(entry.getOption()).toLowerCase(); + String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase(); + + if (strict) { + if (entryOption.equals(option) && entryTarget.equals(target)) { + return i; + } + } else { + if (entryOption.contains(option.toLowerCase()) && entryTarget.equals(target)) { + return i; + } + } + } + + return -1; + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java new file mode 100644 index 0000000000..72757be422 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/TheatreXarpusOverlay.java @@ -0,0 +1,68 @@ +package net.runelite.client.plugins.ztob; + +import com.google.inject.Inject; +import net.runelite.client.ui.overlay.Overlay; +import net.runelite.client.ui.overlay.OverlayMenuEntry; +import net.runelite.client.ui.overlay.OverlayPosition; +import net.runelite.client.ui.overlay.components.LineComponent; +import net.runelite.client.ui.overlay.components.PanelComponent; +import net.runelite.client.ui.overlay.components.TitleComponent; + +import java.awt.*; + +import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG; +import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE; + +public class TheatreXarpusOverlay extends Overlay { + private final TheatrePlugin plugin; + private final TheatreConfig config; + PanelComponent panelComponent = new PanelComponent(); + + @Inject + private TheatreXarpusOverlay(TheatrePlugin plugin, TheatreConfig config) { + super(plugin); + setPosition(OverlayPosition.ABOVE_CHATBOX_RIGHT); + setPosition(OverlayPosition.DYNAMIC); + setPosition(OverlayPosition.DETACHED); + this.plugin = plugin; + this.config = config; + getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Theatre xarpus overlay")); + + } + + @Override + public Dimension render(Graphics2D graphics) { + if (plugin.isRunXarpus()) { + if (config.XarpusExhumeOverlay()) { + if (plugin.getXarpus_NPC().getId() == 8339) { + panelComponent.getChildren().clear(); + String overlayTitle = "Exhume Counter"; + + + // Build overlay title + panelComponent.getChildren().add(TitleComponent.builder() + .text(overlayTitle) + .color(Color.GREEN) + .build()); + + //Set the size of overlay + panelComponent.setPreferredSize(new Dimension( + graphics.getFontMetrics().stringWidth(overlayTitle) + 30, 0 + )); + + panelComponent.getChildren().add(LineComponent.builder() + .left("Exhumes: ") + .right(String.valueOf(plugin.getExhumecount())) + .build()); + } + } + return panelComponent.render(graphics); + } + + return null; + + } + + +} + diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java new file mode 100644 index 0000000000..68f0630c12 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/ztob/VerzikNyloOverlay.java @@ -0,0 +1,81 @@ +package net.runelite.client.plugins.ztob; + +import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.Point; +import net.runelite.client.ui.overlay.*; + +import javax.inject.Inject; +import java.awt.*; + +public class VerzikNyloOverlay extends Overlay { + + private final Client client; + private final TheatrePlugin plugin; + private final TheatreConfig config; + + @Inject + private VerzikNyloOverlay(Client client, TheatrePlugin plugin, TheatreConfig config) { + this.client = client; + this.plugin = plugin; + this.config = config; + setPosition(OverlayPosition.DYNAMIC); + setPriority(OverlayPriority.HIGH); + setLayer(OverlayLayer.ABOVE_SCENE); + } + + public Dimension render(Graphics2D graphics) { + + if (plugin.isRunVerzik()) { + if (config.NyloTargetOverlay()) { + if (plugin.getCrabList().size() > 0) { + + for (NPC npc : plugin.getCrabList()) { + if (npc.isDead()) { + continue; + } + String renderText = ""; + if (npc.getInteracting() != null) { + + renderText = npc.getInteracting().getName(); + Point point = npc.getCanvasTextLocation(graphics, npc.getInteracting().getName(), 0); + + + if (npc.getInteracting().getName().toLowerCase().equals(client.getLocalPlayer().getName().toLowerCase())) { + point = npc.getCanvasTextLocation(graphics, client.getLocalPlayer().getName(), 0); + renderText = "YOU NIGGA RUN!"; + + } else if (npc.getInteracting().getName().toLowerCase().equals("afyy")) { + point = npc.getCanvasTextLocation(graphics, "Ricecup", 0); + renderText = "Ricecup"; + } + if (renderText.equals("YOU NIGGA RUN!")) { + renderTextLocation(graphics, renderText, 12, Font.BOLD, Color.RED, point); + } else { + renderTextLocation(graphics, renderText, 12, Font.BOLD, Color.GREEN, point); + } + } + + } + } + + } + } + + return null; + } + + private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint) { + graphics.setFont(new Font("Arial", fontStyle, fontSize)); + if (canvasPoint != null) { + final Point canvasCenterPoint = new Point( + canvasPoint.getX(), + canvasPoint.getY()); + final Point canvasCenterPoint_shadow = new Point( + canvasPoint.getX() + 1, + canvasPoint.getY() + 1); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK); + OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor); + } + } +} diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/equipmentinspector/normal.png b/runelite-client/src/main/resources/net/runelite/client/plugins/equipmentinspector/normal.png new file mode 100644 index 0000000000..613f95e46d Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/equipmentinspector/normal.png differ