diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/BrokenOnDeathItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/BrokenOnDeathItem.java index 9f1fd5c95e..8512a05541 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/BrokenOnDeathItem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/BrokenOnDeathItem.java @@ -24,7 +24,8 @@ */ package net.runelite.client.plugins.itemskeptondeath; -import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableMap; +import javax.annotation.Nullable; import lombok.AllArgsConstructor; import net.runelite.api.ItemID; @@ -37,75 +38,76 @@ import net.runelite.api.ItemID; enum BrokenOnDeathItem { // Capes - FIRE_CAPE(ItemID.FIRE_CAPE), - FIRE_MAX_CAPE(ItemID.FIRE_MAX_CAPE), - INFERNAL_CAPE(ItemID.INFERNAL_CAPE), - INFERNAL_MAX_CAPE(ItemID.INFERNAL_MAX_CAPE), - AVAS_ASSEMBLER(ItemID.AVAS_ASSEMBLER), - ASSEMBLER_MAX_CAPE(ItemID.ASSEMBLER_MAX_CAPE), + FIRE_CAPE(ItemID.FIRE_CAPE, 50000), + FIRE_MAX_CAPE(ItemID.FIRE_MAX_CAPE, 50000), + INFERNAL_CAPE(ItemID.INFERNAL_CAPE, 50000), + INFERNAL_MAX_CAPE(ItemID.INFERNAL_MAX_CAPE, 50000), + AVAS_ASSEMBLER(ItemID.AVAS_ASSEMBLER, 75000), + ASSEMBLER_MAX_CAPE(ItemID.ASSEMBLER_MAX_CAPE, 75000), // Defenders - BRONZE_DEFENDER(ItemID.BRONZE_DEFENDER), - IRON_DEFENDER(ItemID.IRON_DEFENDER), - STEEL_DEFENDER(ItemID.STEEL_DEFENDER), - BLACK_DEFENDER(ItemID.BLACK_DEFENDER), - MITHRIL_DEFENDER(ItemID.MITHRIL_DEFENDER), - ADAMANT_DEFENDER(ItemID.ADAMANT_DEFENDER), - RUNE_DEFENDER(ItemID.RUNE_DEFENDER), - DRAGON_DEFENDER(ItemID.DRAGON_DEFENDER), - AVERNIC_DEFENDER(ItemID.AVERNIC_DEFENDER), + BRONZE_DEFENDER(ItemID.BRONZE_DEFENDER, 1000), + IRON_DEFENDER(ItemID.IRON_DEFENDER, 2000), + STEEL_DEFENDER(ItemID.STEEL_DEFENDER, 2500), + BLACK_DEFENDER(ItemID.BLACK_DEFENDER, 5000), + MITHRIL_DEFENDER(ItemID.MITHRIL_DEFENDER, 15000), + ADAMANT_DEFENDER(ItemID.ADAMANT_DEFENDER, 25000), + RUNE_DEFENDER(ItemID.RUNE_DEFENDER, 35000), + DRAGON_DEFENDER(ItemID.DRAGON_DEFENDER, 40000), + AVERNIC_DEFENDER(ItemID.AVERNIC_DEFENDER, 1000000), // Void - VOID_MAGE_HELM(ItemID.VOID_MAGE_HELM), - VOID_RANGER_HELM(ItemID.VOID_RANGER_HELM), - VOID_MELEE_HELM(ItemID.VOID_MELEE_HELM), - VOID_KNIGHT_TOP(ItemID.VOID_KNIGHT_TOP), - VOID_KNIGHT_ROBE(ItemID.VOID_KNIGHT_ROBE), - VOID_KNIGHT_GLOVES(ItemID.VOID_KNIGHT_GLOVES), - VOID_KNIGHT_MACE(ItemID.VOID_KNIGHT_MACE), - ELITE_VOID_TOP(ItemID.ELITE_VOID_TOP), - ELITE_VOID_ROBE(ItemID.ELITE_VOID_ROBE), + VOID_MAGE_HELM(ItemID.VOID_MAGE_HELM, 40000), + VOID_RANGER_HELM(ItemID.VOID_RANGER_HELM, 40000), + VOID_MELEE_HELM(ItemID.VOID_MELEE_HELM, 40000), + VOID_KNIGHT_TOP(ItemID.VOID_KNIGHT_TOP, 45000), + VOID_KNIGHT_ROBE(ItemID.VOID_KNIGHT_ROBE, 45000), + VOID_KNIGHT_GLOVES(ItemID.VOID_KNIGHT_GLOVES, 30000), + ELITE_VOID_TOP(ItemID.ELITE_VOID_TOP, 50000), + ELITE_VOID_ROBE(ItemID.ELITE_VOID_ROBE, 50000), // Barb Assault - FIGHTER_HAT(ItemID.FIGHTER_HAT), - RANGER_HAT(ItemID.RANGER_HAT), - HEALER_HAT(ItemID.HEALER_HAT), - FIGHTER_TORSO(ItemID.FIGHTER_TORSO), - PENANCE_SKIRT(ItemID.PENANCE_SKIRT), + FIGHTER_HAT(ItemID.FIGHTER_HAT, 45000), + RANGER_HAT(ItemID.RANGER_HAT, 45000), + HEALER_HAT(ItemID.HEALER_HAT, 45000), + FIGHTER_TORSO(ItemID.FIGHTER_TORSO, 50000), + PENANCE_SKIRT(ItemID.PENANCE_SKIRT, 20000), // Castle Wars - SARADOMIN_HALO(ItemID.SARADOMIN_HALO), - ZAMORAK_HALO(ItemID.ZAMORAK_HALO), - GUTHIX_HALO(ItemID.GUTHIX_HALO), - DECORATIVE_MAGIC_HAT(ItemID.DECORATIVE_ARMOUR_11898), - DECORATIVE_MAGIC_ROBE_TOP(ItemID.DECORATIVE_ARMOUR_11896), - DECORATIVE_MAGIC_ROBE_LEGS(ItemID.DECORATIVE_ARMOUR_11897), - DECORATIVE_RANGE_TOP(ItemID.DECORATIVE_ARMOUR_11899), - DECORATIVE_RANGE_BOTTOM(ItemID.DECORATIVE_ARMOUR_11900), - DECORATIVE_RANGE_QUIVER(ItemID.DECORATIVE_ARMOUR_11901), - GOLD_DECORATIVE_HELM(ItemID.DECORATIVE_HELM_4511), - GOLD_DECORATIVE_BODY(ItemID.DECORATIVE_ARMOUR_4509), - GOLD_DECORATIVE_LEGS(ItemID.DECORATIVE_ARMOUR_4510), - GOLD_DECORATIVE_SKIRT(ItemID.DECORATIVE_ARMOUR_11895), - GOLD_DECORATIVE_SHIELD(ItemID.DECORATIVE_SHIELD_4512), - GOLD_DECORATIVE_SWORD(ItemID.DECORATIVE_SWORD_4508); + SARADOMIN_HALO(ItemID.SARADOMIN_HALO, 25000), + ZAMORAK_HALO(ItemID.ZAMORAK_HALO, 25000), + GUTHIX_HALO(ItemID.GUTHIX_HALO, 25000), + DECORATIVE_MAGIC_HAT(ItemID.DECORATIVE_ARMOUR_11898, 5000), + DECORATIVE_MAGIC_ROBE_TOP(ItemID.DECORATIVE_ARMOUR_11896, 5000), + DECORATIVE_MAGIC_ROBE_LEGS(ItemID.DECORATIVE_ARMOUR_11897, 5000), + DECORATIVE_RANGE_TOP(ItemID.DECORATIVE_ARMOUR_11899, 5000), + DECORATIVE_RANGE_BOTTOM(ItemID.DECORATIVE_ARMOUR_11900, 5000), + DECORATIVE_RANGE_QUIVER(ItemID.DECORATIVE_ARMOUR_11901, 5000), + GOLD_DECORATIVE_HELM(ItemID.DECORATIVE_HELM_4511, 5000), + GOLD_DECORATIVE_BODY(ItemID.DECORATIVE_ARMOUR_4509, 5000), + GOLD_DECORATIVE_LEGS(ItemID.DECORATIVE_ARMOUR_4510, 5000), + GOLD_DECORATIVE_SKIRT(ItemID.DECORATIVE_ARMOUR_11895, 5000), + GOLD_DECORATIVE_SHIELD(ItemID.DECORATIVE_SHIELD_4512, 5000), + GOLD_DECORATIVE_SWORD(ItemID.DECORATIVE_SWORD_4508, 5000); private final int itemID; + private final int repairPrice; - private static final ImmutableSet ID_SET; + private static final ImmutableMap REPAIR_MAP; static { - final ImmutableSet.Builder set = new ImmutableSet.Builder<>(); + final ImmutableMap.Builder map = new ImmutableMap.Builder<>(); for (final BrokenOnDeathItem p : values()) { - set.add(p.itemID); + map.put(p.itemID, p.repairPrice); } - ID_SET = set.build(); + REPAIR_MAP = map.build(); } - static boolean isBrokenOnDeath(final int itemID) + @Nullable + static Integer getRepairPrice(int itemId) { - return ID_SET.contains(itemID); + return REPAIR_MAP.get(itemId); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPlugin.java index 05089bc898..8a6e1791a7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPlugin.java @@ -338,7 +338,7 @@ public class ItemsKeptOnDeathPlugin extends Plugin if (!Pets.isPet(id) && !LostIfNotProtected.isLostIfNotProtected(id) && !isTradeable(itemManager.getItemComposition(id)) && wildyLevel <= DEEP_WILDY - && (wildyLevel <= 0 || BrokenOnDeathItem.isBrokenOnDeath(i.getId()))) + && (wildyLevel <= 0 || BrokenOnDeathItem.getRepairPrice(i.getId()) != null)) { keptItems.add(new ItemStack(id, qty)); } @@ -442,19 +442,29 @@ public class ItemsKeptOnDeathPlugin extends Plugin // Grab base item price exchangePrice = itemManager.getItemPrice(fixedPrice.getBaseId(), true); } - else + + // Jagex uses the repair price when determining which items are kept on death. + final Integer repairPrice = BrokenOnDeathItem.getRepairPrice(canonicalizedItemId); + if (repairPrice != null) { - // Account for items whose death value comes from their tradeable variant (barrows) or components (ornate kits) - for (final int mappedID : ItemMapping.map(canonicalizedItemId)) - { - exchangePrice += itemManager.getItemPrice(mappedID, true); - } + exchangePrice = repairPrice; } if (exchangePrice == 0) { - final ItemComposition c1 = itemManager.getItemComposition(canonicalizedItemId); - exchangePrice = c1.getPrice(); + // Account for items whose death value comes from their tradeable variant (barrows) or components (ornate kits) + // ItemMapping.map will always return a collection with at least the passed ID + for (final int mappedID : ItemMapping.map(canonicalizedItemId)) + { + exchangePrice += itemManager.getItemPrice(mappedID, true); + } + + // If for some reason it still has no price default to the items store price + if (exchangePrice == 0) + { + final ItemComposition c1 = itemManager.getItemComposition(canonicalizedItemId); + exchangePrice = c1.getPrice(); + } } // Apply fixed price offset diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPluginTest.java index 37e8a7d99d..ed697b3b74 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/itemskeptondeath/ItemsKeptOnDeathPluginTest.java @@ -613,4 +613,24 @@ public class ItemsKeptOnDeathPluginTest final List kept = deathItems.getKeptItems(); assertTrue(kept.contains(new ItemStack(ItemID.SHADOW_SWORD, 1))); } + + @Test + public void brokenOnDeathTestRepairPrice() + { + // Dragon defender price should actually be pulled from BrokenOnDeathItem, and be lost on death + final Item[] inv = new Item[] + { + mItem(ItemID.BARROWS_GLOVES, 1, "Barrows gloves", false, 130000), + mItem(ItemID.DRAGON_DEFENDER, 1, "Dragon defender", false, 68007), + mItem(ItemID.DRAGON_SCIMITAR, 1, "Dragon scimitar", true, 63123), + mItem(ItemID.HELM_OF_NEITIZNOT, 1, "Helm of neitiznot", true, 45519), + }; + + plugin.wildyLevel = 21; + + final DeathItems deathItems = plugin.calculateKeptLostItems(inv, new Item[0]); + + final List lost = deathItems.getLostItems(); + assertTrue(lost.contains(new ItemStack(ItemID.DRAGON_DEFENDER, 1))); + } }