First iteration improvement for #24

This commit is contained in:
Collin Smith
2019-03-26 15:29:21 -07:00
parent 0ae8cddf60
commit 2a362cf64a
3 changed files with 500 additions and 469 deletions

View File

@ -5,9 +5,7 @@ import com.badlogic.gdx.assets.AssetDescriptor;
import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.GdxRuntimeException; import com.badlogic.gdx.utils.GdxRuntimeException;
@ -39,7 +37,6 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.EnumMap;
import static com.riiablo.item.Quality.SET; import static com.riiablo.item.Quality.SET;
@ -69,7 +66,7 @@ public class Item extends Actor implements Disposable {
private static final int INSCRIBED = 0x01000000; private static final int INSCRIBED = 0x01000000;
private static final int RUNEWORD = 0x04000000; private static final int RUNEWORD = 0x04000000;
private static final Array<Stat.Instance>[] EMPTY_STAT_ARRAY = (Array<Stat.Instance>[]) new Array[0]; private static final PropertyList[] EMPTY_STAT_ARRAY = new PropertyList[0];
private static final ObjectMap<String, String> WEAPON_DESC = new ObjectMap<>(); private static final ObjectMap<String, String> WEAPON_DESC = new ObjectMap<>();
static { static {
@ -121,8 +118,8 @@ public class Item extends Actor implements Disposable {
public int runewordData; public int runewordData;
public String inscription; public String inscription;
public EnumMap<Stat, Stat.Instance> props; public PropertyList props;
public Array<Stat.Instance> stats[]; public PropertyList stats[];
public ItemEntry base; public ItemEntry base;
public ItemTypes.Entry type; public ItemTypes.Entry type;
@ -141,21 +138,7 @@ public class Item extends Actor implements Disposable {
return new Item().read(bitStream); return new Item().read(bitStream);
} }
private Item() { Item() {}
addListener(new ClickListener() {
@Override
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
super.enter(event, x, y, pointer, fromActor);
if (isOver()) System.out.println("OVER");
}
@Override
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
super.exit(event, x, y, pointer, toActor);
if (!isOver()) System.out.println("!OVER");
}
});
}
private Item read(BitStream bitStream) { private Item read(BitStream bitStream) {
flags = bitStream.read32BitsOrLess(Integer.SIZE); flags = bitStream.read32BitsOrLess(Integer.SIZE);
@ -183,24 +166,25 @@ public class Item extends Actor implements Disposable {
base = findBase(typeCode); base = findBase(typeCode);
type = Riiablo.files.ItemTypes.get(base.type); type = Riiablo.files.ItemTypes.get(base.type);
props = new EnumMap<>(Stat.class); props = new PropertyList();
props.put(Stat.item_levelreq, new Stat.Instance(Stat.item_levelreq, base.levelreq, 0)); props.put(Stat.item_levelreq, base.levelreq);
if (base instanceof Weapons.Entry) { if (base instanceof Weapons.Entry) {
Weapons.Entry weapon = getBase(); Weapons.Entry weapon = getBase();
props.put(Stat.mindamage, new Stat.Instance(Stat.mindamage, weapon.mindam, 0)); props.put(Stat.mindamage, weapon.mindam);
props.put(Stat.maxdamage, new Stat.Instance(Stat.maxdamage, weapon.maxdam, 0)); props.put(Stat.maxdamage, weapon.maxdam);
props.put(Stat.secondary_mindamage, new Stat.Instance(Stat.secondary_mindamage, weapon._2handmindam, 0)); props.put(Stat.secondary_mindamage, weapon._2handmindam);
props.put(Stat.secondary_maxdamage, new Stat.Instance(Stat.secondary_maxdamage, weapon._2handmaxdam, 0)); props.put(Stat.secondary_maxdamage, weapon._2handmaxdam);
props.put(Stat.item_throw_mindamage, new Stat.Instance(Stat.item_throw_mindamage, weapon.minmisdam, 0)); props.put(Stat.item_throw_mindamage, weapon.minmisdam);
props.put(Stat.item_throw_maxdamage, new Stat.Instance(Stat.item_throw_maxdamage, weapon.maxmisdam, 0)); props.put(Stat.item_throw_maxdamage, weapon.maxmisdam);
props.put(Stat.strength, new Stat.Instance(Stat.strength, weapon.reqstr, 0)); props.put(Stat.reqstr, weapon.reqstr);
props.put(Stat.dexterity, new Stat.Instance(Stat.dexterity, weapon.reqdex, 0)); props.put(Stat.reqdex, weapon.reqdex);
} else if (base instanceof Armor.Entry) { } else if (base instanceof Armor.Entry) {
Armor.Entry armor = getBase(); Armor.Entry armor = getBase();
props.put(Stat.strength, new Stat.Instance(Stat.strength, armor.reqstr, 0)); props.put(Stat.reqstr, armor.reqstr);
props.put(Stat.toblock, new Stat.Instance(Stat.toblock, armor.block, 0)); props.put(Stat.reqdex, 0);
props.put(Stat.mindamage, new Stat.Instance(Stat.mindamage, armor.mindam, 0)); props.put(Stat.toblock, armor.block);
props.put(Stat.maxdamage, new Stat.Instance(Stat.maxdamage, armor.maxdam, 0)); props.put(Stat.mindamage, armor.mindam);
props.put(Stat.maxdamage, armor.maxdam);
} }
// TODO: copy base items stats // TODO: copy base items stats
@ -266,19 +250,18 @@ 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.) 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.)
if (type.is("armo")) { if (type.is("armo")) {
props.put(Stat.armorclass, Stat.armorclass.read(bitStream)); props.read(Stat.armorclass, bitStream);
} }
if (type.is("armo") || type.is("weap")) { if (type.is("armo") || type.is("weap")) {
Stat.Instance maxdurability = Stat.maxdurability.read(bitStream); int maxdurability = props.read(Stat.maxdurability, bitStream);
props.put(Stat.maxdurability, maxdurability); if (maxdurability > 0) {
if (maxdurability.value > 0) { props.read(Stat.durability, bitStream);
props.put(Stat.durability, Stat.durability.read(bitStream));
} }
} }
if ((flags & SOCKETED) == SOCKETED && (type.is("armo") || type.is("weap"))) { if ((flags & SOCKETED) == SOCKETED && (type.is("armo") || type.is("weap"))) {
props.put(Stat.item_numsockets, Stat.item_numsockets.read(bitStream)); props.read(Stat.item_numsockets, bitStream);
} }
if (type.is("book")) { if (type.is("book")) {
@ -287,7 +270,7 @@ public class Item extends Actor implements Disposable {
if (base.stackable) { if (base.stackable) {
int quantity = bitStream.readUnsigned15OrLess(9); int quantity = bitStream.readUnsigned15OrLess(9);
props.put(Stat.quantity, new Stat.Instance(Stat.quantity, quantity, 0)); props.put(Stat.quantity, quantity);
} }
if (quality == SET) { if (quality == SET) {
@ -299,19 +282,10 @@ public class Item extends Actor implements Disposable {
listsFlags = 0; listsFlags = 0;
} }
stats = (Array<Stat.Instance>[]) new Array[7]; stats = new PropertyList[7];
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
if (((listsFlags >> i) & 1) == 1) { if (((listsFlags >> i) & 1) == 1) {
stats[i] = new Array<>(Stat.Instance.class); stats[i] = new PropertyList().read(bitStream);
Array<Stat.Instance> stats = this.stats[i];
for (;;) {
int prop = bitStream.readUnsigned15OrLess(9);
if (prop == 0x1ff) break;
for (int j = 0, size = Stat.getStatCount(prop); j < size; j++) {
Stat stat = Stat.valueOf(prop + j);
stats.add(stat.read(bitStream));
}
}
} }
} }
@ -875,7 +849,7 @@ public class Item extends Actor implements Disposable {
if ((flags & COMPACT) == 0) { if ((flags & COMPACT) == 0) {
Stat.Instance stat; Stat.Instance stat;
EnumMap<Stat, Stat.Instance> stats = Item.this.props; PropertyList stats = Item.this.props;
if ((stat = stats.get(Stat.armorclass)) != null) if ((stat = stats.get(Stat.armorclass)) != null)
add(new Label(Riiablo.string.lookup("ItemStats1h") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row(); add(new Label(Riiablo.string.lookup("ItemStats1h") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row();
if (Item.this.type.is("weap")) { if (Item.this.type.is("weap")) {
@ -894,9 +868,9 @@ public class Item extends Actor implements Disposable {
if (Item.this.type.is("clas")) { if (Item.this.type.is("clas")) {
add(new Label(Riiablo.string.lookup(CharacterClass.get(Item.this.type.Class).entry().StrClassOnly), font, Riiablo.colors.white)).center().space(SPACING).row(); add(new Label(Riiablo.string.lookup(CharacterClass.get(Item.this.type.Class).entry().StrClassOnly), font, Riiablo.colors.white)).center().space(SPACING).row();
} }
if ((stat = stats.get(Stat.dexterity)) != null && stat.value > 0) if ((stat = stats.get(Stat.reqdex)) != null && stat.value > 0)
add(new Label(Riiablo.string.lookup("ItemStats1f") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row(); add(new Label(Riiablo.string.lookup("ItemStats1f") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row();
if ((stat = stats.get(Stat.strength)) != null && stat.value > 0) if ((stat = stats.get(Stat.reqstr)) != null && stat.value > 0)
add(new Label(Riiablo.string.lookup("ItemStats1e") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row(); add(new Label(Riiablo.string.lookup("ItemStats1e") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row();
if ((stat = stats.get(Stat.item_levelreq)) != null && stat.value > 0) if ((stat = stats.get(Stat.item_levelreq)) != null && stat.value > 0)
add(new Label(Riiablo.string.lookup("ItemStats1p") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row(); add(new Label(Riiablo.string.lookup("ItemStats1p") + " " + stat.value, font, Riiablo.colors.white)).center().space(SPACING).row();
@ -914,13 +888,14 @@ public class Item extends Actor implements Disposable {
// TODO: Detect stats with encoded groupings and auto join them into a grouped stat // TODO: Detect stats with encoded groupings and auto join them into a grouped stat
for (int i = 0; i < stats.length; i++) { for (int i = 0; i < stats.length; i++) {
Array<Stat.Instance> stats = Item.this.stats[i]; PropertyList props = Item.this.stats[i];
if (stats == null) continue; if (props == null) continue;
Array<Stat.Instance> propsArray = props.toArray();
// TODO: This can be cleaned up later // TODO: This can be cleaned up later
IntMap<Array<Stat.Instance>> groups = new IntMap<>(); IntMap<Array<Stat.Instance>> groups = new IntMap<>();
for (Stat.Instance stat : stats) { for (Stat.Instance stat : propsArray) {
int dgrp = stat.stat.entry().dgrp; int dgrp = stat.entry.dgrp;
if (dgrp > 0) { if (dgrp > 0) {
Array<Stat.Instance> group = groups.get(dgrp); Array<Stat.Instance> group = groups.get(dgrp);
if (group == null) groups.put(dgrp, group = new Array<>()); if (group == null) groups.put(dgrp, group = new Array<>());
@ -951,16 +926,16 @@ public class Item extends Actor implements Disposable {
} }
} }
stats.sort(new Comparator<Stat.Instance>() { propsArray.sort(new Comparator<Stat.Instance>() {
@Override @Override
public int compare(Stat.Instance o1, Stat.Instance o2) { public int compare(Stat.Instance o1, Stat.Instance o2) {
return o2.stat.entry().descpriority - o1.stat.entry().descpriority; return o2.entry.descpriority - o1.entry.descpriority;
} }
}); });
for (Stat.Instance stat : stats) { for (Stat.Instance stat : propsArray) {
Label label; Label label;
int dgrp = stat.stat.entry().dgrp; int dgrp = stat.entry.dgrp;
boolean group = false; boolean group = false;
if (dgrp > 0) { if (dgrp > 0) {
if (groupReplaced.contains(dgrp)) continue; if (groupReplaced.contains(dgrp)) continue;

View File

@ -0,0 +1,39 @@
package com.riiablo.item;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap;
import com.riiablo.codec.util.BitStream;
public class PropertyList {
final IntMap<Stat.Instance> props = new IntMap<>();
PropertyList() {}
public void put(int stat, int value) {
props.put(stat, Stat.create(stat, value));
}
public int read(int stat, BitStream bitStream) {
Stat.Instance instance = Stat.read(stat, bitStream);
props.put(instance.hash, instance);
return instance.value;
}
public PropertyList read(BitStream bitStream) {
for (int prop; (prop = bitStream.readUnsigned15OrLess(Stat.BITS)) != Stat.NONE;) {
for (int j = prop, size = j + Stat.getNumEncoded(prop); j < size; j++) {
read(j, bitStream);
}
}
return this;
}
public Stat.Instance get(int stat) {
return props.get(stat);
}
public Array<Stat.Instance> toArray() {
return props.values().toArray();
}
}

View File

@ -8,370 +8,376 @@ import com.riiablo.codec.excel.SkillDesc;
import com.riiablo.codec.excel.Skills; import com.riiablo.codec.excel.Skills;
import com.riiablo.codec.util.BitStream; import com.riiablo.codec.util.BitStream;
public enum Stat { @SuppressWarnings("unused")
strength, public class Stat {
energy, public static final int strength = 0;
dexterity, public static final int energy = 1;
vitality, public static final int dexterity = 2;
statpts, public static final int vitality = 3;
newskills, public static final int statpts = 4;
hitpoints, public static final int newskills = 5;
maxhp, public static final int hitpoints = 6;
mana, public static final int maxhp = 7;
maxmana, public static final int mana = 8;
stamina, public static final int maxmana = 9;
maxstamina, public static final int stamina = 10;
level, public static final int maxstamina = 11;
experience, public static final int level = 12;
gold, public static final int experience = 13;
goldbank, public static final int gold = 14;
item_armor_percent, public static final int goldbank = 15;
item_maxdamage_percent, public static final int item_armor_percent = 16;
item_mindamage_percent, public static final int item_maxdamage_percent = 17;
tohit, public static final int item_mindamage_percent = 18;
toblock, public static final int tohit = 19;
mindamage, public static final int toblock = 20;
maxdamage, public static final int mindamage = 21;
secondary_mindamage, public static final int maxdamage = 22;
secondary_maxdamage, public static final int secondary_mindamage = 23;
damagepercent, public static final int secondary_maxdamage = 24;
manarecovery, public static final int damagepercent = 25;
manarecoverybonus, public static final int manarecovery = 26;
staminarecoverybonus, public static final int manarecoverybonus = 27;
lastexp, public static final int staminarecoverybonus = 28;
nextexp, public static final int lastexp = 29;
armorclass, public static final int nextexp = 30;
armorclass_vs_missile, public static final int armorclass = 31;
armorclass_vs_hth, public static final int armorclass_vs_missile = 32;
normal_damage_reduction, public static final int armorclass_vs_hth = 33;
magic_damage_reduction, public static final int normal_damage_reduction = 34;
damageresist, public static final int magic_damage_reduction = 35;
magicresist, public static final int damageresist = 36;
maxmagicresist, public static final int magicresist = 37;
fireresist, public static final int maxmagicresist = 38;
maxfireresist, public static final int fireresist = 39;
lightresist, public static final int maxfireresist = 40;
maxlightresist, public static final int lightresist = 41;
coldresist, public static final int maxlightresist = 42;
maxcoldresist, public static final int coldresist = 43;
poisonresist, public static final int maxcoldresist = 44;
maxpoisonresist, public static final int poisonresist = 45;
damageaura, public static final int maxpoisonresist = 46;
firemindam, public static final int damageaura = 47;
firemaxdam, public static final int firemindam = 48;
lightmindam, public static final int firemaxdam = 49;
lightmaxdam, public static final int lightmindam = 50;
magicmindam, public static final int lightmaxdam = 51;
magicmaxdam, public static final int magicmindam = 52;
coldmindam, public static final int magicmaxdam = 53;
coldmaxdam, public static final int coldmindam = 54;
coldlength, public static final int coldmaxdam = 55;
poisonmindam, public static final int coldlength = 56;
poisonmaxdam, public static final int poisonmindam = 57;
poisonlength, public static final int poisonmaxdam = 58;
lifedrainmindam, public static final int poisonlength = 59;
lifedrainmaxdam, public static final int lifedrainmindam = 60;
manadrainmindam, public static final int lifedrainmaxdam = 61;
manadrainmaxdam, public static final int manadrainmindam = 62;
stamdrainmindam, public static final int manadrainmaxdam = 63;
stamdrainmaxdam, public static final int stamdrainmindam = 64;
stunlength, public static final int stamdrainmaxdam = 65;
velocitypercent, public static final int stunlength = 66;
attackrate, public static final int velocitypercent = 67;
other_animrate, public static final int attackrate = 68;
quantity, public static final int other_animrate = 69;
value, public static final int quantity = 70;
durability, public static final int value = 71;
maxdurability, public static final int durability = 72;
hpregen, public static final int maxdurability = 73;
item_maxdurability_percent, public static final int hpregen = 74;
item_maxhp_percent, public static final int item_maxdurability_percent = 75;
item_maxmana_percent, public static final int item_maxhp_percent = 76;
item_attackertakesdamage, public static final int item_maxmana_percent = 77;
item_goldbonus, public static final int item_attackertakesdamage = 78;
item_magicbonus, public static final int item_goldbonus = 79;
item_knockback, public static final int item_magicbonus = 80;
item_timeduration, public static final int item_knockback = 81;
item_addclassskills, public static final int item_timeduration = 82;
unsentparam1, public static final int item_addclassskills = 83;
item_addexperience, public static final int unsentparam1 = 84;
item_healafterkill, public static final int item_addexperience = 85;
item_reducedprices, public static final int item_healafterkill = 86;
item_doubleherbduration, public static final int item_reducedprices = 87;
item_lightradius, public static final int item_doubleherbduration = 88;
item_lightcolor, public static final int item_lightradius = 89;
item_req_percent, public static final int item_lightcolor = 90;
item_levelreq, public static final int item_req_percent = 91;
item_fasterattackrate, public static final int item_levelreq = 92;
item_levelreqpct, public static final int item_fasterattackrate = 93;
lastblockframe, public static final int item_levelreqpct = 94;
item_fastermovevelocity, public static final int lastblockframe = 95;
item_nonclassskill, public static final int item_fastermovevelocity = 96;
state, public static final int item_nonclassskill = 97;
item_fastergethitrate, public static final int state = 98;
monster_playercount, public static final int item_fastergethitrate = 99;
skill_poison_override_length, public static final int monster_playercount = 100;
item_fasterblockrate, public static final int skill_poison_override_length = 101;
skill_bypass_undead, public static final int item_fasterblockrate = 102;
skill_bypass_demons, public static final int skill_bypass_undead = 103;
item_fastercastrate, public static final int skill_bypass_demons = 104;
skill_bypass_beasts, public static final int item_fastercastrate = 105;
item_singleskill, public static final int skill_bypass_beasts = 106;
item_restinpeace, public static final int item_singleskill = 107;
curse_resistance, public static final int item_restinpeace = 108;
item_poisonlengthresist, public static final int curse_resistance = 109;
item_normaldamage, public static final int item_poisonlengthresist = 110;
item_howl, public static final int item_normaldamage = 111;
item_stupidity, public static final int item_howl = 112;
item_damagetomana, public static final int item_stupidity = 113;
item_ignoretargetac, public static final int item_damagetomana = 114;
item_fractionaltargetac, public static final int item_ignoretargetac = 115;
item_preventheal, public static final int item_fractionaltargetac = 116;
item_halffreezeduration, public static final int item_preventheal = 117;
item_tohit_percent, public static final int item_halffreezeduration = 118;
item_damagetargetac, public static final int item_tohit_percent = 119;
item_demondamage_percent, public static final int item_damagetargetac = 120;
item_undeaddamage_percent, public static final int item_demondamage_percent = 121;
item_demon_tohit, public static final int item_undeaddamage_percent = 122;
item_undead_tohit, public static final int item_demon_tohit = 123;
item_throwable, public static final int item_undead_tohit = 124;
item_elemskill, public static final int item_throwable = 125;
item_allskills, public static final int item_elemskill = 126;
item_attackertakeslightdamage, public static final int item_allskills = 127;
ironmaiden_level, public static final int item_attackertakeslightdamage = 128;
lifetap_level, public static final int ironmaiden_level = 129;
thorns_percent, public static final int lifetap_level = 130;
bonearmor, public static final int thorns_percent = 131;
bonearmormax, public static final int bonearmor = 132;
item_freeze, public static final int bonearmormax = 133;
item_openwounds, public static final int item_freeze = 134;
item_crushingblow, public static final int item_openwounds = 135;
item_kickdamage, public static final int item_crushingblow = 136;
item_manaafterkill, public static final int item_kickdamage = 137;
item_healafterdemonkill, public static final int item_manaafterkill = 138;
item_extrablood, public static final int item_healafterdemonkill = 139;
item_deadlystrike, public static final int item_extrablood = 140;
item_absorbfire_percent, public static final int item_deadlystrike = 141;
item_absorbfire, public static final int item_absorbfire_percent = 142;
item_absorblight_percent, public static final int item_absorbfire = 143;
item_absorblight, public static final int item_absorblight_percent = 144;
item_absorbmagic_percent, public static final int item_absorblight = 145;
item_absorbmagic, public static final int item_absorbmagic_percent = 146;
item_absorbcold_percent, public static final int item_absorbmagic = 147;
item_absorbcold, public static final int item_absorbcold_percent = 148;
item_slow, public static final int item_absorbcold = 149;
item_aura, public static final int item_slow = 150;
item_indesctructible, public static final int item_aura = 151;
item_cannotbefrozen, public static final int item_indesctructible = 152;
item_staminadrainpct, public static final int item_cannotbefrozen = 153;
item_reanimate, public static final int item_staminadrainpct = 154;
item_pierce, public static final int item_reanimate = 155;
item_magicarrow, public static final int item_pierce = 156;
item_explosivearrow, public static final int item_magicarrow = 157;
item_throw_mindamage, public static final int item_explosivearrow = 158;
item_throw_maxdamage, public static final int item_throw_mindamage = 159;
skill_handofathena, public static final int item_throw_maxdamage = 160;
skill_staminapercent, public static final int skill_handofathena = 161;
skill_passive_staminapercent, public static final int skill_staminapercent = 162;
skill_concentration, public static final int skill_passive_staminapercent = 163;
skill_enchant, public static final int skill_concentration = 164;
skill_pierce, public static final int skill_enchant = 165;
skill_conviction, public static final int skill_pierce = 166;
skill_chillingarmor, public static final int skill_conviction = 167;
skill_frenzy, public static final int skill_chillingarmor = 168;
skill_decrepify, public static final int skill_frenzy = 169;
skill_armor_percent, public static final int skill_decrepify = 170;
alignment, public static final int skill_armor_percent = 171;
target0, public static final int alignment = 172;
target1, public static final int target0 = 173;
goldlost, public static final int target1 = 174;
conversion_level, public static final int goldlost = 175;
conversion_maxhp, public static final int conversion_level = 176;
unit_dooverlay, public static final int conversion_maxhp = 177;
attack_vs_montype, public static final int unit_dooverlay = 178;
damage_vs_montype, public static final int attack_vs_montype = 179;
fade, public static final int damage_vs_montype = 180;
armor_override_percent, public static final int fade = 181;
unused183, public static final int armor_override_percent = 182;
unused184, public static final int unused183 = 183;
unused185, public static final int unused184 = 184;
unused186, public static final int unused185 = 185;
unused187, public static final int unused186 = 186;
item_addskill_tab, public static final int unused187 = 187;
unused189, public static final int item_addskill_tab = 188;
unused190, public static final int unused189 = 189;
unused191, public static final int unused190 = 190;
unused192, public static final int unused191 = 191;
unused193, public static final int unused192 = 192;
item_numsockets, public static final int unused193 = 193;
item_skillonattack, public static final int item_numsockets = 194;
item_skillonkill, public static final int item_skillonattack = 195;
item_skillondeath, public static final int item_skillonkill = 196;
item_skillonhit, public static final int item_skillondeath = 197;
item_skillonlevelup, public static final int item_skillonhit = 198;
unused200, public static final int item_skillonlevelup = 199;
item_skillongethit, public static final int unused200 = 200;
unused202, public static final int item_skillongethit = 201;
unused203, public static final int unused202 = 202;
item_charged_skill, public static final int unused203 = 203;
unused204, public static final int item_charged_skill = 204;
unused205, public static final int unused204 = 205;
unused206, public static final int unused205 = 206;
unused207, public static final int unused206 = 207;
unused208, public static final int unused207 = 208;
unused209, public static final int unused208 = 209;
unused210, public static final int unused209 = 210;
unused211, public static final int unused210 = 211;
unused212, public static final int unused211 = 212;
item_armor_perlevel, public static final int unused212 = 213;
item_armorpercent_perlevel, public static final int item_armor_perlevel = 214;
item_hp_perlevel, public static final int item_armorpercent_perlevel = 215;
item_mana_perlevel, public static final int item_hp_perlevel = 216;
item_maxdamage_perlevel, public static final int item_mana_perlevel = 217;
item_maxdamage_percent_perlevel, public static final int item_maxdamage_perlevel = 218;
item_strength_perlevel, public static final int item_maxdamage_percent_perlevel = 219;
item_dexterity_perlevel, public static final int item_strength_perlevel = 220;
item_energy_perlevel, public static final int item_dexterity_perlevel = 221;
item_vitality_perlevel, public static final int item_energy_perlevel = 222;
item_tohit_perlevel, public static final int item_vitality_perlevel = 223;
item_tohitpercent_perlevel, public static final int item_tohit_perlevel = 224;
item_cold_damagemax_perlevel, public static final int item_tohitpercent_perlevel = 225;
item_fire_damagemax_perlevel, public static final int item_cold_damagemax_perlevel = 226;
item_ltng_damagemax_perlevel, public static final int item_fire_damagemax_perlevel = 227;
item_pois_damagemax_perlevel, public static final int item_ltng_damagemax_perlevel = 228;
item_resist_cold_perlevel, public static final int item_pois_damagemax_perlevel = 229;
item_resist_fire_perlevel, public static final int item_resist_cold_perlevel = 230;
item_resist_ltng_perlevel, public static final int item_resist_fire_perlevel = 231;
item_resist_pois_perlevel, public static final int item_resist_ltng_perlevel = 232;
item_absorb_cold_perlevel, public static final int item_resist_pois_perlevel = 233;
item_absorb_fire_perlevel, public static final int item_absorb_cold_perlevel = 234;
item_absorb_ltng_perlevel, public static final int item_absorb_fire_perlevel = 235;
item_absorb_pois_perlevel, public static final int item_absorb_ltng_perlevel = 236;
item_thorns_perlevel, public static final int item_absorb_pois_perlevel = 237;
item_find_gold_perlevel, public static final int item_thorns_perlevel = 238;
item_find_magic_perlevel, public static final int item_find_gold_perlevel = 239;
item_regenstamina_perlevel, public static final int item_find_magic_perlevel = 240;
item_stamina_perlevel, public static final int item_regenstamina_perlevel = 241;
item_damage_demon_perlevel, public static final int item_stamina_perlevel = 242;
item_damage_undead_perlevel, public static final int item_damage_demon_perlevel = 243;
item_tohit_demon_perlevel, public static final int item_damage_undead_perlevel = 244;
item_tohit_undead_perlevel, public static final int item_tohit_demon_perlevel = 245;
item_crushingblow_perlevel, public static final int item_tohit_undead_perlevel = 246;
item_openwounds_perlevel, public static final int item_crushingblow_perlevel = 247;
item_kick_damage_perlevel, public static final int item_openwounds_perlevel = 248;
item_deadlystrike_perlevel, public static final int item_kick_damage_perlevel = 249;
item_find_gems_perlevel, public static final int item_deadlystrike_perlevel = 250;
item_replenish_durability, public static final int item_find_gems_perlevel = 251;
item_replenish_quantity, public static final int item_replenish_durability = 252;
item_extra_stack, public static final int item_replenish_quantity = 253;
item_find_item, public static final int item_extra_stack = 254;
item_slash_damage, public static final int item_find_item = 255;
item_slash_damage_percent, public static final int item_slash_damage = 256;
item_crush_damage, public static final int item_slash_damage_percent = 257;
item_crush_damage_percent, public static final int item_crush_damage = 258;
item_thrust_damage, public static final int item_crush_damage_percent = 259;
item_thrust_damage_percent, public static final int item_thrust_damage = 260;
item_absorb_slash, public static final int item_thrust_damage_percent = 261;
item_absorb_crush, public static final int item_absorb_slash = 262;
item_absorb_thrust, public static final int item_absorb_crush = 263;
item_absorb_slash_percent, public static final int item_absorb_thrust = 264;
item_absorb_crush_percent, public static final int item_absorb_slash_percent = 265;
item_absorb_thrust_percent, public static final int item_absorb_crush_percent = 266;
item_armor_bytime, public static final int item_absorb_thrust_percent = 267;
item_armorpercent_bytime, public static final int item_armor_bytime = 268;
item_hp_bytime, public static final int item_armorpercent_bytime = 269;
item_mana_bytime, public static final int item_hp_bytime = 270;
item_maxdamage_bytime, public static final int item_mana_bytime = 271;
item_maxdamage_percent_bytime, public static final int item_maxdamage_bytime = 272;
item_strength_bytime, public static final int item_maxdamage_percent_bytime = 273;
item_dexterity_bytime, public static final int item_strength_bytime = 274;
item_energy_bytime, public static final int item_dexterity_bytime = 275;
item_vitality_bytime, public static final int item_energy_bytime = 276;
item_tohit_bytime, public static final int item_vitality_bytime = 277;
item_tohitpercent_bytime, public static final int item_tohit_bytime = 278;
item_cold_damagemax_bytime, public static final int item_tohitpercent_bytime = 279;
item_fire_damagemax_bytime, public static final int item_cold_damagemax_bytime = 280;
item_ltng_damagemax_bytime, public static final int item_fire_damagemax_bytime = 281;
item_pois_damagemax_bytime, public static final int item_ltng_damagemax_bytime = 282;
item_resist_cold_bytime, public static final int item_pois_damagemax_bytime = 283;
item_resist_fire_bytime, public static final int item_resist_cold_bytime = 284;
item_resist_ltng_bytime, public static final int item_resist_fire_bytime = 285;
item_resist_pois_bytime, public static final int item_resist_ltng_bytime = 286;
item_absorb_cold_bytime, public static final int item_resist_pois_bytime = 287;
item_absorb_fire_bytime, public static final int item_absorb_cold_bytime = 288;
item_absorb_ltng_bytime, public static final int item_absorb_fire_bytime = 289;
item_absorb_pois_bytime, public static final int item_absorb_ltng_bytime = 290;
item_find_gold_bytime, public static final int item_absorb_pois_bytime = 291;
item_find_magic_bytime, public static final int item_find_gold_bytime = 292;
item_regenstamina_bytime, public static final int item_find_magic_bytime = 293;
item_stamina_bytime, public static final int item_regenstamina_bytime = 294;
item_damage_demon_bytime, public static final int item_stamina_bytime = 295;
item_damage_undead_bytime, public static final int item_damage_demon_bytime = 296;
item_tohit_demon_bytime, public static final int item_damage_undead_bytime = 297;
item_tohit_undead_bytime, public static final int item_tohit_demon_bytime = 298;
item_crushingblow_bytime, public static final int item_tohit_undead_bytime = 299;
item_openwounds_bytime, public static final int item_crushingblow_bytime = 300;
item_kick_damage_bytime, public static final int item_openwounds_bytime = 301;
item_deadlystrike_bytime, public static final int item_kick_damage_bytime = 302;
item_find_gems_bytime, public static final int item_deadlystrike_bytime = 303;
item_pierce_cold, public static final int item_find_gems_bytime = 304;
item_pierce_fire, public static final int item_pierce_cold = 305;
item_pierce_ltng, public static final int item_pierce_fire = 306;
item_pierce_pois, public static final int item_pierce_ltng = 307;
item_damage_vs_monster, public static final int item_pierce_pois = 308;
item_damage_percent_vs_monster, public static final int item_damage_vs_monster = 309;
item_tohit_vs_monster, public static final int item_damage_percent_vs_monster = 310;
item_tohit_percent_vs_monster, public static final int item_tohit_vs_monster = 311;
item_ac_vs_monster, public static final int item_tohit_percent_vs_monster = 312;
item_ac_percent_vs_monster, public static final int item_ac_vs_monster = 313;
firelength, public static final int item_ac_percent_vs_monster = 314;
burningmin, public static final int firelength = 315;
burningmax, public static final int burningmin = 316;
progressive_damage, public static final int burningmax = 317;
progressive_steal, public static final int progressive_damage = 318;
progressive_other, public static final int progressive_steal = 319;
progressive_fire, public static final int progressive_other = 320;
progressive_cold, public static final int progressive_fire = 321;
progressive_lightning, public static final int progressive_cold = 322;
item_extra_charges, public static final int progressive_lightning = 323;
progressive_tohit, public static final int item_extra_charges = 324;
poison_count, public static final int progressive_tohit = 325;
damage_framerate, public static final int poison_count = 326;
pierce_idx, public static final int damage_framerate = 327;
passive_fire_mastery, public static final int pierce_idx = 328;
passive_ltng_mastery, public static final int passive_fire_mastery = 329;
passive_cold_mastery, public static final int passive_ltng_mastery = 330;
passive_pois_mastery, public static final int passive_cold_mastery = 331;
passive_fire_pierce, public static final int passive_pois_mastery = 332;
passive_ltng_pierce, public static final int passive_fire_pierce = 333;
passive_cold_pierce, public static final int passive_ltng_pierce = 334;
passive_pois_pierce, public static final int passive_cold_pierce = 335;
passive_critical_strike, public static final int passive_pois_pierce = 336;
passive_dodge, public static final int passive_critical_strike = 337;
passive_avoid, public static final int passive_dodge = 338;
passive_evade, public static final int passive_avoid = 339;
passive_warmth, public static final int passive_evade = 340;
passive_mastery_melee_th, public static final int passive_warmth = 341;
passive_mastery_melee_dmg, public static final int passive_mastery_melee_th = 342;
passive_mastery_melee_crit, public static final int passive_mastery_melee_dmg = 343;
passive_mastery_throw_th, public static final int passive_mastery_melee_crit = 344;
passive_mastery_throw_dmg, public static final int passive_mastery_throw_th = 345;
passive_mastery_throw_crit, public static final int passive_mastery_throw_dmg = 346;
passive_weaponblock, public static final int passive_mastery_throw_crit = 347;
passive_summon_resist, public static final int passive_weaponblock = 348;
modifierlist_skill, public static final int passive_summon_resist = 349;
modifierlist_level, public static final int modifierlist_skill = 350;
last_sent_hp_pct, public static final int modifierlist_level = 351;
source_unit_type, public static final int last_sent_hp_pct = 352;
source_unit_id, public static final int source_unit_type = 353;
shortparam1, public static final int source_unit_id = 354;
questitemdifficulty, public static final int shortparam1 = 355;
passive_mag_mastery, public static final int questitemdifficulty = 356;
passive_mag_pierce; public static final int passive_mag_mastery = 357;
public static final int passive_mag_pierce = 358;
private static final int NONE = 0x1FF; public static final int BITS = 9;
public static final int NONE = (1 << BITS) - 1; // 0x1FF
private static final int[] ENCODED_COUNT = { // These don't actually exist in the game
public static final int reqstr = NONE - 1;
public static final int reqdex = NONE - 2;
static final int[] ENCODED_COUNT = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 1, 3, 1, 1, 1, 1, 1, 1, // 32 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 1, 3, 1, 1, 1, 1, 1, 1, // 32
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64
@ -386,45 +392,53 @@ public enum Stat {
1, 1, 1, 1, 1, 1, 1, // 352 1, 1, 1, 1, 1, 1, 1, // 352
}; };
private static final String[] BY_TIME = { static int getNumEncoded(int stat) {
"ModStre9e", "ModStre9g", "ModStre9d", "ModStre9f",
};
private final ItemStatCost.Entry entry;
Stat() {
entry = Riiablo.files.ItemStatCost.get(ordinal());
}
public static int getStatCount(int stat) {
return ENCODED_COUNT[stat]; return ENCODED_COUNT[stat];
} }
private static final Stat[] values = values(); static int hash(int stat, int param) {
return stat | (param << 16);
public static Stat valueOf(int i) {
return i == NONE ? null : values[i];
} }
public ItemStatCost.Entry entry() { static Stat.Instance read(int stat, BitStream bitStream) {
return entry; return new Instance(stat, bitStream);
} }
public Instance read(BitStream bitStream) { static Stat.Instance create(int stat, int value) {
int param = bitStream.readUnsigned31OrLess(entry.Save_Param_Bits); return new Instance(stat, value);
int value = bitStream.readUnsigned31OrLess(entry.Save_Bits) - entry.Save_Add;
return new Instance(this, value, param);
} }
public static class Instance { static class Instance {
final Stat stat; final int stat;
final int value; final int param; // can probably safely be truncated to short
final int param; final int hash;
final ItemStatCost.Entry entry;
Instance(Stat stat, int value, int param) { int value;
Instance(int stat, BitStream bitStream) {
this.stat = stat;
entry = Riiablo.files.ItemStatCost.get(stat);
param = bitStream.readUnsigned31OrLess(entry.Save_Param_Bits);
value = bitStream.readUnsigned31OrLess(entry.Save_Bits) - entry.Save_Add;
hash = Stat.hash(stat, param);
}
Instance(int stat, int value) {
this.stat = stat; this.stat = stat;
this.value = value; this.value = value;
this.param = param; entry = Riiablo.files.ItemStatCost.get(stat);
param = 0;
hash = Stat.hash(stat, param);
}
@Override
public int hashCode() {
return hash;
}
public void add(Instance other) {
// TODO
} }
private static final StringBuilder builder = new StringBuilder(32); private static final StringBuilder builder = new StringBuilder(32);
@ -434,8 +448,11 @@ public enum Stat {
private static final CharSequence PLUS = Riiablo.string.lookup("plus"); private static final CharSequence PLUS = Riiablo.string.lookup("plus");
private static final CharSequence TO = Riiablo.string.lookup("ItemStast1k"); private static final CharSequence TO = Riiablo.string.lookup("ItemStast1k");
private static final String[] BY_TIME = {
"ModStre9e", "ModStre9g", "ModStre9d", "ModStre9f",
};
public String format(boolean group) { public String format(boolean group) {
ItemStatCost.Entry entry = stat.entry;
return group return group
? format(entry.dgrpfunc, entry.dgrpval, entry.dgrpstrpos, entry.dgrpstrneg, entry.dgrpstr2) ? format(entry.dgrpfunc, entry.dgrpval, entry.dgrpstrpos, entry.dgrpstrneg, entry.dgrpstr2)
: format(entry.descfunc, entry.descval, entry.descstrpos, entry.descstrneg, entry.descstr2); : format(entry.descfunc, entry.descval, entry.descstrpos, entry.descstrneg, entry.descstr2);
@ -597,7 +614,7 @@ public enum Stat {
.append(Riiablo.string.lookup("ModStre10b")).append(SPACE) .append(Riiablo.string.lookup("ModStre10b")).append(SPACE)
.append(param1()).append(SPACE) .append(param1()).append(SPACE)
.append(Riiablo.string.lookup(desc.str_name)).append(SPACE) .append(Riiablo.string.lookup(desc.str_name)).append(SPACE)
.append(Riiablo.string.format(stat.entry.descstrpos, value1(), value2())); .append(Riiablo.string.format(strpos, value1(), value2()));
return builder.toString(); return builder.toString();
case 25: // TODO: unsupported case 25: // TODO: unsupported
return "ERROR 25"; return "ERROR 25";
@ -635,7 +652,7 @@ public enum Stat {
// Looks like this is unused outside character stats // Looks like this is unused outside character stats
// fortitude is calculated using OP (statvalue * basevalue) / (2 ^ param) -- (10 * 89) / (2 ^ 3) = 111.25 // fortitude is calculated using OP (statvalue * basevalue) / (2 ^ param) -- (10 * 89) / (2 ^ 3) = 111.25
public float toFloat() { public float toFloat() {
int shift = stat.entry.ValShift; int shift = entry.ValShift;
int pow = (1 << shift); int pow = (1 << shift);
int mask = pow - 1; int mask = pow - 1;
return ((value >>> shift) + ((value & mask) / (float) pow)); return ((value >>> shift) + ((value & mask) / (float) pow));
@ -646,7 +663,7 @@ public enum Stat {
} }
public int value1() { public int value1() {
switch (stat.entry.Encode) { switch (entry.Encode) {
case 0: return value; case 0: return value;
case 1: return value; case 1: return value;
case 2: return value; case 2: return value;
@ -657,7 +674,7 @@ public enum Stat {
} }
public int value2() { public int value2() {
switch (stat.entry.Encode) { switch (entry.Encode) {
case 0: return 0; case 0: return 0;
case 1: return 0; case 1: return 0;
case 2: return 0; case 2: return 0;
@ -668,7 +685,7 @@ public enum Stat {
} }
public int value3() { public int value3() {
switch (stat.entry.Encode) { switch (entry.Encode) {
case 0: return 0; case 0: return 0;
case 1: return 0; case 1: return 0;
case 2: return 0; case 2: return 0;
@ -679,7 +696,7 @@ public enum Stat {
} }
public int param1() { public int param1() {
switch (stat.entry.Encode) { switch (entry.Encode) {
case 0: return param; case 0: return param;
case 1: return param; case 1: return param;
case 2: return param & 0x3F; case 2: return param & 0x3F;
@ -690,7 +707,7 @@ public enum Stat {
} }
public int param2() { public int param2() {
switch (stat.entry.Encode) { switch (entry.Encode) {
case 0: return 0; case 0: return 0;
case 1: return 0; case 1: return 0;
case 2: return (param >>> 6) & 0x3FF; case 2: return (param >>> 6) & 0x3FF;
@ -702,13 +719,13 @@ public enum Stat {
@Override @Override
public String toString() { public String toString() {
switch (stat.entry.Encode) { switch (entry.Encode) {
case 0: return stat + "=" + (stat.entry.Save_Param_Bits == 0 ? Integer.toString(value) : value + ":" + param); case 0: return stat + "(" + entry + ")" + "=" + (entry.Save_Param_Bits == 0 ? Integer.toString(value) : value + ":" + param);
case 1: return stat + "=" + (stat.entry.Save_Param_Bits == 0 ? Integer.toString(value) : value + ":" + param); case 1: return stat + "(" + entry + ")" + "=" + param() + ":" + value();
case 2: return stat + "=" + param2() + ":" + param1() + ":" + value(); case 2: return stat + "(" + entry + ")" + "=" + param1() + ":" + param2() + ":" + value();
case 3: return stat + "=" + param2() + ":" + param1() + ":" + value2() + ":" + value1(); case 3: return stat + "(" + entry + ")" + "=" + param1() + ":" + param2() + ":" + value1() + ":" + value2();
case 4: return stat + "=" + value1() + ":" + value2() + ":" + value3(); case 4: return stat + "(" + entry + ")" + "=" + value1() + ":" + value2() + ":" + value3();
default: return stat + "=" + (stat.entry.Save_Param_Bits == 0 ? Integer.toString(value) : value + ":" + param); default: return stat + "(" + entry + ")" + "=" + (entry.Save_Param_Bits == 0 ? Integer.toString(value) : value + ":" + param);
} }
} }
} }