Fix BrokenOnDeathItems death value by adding repair price

Jagex uses the repair price when determing items lost on death by value. adds test for this case as well
This commit is contained in:
TheStonedTurtle
2019-07-21 12:03:33 -07:00
parent 44cf040cac
commit 742133e456
3 changed files with 92 additions and 60 deletions

View File

@@ -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<Integer> ID_SET;
private static final ImmutableMap<Integer, Integer> REPAIR_MAP;
static
{
final ImmutableSet.Builder<Integer> set = new ImmutableSet.Builder<>();
final ImmutableMap.Builder<Integer, Integer> 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);
}
}

View File

@@ -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

View File

@@ -613,4 +613,24 @@ public class ItemsKeptOnDeathPluginTest
final List<ItemStack> 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<ItemStack> lost = deathItems.getLostItems();
assertTrue(lost.contains(new ItemStack(ItemID.DRAGON_DEFENDER, 1)));
}
}