From e643ad5cae4039db4cd5aefafe4091fb876f0c64 Mon Sep 17 00:00:00 2001 From: Collin Smith Date: Fri, 22 Mar 2019 23:27:39 -0700 Subject: [PATCH] Rewrote stat format strings Rewrote stat format strings (should be correct) Rewrote item details builder Changed stat impl to use a map for item inherent stats Added inherent stats header Added ethereal/socket footer Added potion right click description Added placeholders for many item inherent stats --- core/src/com/riiablo/codec/excel/Misc.java | 6 +- core/src/com/riiablo/item/Item.java | 110 +++++++- core/src/com/riiablo/item/Stat.java | 290 +++++++++++++++++---- 3 files changed, 345 insertions(+), 61 deletions(-) diff --git a/core/src/com/riiablo/codec/excel/Misc.java b/core/src/com/riiablo/codec/excel/Misc.java index 2f4af959..0522d96a 100644 --- a/core/src/com/riiablo/codec/excel/Misc.java +++ b/core/src/com/riiablo/codec/excel/Misc.java @@ -1,10 +1,8 @@ package com.riiablo.codec.excel; -import com.riiablo.codec.excel.Excel; -import com.riiablo.codec.excel.ItemEntry; - public class Misc extends Excel { public static class Entry extends ItemEntry { - + @Column public int spelldesc; + @Column public String spelldescstr; } } diff --git a/core/src/com/riiablo/item/Item.java b/core/src/com/riiablo/item/Item.java index a563a76e..24ccfaf3 100644 --- a/core/src/com/riiablo/item/Item.java +++ b/core/src/com/riiablo/item/Item.java @@ -1,5 +1,6 @@ package com.riiablo.item; +import com.badlogic.gdx.Gdx; import com.badlogic.gdx.assets.AssetDescriptor; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.BitmapFont; @@ -12,13 +13,16 @@ import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.GdxRuntimeException; import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.IntSet; +import com.badlogic.gdx.utils.ObjectMap; import com.riiablo.Riiablo; import com.riiablo.codec.DC6; import com.riiablo.codec.Index; +import com.riiablo.codec.StringTBL; import com.riiablo.codec.excel.Inventory; import com.riiablo.codec.excel.ItemEntry; import com.riiablo.codec.excel.ItemTypes; import com.riiablo.codec.excel.MagicAffix; +import com.riiablo.codec.excel.Misc; import com.riiablo.codec.excel.SetItems; import com.riiablo.codec.excel.UniqueItems; import com.riiablo.codec.util.BBox; @@ -32,6 +36,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import java.util.Arrays; import java.util.Comparator; +import java.util.EnumMap; import static com.riiablo.item.Quality.SET; @@ -63,6 +68,33 @@ public class Item extends Actor implements Disposable { private static final Array[] EMPTY_STAT_ARRAY = (Array[]) new Array[0]; + private static final ObjectMap WEAPON_DESC = new ObjectMap<>(); + static { + WEAPON_DESC.put("mace", "WeaponDescMace"); + WEAPON_DESC.put("club", "WeaponDescMace"); + WEAPON_DESC.put("hamm", "WeaponDescMace"); + WEAPON_DESC.put("scep", "WeaponDescMace"); + WEAPON_DESC.put("axe", "WeaponDescAxe"); + WEAPON_DESC.put("taxe", "WeaponDescAxe"); + WEAPON_DESC.put("swor", "WeaponDescSword"); + WEAPON_DESC.put("knif", "WeaponDescDagger"); + WEAPON_DESC.put("tkni", "WeaponDescDagger"); + WEAPON_DESC.put("tpot", "WeaponDescThrownPotion"); + WEAPON_DESC.put("jave", "WeaponDescJavelin"); + WEAPON_DESC.put("ajav", "WeaponDescJavelin"); + WEAPON_DESC.put("spea", "WeaponDescSpear"); + WEAPON_DESC.put("aspe", "WeaponDescSpear"); + WEAPON_DESC.put("bow", "WeaponDescBow"); + WEAPON_DESC.put("abow", "WeaponDescBow"); + WEAPON_DESC.put("staf", "WeaponDescStaff"); + WEAPON_DESC.put("pole", "WeaponDescPoleArm"); + WEAPON_DESC.put("xbow", "WeaponDescCrossBow"); + WEAPON_DESC.put("h2h", "WeaponDescH2H"); + WEAPON_DESC.put("h2h2", "WeaponDescH2H"); + WEAPON_DESC.put("wand", "WeaponDescOrb"); + WEAPON_DESC.put("orb", "WeaponDescOrb"); + } + public int flags; public int version; // 0 = pre-1.08; 1 = 1.08/1.09 normal; 2 = 1.10 normal; 100 = 1.08/1.09 expansion; 101 = 1.10 expansion public Location location; @@ -86,6 +118,7 @@ public class Item extends Actor implements Disposable { public int runewordData; public String inscription; + public EnumMap props; public Array stats[]; public ItemEntry base; @@ -147,6 +180,9 @@ public class Item extends Actor implements Disposable { base = findBase(typeCode); type = Riiablo.files.ItemTypes.get(base.type); + props = new EnumMap<>(Stat.class); + // TODO: copy base items stats + if ((flags & COMPACT) == COMPACT) { id = 0; level = 0; @@ -208,22 +244,20 @@ public class Item extends Actor implements Disposable { bitStream.skip(1); // TODO: Unknown, this usually is 0, but is 1 on a Tome of Identify. (It's still 0 on a Tome of Townportal.) - stats = (Array[]) new Array[7]; - stats[0] = new Array<>(Stat.Instance.class); if (type.is("armo")) { - stats[0].add(Stat.armorclass.read(bitStream)); + props.put(Stat.armorclass, Stat.armorclass.read(bitStream)); } if (type.is("armo") || type.is("weap")) { Stat.Instance maxdurability = Stat.maxdurability.read(bitStream); - stats[0].add(maxdurability); + props.put(Stat.maxdurability, maxdurability); if (maxdurability.value > 0) { - stats[0].add(Stat.durability.read(bitStream)); + props.put(Stat.durability, Stat.durability.read(bitStream)); } } if ((flags & SOCKETED) == SOCKETED && (type.is("armo") || type.is("weap"))) { - stats[0].add(Stat.item_numsockets.read(bitStream)); + props.put(Stat.item_numsockets, Stat.item_numsockets.read(bitStream)); } if (type.is("book")) { @@ -232,7 +266,7 @@ public class Item extends Actor implements Disposable { if (base.stackable) { int quantity = bitStream.readUnsigned15OrLess(9); - stats[0].add(new Stat.Instance(Stat.quantity, quantity, 0)); + props.put(Stat.quantity, new Stat.Instance(Stat.quantity, quantity, 0)); } if (quality == SET) { @@ -244,9 +278,10 @@ public class Item extends Actor implements Disposable { listsFlags = 0; } + stats = (Array[]) new Array[7]; for (int i = 0; i < 7; i++) { if (((listsFlags >> i) & 1) == 1) { - if (i > 0) stats[i] = new Array<>(Stat.Instance.class); + stats[i] = new Array<>(Stat.Instance.class); Array stats = this.stats[i]; for (;;) { int prop = bitStream.readUnsigned15OrLess(9); @@ -786,6 +821,13 @@ public class Item extends Actor implements Disposable { string = Riiablo.string.lookup("RightClicktoOpen"); } else if (base.code.equalsIgnoreCase("bkd")) { string = Riiablo.string.lookup("RightClicktoRead"); + } else if (base instanceof Misc.Entry) { + Misc.Entry misc = (Misc.Entry) base; + if (misc.spelldesc > 0) { + string = Riiablo.string.lookup(misc.spelldescstr); + } else { + string = Riiablo.string.lookup("RightClicktoUse"); + } } else { string = Riiablo.string.lookup("RightClicktoUse"); } @@ -794,6 +836,33 @@ public class Item extends Actor implements Disposable { add(usable).center().space(SPACING).row(); } + if ((flags & COMPACT) == 0) { + Stat.Instance stat; + EnumMap stats = Item.this.props; + if ((stat = stats.get(Stat.armorclass)) != null) + add(new Label(Riiablo.string.lookup("ItemStats1h") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row(); + if ((stat = stats.get(Stat.maxdamage)) != null) // TODO: Conditional 2 handed if barbarian, etc + add(new Label(Riiablo.string.lookup("ItemStats1l") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row(); + if (Item.this.type.is("shie")) { + add(new Label(Riiablo.string.lookup("ItemStats1r") + " " + 0, font, Riiablo.colors.white)).center().space(SPACING).row(); + // TODO: if paladin, show smite damage -- ItemStats1o %d to %d + } + if ((stat = stats.get(Stat.durability)) != null) + add(new Label(Riiablo.string.lookup("ItemStats1d") + " " + stat.value + " " + Riiablo.string.lookup("ItemStats1j") + " " + stats.get(Stat.maxdurability).value, font, Riiablo.colors.white)).center().space(SPACING).row(); + add(new Label(Riiablo.string.lookup("ItemStats1f") + " " + 0, font, Riiablo.colors.white)).center().space(SPACING).row(); + add(new Label(Riiablo.string.lookup("ItemStats1e") + " " + 0, font, Riiablo.colors.white)).center().space(SPACING).row(); + add(new Label(Riiablo.string.lookup("ItemStats1p") + " " + 0, font, Riiablo.colors.white)).center().space(SPACING).row(); + if (Item.this.type.is("weap")) { + add(new Label(Riiablo.string.lookup(WEAPON_DESC.get(Item.this.base.type)) + " - " + 0, font, Riiablo.colors.white)).center().space(SPACING).row(); + } + + //for (Stat.Instance stat : stats.values()) { + // add(new Label(stat.stat.toString(), font, Riiablo.colors.white)).center().space(SPACING).row(); + //} + } + + // TODO: Detect stats with encoded groupings and auto join them into a grouped stat + for (int i = 0; i < stats.length; i++) { Array stats = Item.this.stats[i]; if (stats == null) continue; @@ -835,7 +904,7 @@ public class Item extends Actor implements Disposable { stats.sort(new Comparator() { @Override public int compare(Stat.Instance o1, Stat.Instance o2) { - return o1.stat.entry().descpriority - o2.stat.entry().descpriority; + return o2.stat.entry().descpriority - o1.stat.entry().descpriority; } }); @@ -853,11 +922,32 @@ public class Item extends Actor implements Disposable { } } - label = new Label(stat.format(group), font); + String text = stat.format(group); + if (text == null) continue; + label = new Label(text, font, Riiablo.colors.blue); // Conditionally, set should be green add(label).center().space(SPACING).row(); } } + StringBuilder itemFlags = null; + if ((Item.this.flags & ETHEREAL) == ETHEREAL) { + itemFlags = new StringBuilder(32); + itemFlags.append(Riiablo.string.lookup(StringTBL.EXPANSION_OFFSET + 2745)); + } + if ((Item.this.flags & SOCKETED) == SOCKETED) { + if (itemFlags != null) itemFlags.append(',').append(' '); + else itemFlags = new StringBuilder(16); + Stat.Instance stat = props.get(Stat.item_numsockets); + if (stat != null) { + itemFlags.append(Riiablo.string.lookup("Socketable")).append(' ').append('(').append(stat.value).append(')'); + } else { + Gdx.app.error(TAG, "Item marked socketed, but missing item_numsockets: " + Item.this.getName()); + } + } + if (itemFlags != null) { + add(new Label(itemFlags.toString(), font, Riiablo.colors.blue)).center().space(SPACING).row(); + } + // TODO: This can be cleaned up later -- add support for set detection if (quality == SET) { add().height(font.getLineHeight()).space(SPACING).row(); diff --git a/core/src/com/riiablo/item/Stat.java b/core/src/com/riiablo/item/Stat.java index b0a5eb35..61849512 100644 --- a/core/src/com/riiablo/item/Stat.java +++ b/core/src/com/riiablo/item/Stat.java @@ -386,6 +386,10 @@ public enum Stat { 1, 1, 1, 1, 1, 1, 1, // 352 }; + private static final String[] BY_TIME = { + "ModStre9e", "ModStre9g", "ModStre9d", "ModStre9f", + }; + private final ItemStatCost.Entry entry; Stat() { @@ -424,76 +428,268 @@ public enum Stat { this.param = param; } + private static final StringBuilder builder = new StringBuilder(32); + private static final CharSequence SPACE = Riiablo.string.lookup("space"); + private static final CharSequence DASH = Riiablo.string.lookup("dash"); + private static final CharSequence PERCENT = Riiablo.string.lookup("percent"); + private static final CharSequence PLUS = Riiablo.string.lookup("plus"); + private static final CharSequence TO = Riiablo.string.lookup("ItemStast1k"); + public String format(boolean group) { + ItemStatCost.Entry entry = stat.entry; + return group + ? format(entry.dgrpfunc, entry.dgrpval, entry.dgrpstrpos, entry.dgrpstrneg, entry.dgrpstr2) + : format(entry.descfunc, entry.descval, entry.descstrpos, entry.descstrneg, entry.descstr2); + } + + public String format(int func, int valmode, String strpos, String strneg, String str2) { + int value; CharStats.Entry entry; Skills.Entry skill; SkillDesc.Entry desc; - switch (group ? stat.entry.dgrpfunc : stat.entry.descfunc) { - case 1: return String.format("+%d %s", value, descstr(group)); - case 2: return String.format("%d%% %s", value, descstr()); - case 3: return String.format("%d %s", value, descstr()); - case 4: return String.format("+%d%% %s", value, descstr()); - case 5: return String.format("%d%% %s", value * 100 / 128, descstr()); // TODO: item_howl -- verify - case 6: return String.format("+%d %s %s", value, descstr(), descstr2()); - case 7: return String.format("%d%% %s %s", value, descstr(), descstr2()); - case 8: return String.format("+%d%% %s %s", value, descstr(), descstr2()); - case 9: return String.format("%d %s %s", value, descstr(), descstr2()); - case 11: return Riiablo.string.format("ModStre9u", 1, value / 100); - case 12: return String.format("+%d %s", value, descstr()); - case 13: return String.format("+%d %s", value, Riiablo.string.lookup(CharacterClass.get(param).entry().StrAllSkills)); - case 14: + builder.setLength(0); + switch (func) { + case 1: // +%d %s1 + value = this.value; + if (valmode == 1) builder.append(PLUS).append(value).append(SPACE); + builder.append(Riiablo.string.lookup(value < 0 ? strneg : strpos)); + if (valmode == 2) builder.append(SPACE).append(PLUS).append(value); + return builder.toString(); + case 2: // %d%% %s1 + value = this.value; + if (valmode == 1) builder.append(value).append(PERCENT).append(SPACE); + builder.append(Riiablo.string.lookup(value < 0 ? strneg : strpos)); + if (valmode == 2) builder.append(SPACE).append(value).append(PERCENT); + return builder.toString(); + case 3: // %d %s1 + value = this.value; + if (valmode == 1) builder.append(value).append(SPACE); + builder.append(Riiablo.string.lookup(value < 0 ? strneg : strpos)); + if (valmode == 2) builder.append(SPACE).append(value); + return builder.toString(); + case 4: // +%d%% %s1 + value = this.value; + if (valmode == 1) builder.append(PLUS).append(value).append(PERCENT).append(SPACE); + builder.append(Riiablo.string.lookup(value < 0 ? strneg : strpos)); + if (valmode == 2) builder.append(SPACE).append(PLUS).append(value).append(PERCENT); + return builder.toString(); + case 5: // %d%% %s1 + value = this.value * 100 / 128; + if (valmode == 1) builder.append(value).append(PERCENT).append(SPACE); + builder.append(Riiablo.string.lookup(value < 0 ? strneg : strpos)); + if (valmode == 2) builder.append(SPACE).append(value).append(PERCENT); + return builder.toString(); + case 6: // +%d %s1 %s2 + value = this.value; + if (valmode == 1) builder.append(PLUS).append(value).append(SPACE); + builder + .append(Riiablo.string.lookup(value < 0 ? strneg : strpos)) + .append(SPACE) + .append(Riiablo.string.lookup(str2)); + if (valmode == 2) builder.append(SPACE).append(PLUS).append(value); + return builder.toString(); + case 7: // %d%% %s1 %s2 + value = this.value; + if (valmode == 1) builder.append(value).append(PERCENT).append(SPACE); + builder + .append(Riiablo.string.lookup(value < 0 ? strneg : strpos)) + .append(SPACE) + .append(Riiablo.string.lookup(str2)); + if (valmode == 2) builder.append(SPACE).append(value).append(PERCENT); + return builder.toString(); + case 8: // +%d%% %s1 %s2 + value = this.value; + if (valmode == 1) builder.append(PLUS).append(value).append(PERCENT).append(SPACE); + builder + .append(Riiablo.string.lookup(value < 0 ? strneg : strpos)) + .append(SPACE) + .append(Riiablo.string.lookup(str2)); + if (valmode == 2) builder.append(SPACE).append(PLUS).append(value).append(PERCENT); + return builder.toString(); + case 9: // %d %s1 %s2 + value = this.value; + if (valmode == 1) builder.append(value).append(SPACE); + builder + .append(Riiablo.string.lookup(value < 0 ? strneg : strpos)) + .append(SPACE) + .append(Riiablo.string.lookup(str2)); + if (valmode == 2) builder.append(SPACE).append(value); + return builder.toString(); + case 10: // %d%% %s1 %s2 + value = this.value * 100 / 128; + if (valmode == 1) builder.append(value).append(PERCENT).append(SPACE); + builder + .append(Riiablo.string.lookup(value < 0 ? strneg : strpos)) + .append(SPACE) + .append(Riiablo.string.lookup(str2)); + if (valmode == 2) builder.append(SPACE).append(value).append(PERCENT); + return builder.toString(); + case 11: // Repairs 1 Durability in %d Seconds + value = 100 / this.value; + return Riiablo.string.format("ModStre9u", 1, value); + case 12: // +%d %s1 + value = this.value; + if (valmode == 1) builder.append(PLUS).append(value).append(SPACE); + builder.append(Riiablo.string.lookup(value < 0 ? strneg : strpos)); + if (valmode == 2) builder.append(SPACE).append(PLUS).append(value); + return builder.toString(); + case 13: // +%d %s | +1 to Paladin Skills + value = this.value; + builder + .append(PLUS).append(value) + .append(SPACE) + .append(CharacterClass.get(param).entry().StrAllSkills); + return builder.toString(); + case 14: // %s %s | +1 to Fire Skills (Sorceress Only) + value = this.value; entry = CharacterClass.get((param >>> 3) & 0x3).entry(); - return String.format("%s %s", Riiablo.string.format(entry.StrSkillTab[param & 0x7], value), Riiablo.string.lookup(entry.StrClassOnly)); - case 15: - int e2p1 = (param >>> 6) & 0x3FF; - int e2p2 = param & 0x3F; - int e2p3 = value; - skill = Riiablo.files.skills.get(e2p1); + builder + .append(Riiablo.string.format(entry.StrSkillTab[param & 0x7], value)) + .append(SPACE) + .append(Riiablo.string.lookup(entry.StrClassOnly)); + return builder.toString(); + case 15: // 15% chance to cast Level 5 Life Tap on Striking + value = this.value; + skill = Riiablo.files.skills.get(param2()); desc = Riiablo.files.skilldesc.get(skill.skilldesc); - return Riiablo.string.format(stat.entry.descstrpos, e2p3, e2p2, Riiablo.string.lookup(desc.str_name)); - case 16: + return Riiablo.string.format(strpos, value, param1(), Riiablo.string.lookup(desc.str_name)); + case 16: // Level 16 Defiance Aura When Equipped + value = this.value; skill = Riiablo.files.skills.get(param); desc = Riiablo.files.skilldesc.get(skill.skilldesc); - return Riiablo.string.format(stat.entry.descstrpos, value, Riiablo.string.lookup(desc.str_name)); - case 19: return String.format(descstr(group), value); - case 20: return String.format("%d%% %s", -value, descstr()); - case 22: return toString(); - case 23: return toString(); + return Riiablo.string.format(strpos, value, Riiablo.string.lookup(desc.str_name)); + case 17: // +10 to Dexterity (Increases Near Dawn) // TODO: untested + // value needs to update based on time of day + if (valmode == 1) builder.append(PLUS).append(value3()).append(SPACE); + builder.append(Riiablo.string.lookup(strpos)); + if (valmode == 2) builder.append(SPACE).append(PLUS).append(value3()); + builder.append(SPACE).append(Riiablo.string.lookup(BY_TIME[value1()])); + return builder.toString(); + case 18: // 50% Enhanced Defense (Increases Near Dawn) // TODO: untested + // value needs to update based on time of day + if (valmode == 1) builder.append(value3()).append(PERCENT).append(SPACE); + builder.append(Riiablo.string.lookup(strpos)); + if (valmode == 2) builder.append(SPACE).append(value3()).append(PERCENT); + builder.append(SPACE).append(Riiablo.string.lookup(BY_TIME[value1()])); + return builder.toString(); + case 19: // Formats strpos/strneg with value + value = this.value; + return Riiablo.string.format(value < 0 ? strneg : strpos, value); + case 20: // -%d%% %s1 + value = -this.value; + if (valmode == 1) builder.append(value).append(PERCENT).append(SPACE); + builder.append(Riiablo.string.lookup(value < 0 ? strneg : strpos)); + if (valmode == 2) builder.append(SPACE).append(value).append(PERCENT); + return builder.toString(); + case 21: // -%d %s1 + value = -this.value; + if (valmode == 1) builder.append(value).append(SPACE); + builder.append(Riiablo.string.lookup(value < 0 ? strneg : strpos)); + if (valmode == 2) builder.append(SPACE).append(value); + return builder.toString(); + case 22: // +%d%% %s1 %s | +3% Attack Rating Versus: %s // TODO: unsupported for now + return "ERROR 22"; + case 23: // %d%% %s1 %s | 3% ReanimateAs: %s // TODO: unsupported for now + return "ERROR 23"; case 24: - int e3p1 = (param >>> 6) & 0x3FF; - int e3p2 = param & 0x3F; - int e3p3 = (value >>> 8) & 0xFF; - int e3p4 = value & 0xFF; - skill = Riiablo.files.skills.get(e3p1); + skill = Riiablo.files.skills.get(param2()); desc = Riiablo.files.skilldesc.get(skill.skilldesc); - return String.format("%s %d %s %s", Riiablo.string.lookup("ModStre10b"), e3p2, Riiablo.string.lookup(desc.str_name), Riiablo.string.format(stat.entry.descstrpos, e3p3, e3p4)); - case 27: + builder + .append(Riiablo.string.lookup("ModStre10b")).append(SPACE) + .append(param1()).append(SPACE) + .append(Riiablo.string.lookup(desc.str_name)).append(SPACE) + .append(Riiablo.string.format(stat.entry.descstrpos, value1(), value2())); + return builder.toString(); + case 25: // TODO: unsupported + return "ERROR 25"; + case 26: // TODO: unsupported + return "ERROR 26"; + case 27: // +1 to Lightning (Sorceress Only) + value = this.value; skill = Riiablo.files.skills.get(param); desc = Riiablo.files.skilldesc.get(skill.skilldesc); entry = Riiablo.files.skills.getClass(skill.charclass).entry(); - return String.format("+%d %s %s %s", value, Riiablo.string.lookup("ItemStast1k"), Riiablo.string.lookup(desc.str_name), Riiablo.string.lookup(entry.StrClassOnly)); - case 28: + builder + .append(PLUS).append(value).append(SPACE) + .append(TO).append(SPACE) + .append(Riiablo.string.lookup(desc.str_name)).append(SPACE) + .append(Riiablo.string.lookup(entry.StrClassOnly)); + return builder.toString(); + case 28: // +1 to Teleport + value = this.value; skill = Riiablo.files.skills.get(param); desc = Riiablo.files.skilldesc.get(skill.skilldesc); - return String.format("+%d %s %s", value, Riiablo.string.lookup("ItemStast1k"), Riiablo.string.lookup(desc.str_name)); - default: return toString(); + builder + .append(PLUS).append(value).append(SPACE) + .append(TO).append(SPACE) + .append(Riiablo.string.lookup(desc.str_name)); + return builder.toString(); + default: + return null; } } - private String descstr() { - return Riiablo.string.lookup(value < 0 ? stat.entry.descstrneg : stat.entry.descstrpos); + public int value() { + return value1(); } - private String descstr(boolean group) { - if (group) { - return Riiablo.string.lookup(value < 0 ? stat.entry.dgrpstrneg : stat.entry.dgrpstrpos); - } else { - return Riiablo.string.lookup(value < 0 ? stat.entry.descstrneg : stat.entry.descstrpos); + public int param() { + return param1(); + } + + public int value1() { + switch (stat.entry.Encode) { + case 0: return value; + case 1: return value; + case 2: return value; + case 3: return value & 0xFF; + case 4: return value & 0x3; + default: return value; } } - private String descstr2() { - return Riiablo.string.lookup(stat.entry.descstr2); + public int value2() { + switch (stat.entry.Encode) { + case 0: return 0; + case 1: return 0; + case 2: return 0; + case 3: return (value >>> 8) & 0xFF; + case 4: return (value >>> 2) & 0x3FF; + default: return 0; + } + } + + public int value3() { + switch (stat.entry.Encode) { + case 0: return 0; + case 1: return 0; + case 2: return 0; + case 3: return 0; + case 4: return (value >>> 12) & 0x3FF; + default: return 0; + } + } + + public int param1() { + switch (stat.entry.Encode) { + case 0: return param; + case 1: return param; + case 2: return param & 0x3F; + case 3: return param & 0x3F; + case 4: return param; + default: return param; + } + } + + public int param2() { + switch (stat.entry.Encode) { + case 0: return 0; + case 1: return 0; + case 2: return (param >>> 6) & 0x3FF; + case 3: return (param >>> 6) & 0x3FF; + case 4: return 0; + default: return 0; + } } @Override