Changed item type lookup to use custom Bits implementation

Changed item type lookup to use custom Bits implementation
Item type lookup should now be O(1) -- I'll look into further optimizations
This commit is contained in:
Collin Smith 2019-03-28 20:10:21 -07:00
parent c9c5ee346b
commit 22a1498d64
4 changed files with 186 additions and 32 deletions

View File

@ -259,18 +259,18 @@ public class Player extends Entity {
Item RH = null, LH = null, SH = null;
Item rArm = getSlot(Slot.RARM);
if (rArm != null) {
if (rArm.type.is("weap")) {
if (rArm.type.is(com.riiablo.item.Type.WEAP)) {
RH = rArm;
} else if (rArm.type.is("shld")) {
} else if (rArm.type.is(com.riiablo.item.Type.SHLD)) {
SH = rArm;
}
}
Item lArm = getSlot(Slot.LARM);
if (lArm != null) {
if (lArm.type.is("weap")) {
if (lArm.type.is(com.riiablo.item.Type.WEAP)) {
LH = lArm;
} else if (lArm.type.is("shld")) {
} else if (lArm.type.is(com.riiablo.item.Type.SHLD)) {
SH = lArm;
}
}
@ -292,9 +292,9 @@ public class Player extends Entity {
setWeapon(WEAPON_1JS); // Left Jab Right Swing
} else if (LHEntry.wclass.equals("1ht") && RHEntry.wclass.equals("1ht")) {
setWeapon(WEAPON_1JT); // Left Jab Right Thrust
} else if (LH.type.is("miss") || RH.type.is("miss")) {
setWeapon((byte) Riiablo.files.WeaponClass.index(LH.type.is("miss") ? LHEntry.wclass : RHEntry.wclass));
} else if (LH.type.is("h2h") || RH.type.is("h2h")) {
} else if (LH.type.is(com.riiablo.item.Type.MISS) || RH.type.is(com.riiablo.item.Type.MISS)) {
setWeapon((byte) Riiablo.files.WeaponClass.index(LH.type.is(com.riiablo.item.Type.MISS) ? LHEntry.wclass : RHEntry.wclass));
} else if (LH.type.is(com.riiablo.item.Type.H2H) || RH.type.is(com.riiablo.item.Type.H2H)) {
setWeapon(WEAPON_HT2); // Two Hand-to-Hand
} else {
setWeapon(WEAPON_HTH);
@ -304,12 +304,12 @@ public class Player extends Entity {
} else if (LH != null || RH != null) {
RH = ObjectUtils.firstNonNull(RH, LH);
LH = null;
if (RH.type.is("bow")) {
if (RH.type.is(com.riiablo.item.Type.BOW)) {
LH = RH;
RH = null;
Weapons.Entry LHEntry = LH.getBase();
setWeapon((byte) Riiablo.files.WeaponClass.index(LHEntry.wclass));
} else if (RH.type.is("weap")) { // make sure weap and not e.g. misl, might not be required
} else if (RH.type.is(com.riiablo.item.Type.WEAP)) { // make sure weap and not e.g. misl, might not be required
Weapons.Entry RHEntry = RH.getBase();
setWeapon((byte) Riiablo.files.WeaponClass.index(RHEntry.wclass));
} else {

View File

@ -138,7 +138,8 @@ public class Item extends Actor implements Disposable {
public PropertyList stats[];
public ItemEntry base;
public ItemTypes.Entry type;
public ItemTypes.Entry typeEntry;
public Type type;
private String name;
private AssetDescriptor<DC6> invFileDescriptor;
@ -180,7 +181,8 @@ public class Item extends Actor implements Disposable {
socketed = new Array<>(6);
base = findBase(typeCode);
type = Riiablo.files.ItemTypes.get(base.type);
typeEntry = Riiablo.files.ItemTypes.get(base.type);
type = Type.get(typeEntry);
props = new PropertyList();
props.put(Stat.item_levelreq, base.levelreq);
@ -216,7 +218,7 @@ public class Item extends Actor implements Disposable {
qualityData = null;
runewordData = 0;
inscription = null;
if (type.is("gem") || type.is("rune")) {
if (type.is(Type.GEM) || type.is(Type.RUNE)) {
Gems.Entry gem = Riiablo.files.Gems.get(base.code);
stats = new PropertyList[NUM_GEM_PROPS];
stats[WEAPON_PROPS] = new PropertyList().add(gem.weaponModCode, gem.weaponModParam, gem.weaponModMin, gem.weaponModMax);
@ -275,22 +277,22 @@ 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.)
if (type.is("armo")) {
if (type.is(Type.ARMO)) {
props.read(Stat.armorclass, bitStream);
}
if (type.is("armo") || type.is("weap")) {
if (type.is(Type.ARMO) || type.is(Type.WEAP)) {
int maxdurability = props.read(Stat.maxdurability, bitStream);
if (maxdurability > 0) {
props.read(Stat.durability, bitStream);
}
}
if ((flags & SOCKETED) == SOCKETED && (type.is("armo") || type.is("weap"))) {
if ((flags & SOCKETED) == SOCKETED && (type.is(Type.ARMO) || type.is(Type.WEAP))) {
props.read(Stat.item_numsockets, bitStream);
}
if (type.is("book")) {
if (type.is(Type.BOOK)) {
bitStream.skip(5); // TODO: Tomes have an extra 5 bits inserted at this point. I have no idea what purpose they serve. It looks like the value is 0 on all of my tomes.
}
@ -304,7 +306,7 @@ public class Item extends Actor implements Disposable {
listsFlags |= (lists << SET_PROPS);
}
if (type.is("book")) {
if (type.is(Type.BOOK)) {
listsFlags = 0;
}
@ -562,7 +564,7 @@ public class Item extends Actor implements Disposable {
return "invtrch";
}
}
return type.InvGfx[pictureId];
return typeEntry.InvGfx[pictureId];
}
switch (quality) {
case SET:
@ -818,7 +820,7 @@ public class Item extends Actor implements Disposable {
break;
}
if (Item.this.type.is("rune"))
if (Item.this.type.is(Type.RUNE))
name.setColor(Riiablo.colors.orange);
add(name).center().space(SPACING).row();
@ -837,7 +839,7 @@ public class Item extends Actor implements Disposable {
String runequote = Riiablo.string.lookup("RuneQuote");
StringBuilder runewordBuilder = null;
for (Item socket : socketed) {
if (socket.type.is("rune")) {
if (socket.type.is(Type.RUNE)) {
if (runewordBuilder == null) runewordBuilder = new StringBuilder(runequote);
runewordBuilder.append(Riiablo.string.lookup(socket.base.namestr + "L")); // TODO: Is there a r##L reference somewhere?
}
@ -848,15 +850,15 @@ public class Item extends Actor implements Disposable {
}
}
if (Item.this.type.is("book")) {
if (Item.this.type.is(Type.BOOK)) {
add(new Label(Riiablo.string.lookup("InsertScrolls"), font, Riiablo.colors.white)).center().space(SPACING).row();
} else if (Item.this.type.is("char")) {
} else if (Item.this.type.is(Type.CHAR)) {
add(new Label(Riiablo.string.lookup("ItemExpcharmdesc"), font, Riiablo.colors.white)).center().space(SPACING).row();
} else if (Item.this.type.is("sock")) {
} else if (Item.this.type.is(Type.SOCK)) {
add(new Label(Riiablo.string.lookup("ExInsertSocketsX"), font, Riiablo.colors.white)).center().space(SPACING).row();
}
if (Item.this.type.is("gem") || Item.this.type.is("rune")) {
if (Item.this.type.is(Type.GEM) || Item.this.type.is(Type.RUNE)) {
assert stats.length == NUM_GEM_PROPS;
add().height(font.getLineHeight()).space(SPACING).row();
add(new Label(Riiablo.string.lookup("GemXp3") + " " + stats[WEAPON_PROPS].copy().reduce().get().format(), font, Riiablo.colors.white)).center().space(SPACING).row();
@ -893,11 +895,11 @@ public class Item extends Actor implements Disposable {
Stat.Instance prop;
if ((prop = props.get(Stat.armorclass)) != null)
add(new Label(Riiablo.string.lookup("ItemStats1h") + " " + prop.value, font, Riiablo.colors.white)).center().space(SPACING).row();
if (Item.this.type.is("weap")) {
if (Item.this.type.is(Type.WEAP)) {
if ((prop = props.get(Stat.maxdamage)) != null) // TODO: Conditional 2 handed if barbarian, etc
add(new Label(Riiablo.string.lookup("ItemStats1l") + " " + props.get(Stat.mindamage).value + " to " + prop.value, font, Riiablo.colors.white)).center().space(SPACING).row();
}
if (Item.this.type.is("shld")) {
if (Item.this.type.is(Type.SHLD)) {
if ((prop = props.get(Stat.toblock)) != null)
add(new Label(Riiablo.string.lookup("ItemStats1r") + prop.value + "%", font, Riiablo.colors.white)).center().space(SPACING).row();
// TODO: if paladin, show smite damage -- ItemStats1o %d to %d
@ -906,8 +908,8 @@ public class Item extends Actor implements Disposable {
}
if (!Item.this.base.nodurability && (prop = props.get(Stat.durability)) != null)
add(new Label(Riiablo.string.lookup("ItemStats1d") + " " + prop.value + " " + Riiablo.string.lookup("ItemStats1j") + " " + props.get(Stat.maxdurability).value, font, Riiablo.colors.white)).center().space(SPACING).row();
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();
if (Item.this.type.is(Type.CLAS)) {
add(new Label(Riiablo.string.lookup(CharacterClass.get(Item.this.typeEntry.Class).entry().StrClassOnly), font, Riiablo.colors.white)).center().space(SPACING).row();
}
if ((prop = props.get(Stat.reqdex)) != null && prop.value > 0)
add(new Label(Riiablo.string.lookup("ItemStats1f") + " " + prop.value, font, Riiablo.colors.white)).center().space(SPACING).row();
@ -917,7 +919,7 @@ public class Item extends Actor implements Disposable {
add(new Label(Riiablo.string.lookup("ItemStats1p") + " " + prop.value, font, Riiablo.colors.white)).center().space(SPACING).row();
if ((prop = props.get(Stat.quantity)) != null)
add(new Label(Riiablo.string.lookup("ItemStats1i") + " " + prop.value, font, Riiablo.colors.white)).center().space(SPACING).row();
if (Item.this.type.is("weap")) {
if (Item.this.type.is(Type.WEAP)) {
add(new Label(Riiablo.string.lookup(WEAPON_DESC.get(Item.this.base.type)) + " - " + 0, font, Riiablo.colors.white)).center().space(SPACING).row();
}
//}
@ -929,7 +931,7 @@ public class Item extends Actor implements Disposable {
if (magicProps != null) {
PropertyList magicPropsAggregate = magicProps.copy();
for (Item socket : socketed) {
if (socket.type.is("gem") | socket.type.is("rune")) {
if (socket.type.is(Type.GEM) || socket.type.is(Type.RUNE)) {
magicPropsAggregate.addAll(socket.stats[base.gemapplytype]);
} else {
magicPropsAggregate.addAll(socket.stats[MAGIC_PROPS]);

View File

@ -0,0 +1,152 @@
package com.riiablo.item;
import com.badlogic.gdx.utils.Bits;
import com.riiablo.Riiablo;
import com.riiablo.codec.excel.ItemTypes;
public class Type extends Bits {
private static final Type[] TYPES;
static {
TYPES = new Type[128];
for (int i = 0, size = Riiablo.files.ItemTypes.size(); i < size; i++) {
if (TYPES[i] == null) TYPES[i] = new Type(Riiablo.files.ItemTypes.get(i));
}
}
public static Type get(ItemTypes.Entry type) {
return get(type.Code);
}
public static Type get(String type) {
return TYPES[Riiablo.files.ItemTypes.index(type)];
}
Type(String type) {
super(128);
setAll(type);
}
Type(ItemTypes.Entry type) {
this(type.Code);
}
private void setAll(String type) {
int id = Riiablo.files.ItemTypes.index(type);
if (TYPES[id] != null) {
or(TYPES[id]);
return;
} else {
TYPES[id] = this;
set(id);
}
ItemTypes.Entry entry = Riiablo.files.ItemTypes.get(id);
for (String equiv : entry.Equiv) {
if (equiv.isEmpty()) break;
setAll(equiv);
}
}
public boolean is(int index) {
return get(index);
}
public static final int SHIE = Riiablo.files.ItemTypes.index("shie");
public static final int TORS = Riiablo.files.ItemTypes.index("tors");
public static final int GOLD = Riiablo.files.ItemTypes.index("gold");
public static final int BOWQ = Riiablo.files.ItemTypes.index("bowq");
public static final int XBOQ = Riiablo.files.ItemTypes.index("xboq");
public static final int PLAY = Riiablo.files.ItemTypes.index("play");
public static final int HERB = Riiablo.files.ItemTypes.index("herb");
public static final int POTI = Riiablo.files.ItemTypes.index("poti");
public static final int RING = Riiablo.files.ItemTypes.index("ring");
public static final int ELIX = Riiablo.files.ItemTypes.index("elix");
public static final int AMUL = Riiablo.files.ItemTypes.index("amul");
public static final int CHAR = Riiablo.files.ItemTypes.index("char");
public static final int BOOT = Riiablo.files.ItemTypes.index("boot");
public static final int GLOV = Riiablo.files.ItemTypes.index("glov");
public static final int BOOK = Riiablo.files.ItemTypes.index("book");
public static final int BELT = Riiablo.files.ItemTypes.index("belt");
public static final int GEM = Riiablo.files.ItemTypes.index("gem");
public static final int TORC = Riiablo.files.ItemTypes.index("torc");
public static final int SCRO = Riiablo.files.ItemTypes.index("scro");
public static final int SCEP = Riiablo.files.ItemTypes.index("scep");
public static final int WAND = Riiablo.files.ItemTypes.index("wand");
public static final int STAF = Riiablo.files.ItemTypes.index("staf");
public static final int BOW = Riiablo.files.ItemTypes.index("bow");
public static final int AXE = Riiablo.files.ItemTypes.index("axe");
public static final int CLUB = Riiablo.files.ItemTypes.index("club");
public static final int SWOR = Riiablo.files.ItemTypes.index("swor");
public static final int HAMM = Riiablo.files.ItemTypes.index("hamm");
public static final int KNIF = Riiablo.files.ItemTypes.index("knif");
public static final int SPEA = Riiablo.files.ItemTypes.index("spea");
public static final int POLE = Riiablo.files.ItemTypes.index("pole");
public static final int XBOW = Riiablo.files.ItemTypes.index("xbow");
public static final int MACE = Riiablo.files.ItemTypes.index("mace");
public static final int HELM = Riiablo.files.ItemTypes.index("helm");
public static final int TPOT = Riiablo.files.ItemTypes.index("tpot");
public static final int QUES = Riiablo.files.ItemTypes.index("ques");
public static final int BODY = Riiablo.files.ItemTypes.index("body");
public static final int KEY = Riiablo.files.ItemTypes.index("key");
public static final int TKNI = Riiablo.files.ItemTypes.index("tkni");
public static final int TAXE = Riiablo.files.ItemTypes.index("taxe");
public static final int JAVE = Riiablo.files.ItemTypes.index("jave");
public static final int WEAP = Riiablo.files.ItemTypes.index("weap");
public static final int MELE = Riiablo.files.ItemTypes.index("mele");
public static final int MISS = Riiablo.files.ItemTypes.index("miss");
public static final int THRO = Riiablo.files.ItemTypes.index("thro");
public static final int COMB = Riiablo.files.ItemTypes.index("comb");
public static final int ARMO = Riiablo.files.ItemTypes.index("armo");
public static final int SHLD = Riiablo.files.ItemTypes.index("shld");
public static final int MISC = Riiablo.files.ItemTypes.index("misc");
public static final int SOCK = Riiablo.files.ItemTypes.index("sock");
public static final int SECO = Riiablo.files.ItemTypes.index("seco");
public static final int ROD = Riiablo.files.ItemTypes.index("rod");
public static final int MISL = Riiablo.files.ItemTypes.index("misl");
public static final int BLUN = Riiablo.files.ItemTypes.index("blun");
public static final int JEWL = Riiablo.files.ItemTypes.index("jewl");
public static final int CLAS = Riiablo.files.ItemTypes.index("clas");
public static final int AMAZ = Riiablo.files.ItemTypes.index("amaz");
public static final int BARB = Riiablo.files.ItemTypes.index("barb");
public static final int NECR = Riiablo.files.ItemTypes.index("necr");
public static final int PALA = Riiablo.files.ItemTypes.index("pala");
public static final int SORC = Riiablo.files.ItemTypes.index("sorc");
public static final int ASSN = Riiablo.files.ItemTypes.index("assn");
public static final int DRUI = Riiablo.files.ItemTypes.index("drui");
public static final int H2H = Riiablo.files.ItemTypes.index("h2h");
public static final int ORB = Riiablo.files.ItemTypes.index("orb");
public static final int HEAD = Riiablo.files.ItemTypes.index("head");
public static final int ASHD = Riiablo.files.ItemTypes.index("ashd");
public static final int PHLM = Riiablo.files.ItemTypes.index("phlm");
public static final int PELT = Riiablo.files.ItemTypes.index("pelt");
public static final int CLOA = Riiablo.files.ItemTypes.index("cloa");
public static final int RUNE = Riiablo.files.ItemTypes.index("rune");
public static final int CIRC = Riiablo.files.ItemTypes.index("circ");
public static final int HPOT = Riiablo.files.ItemTypes.index("hpot");
public static final int MPOT = Riiablo.files.ItemTypes.index("mpot");
public static final int RPOT = Riiablo.files.ItemTypes.index("rpot");
public static final int SPOT = Riiablo.files.ItemTypes.index("spot");
public static final int APOT = Riiablo.files.ItemTypes.index("apot");
public static final int WPOT = Riiablo.files.ItemTypes.index("wpot");
public static final int SCHA = Riiablo.files.ItemTypes.index("scha");
public static final int MCHA = Riiablo.files.ItemTypes.index("mcha");
public static final int LCHA = Riiablo.files.ItemTypes.index("lcha");
public static final int ABOW = Riiablo.files.ItemTypes.index("abow");
public static final int ASPE = Riiablo.files.ItemTypes.index("aspe");
public static final int AJAV = Riiablo.files.ItemTypes.index("ajav");
public static final int H2H2 = Riiablo.files.ItemTypes.index("h2h2");
public static final int MBOQ = Riiablo.files.ItemTypes.index("mboq");
public static final int MXBQ = Riiablo.files.ItemTypes.index("mxbq");
public static final int GEM0 = Riiablo.files.ItemTypes.index("gem0");
public static final int GEM1 = Riiablo.files.ItemTypes.index("gem1");
public static final int GEM2 = Riiablo.files.ItemTypes.index("gem2");
public static final int GEM3 = Riiablo.files.ItemTypes.index("gem3");
public static final int GEM4 = Riiablo.files.ItemTypes.index("gem4");
public static final int GEMA = Riiablo.files.ItemTypes.index("gema");
public static final int GEMD = Riiablo.files.ItemTypes.index("gemd");
public static final int GEME = Riiablo.files.ItemTypes.index("geme");
public static final int GEMR = Riiablo.files.ItemTypes.index("gemr");
public static final int GEMS = Riiablo.files.ItemTypes.index("gems");
public static final int GEMT = Riiablo.files.ItemTypes.index("gemt");
public static final int GEMZ = Riiablo.files.ItemTypes.index("gemz");
}

View File

@ -314,7 +314,7 @@ public class InventoryPanel extends WidgetGroup implements Disposable {
public void clicked(InputEvent event, float x, float y) {
Item cursor = Riiablo.cursor.getItem();
if (cursor != null) {
if (!ArrayUtils.contains(cursor.type.BodyLoc, bodyPart)) {
if (!ArrayUtils.contains(cursor.typeEntry.BodyLoc, bodyPart)) {
Riiablo.audio.play(gameScreen.player.stats.getCharClass().name().toLowerCase() + "_impossible_1", false);
return;
}
@ -357,7 +357,7 @@ public class InventoryPanel extends WidgetGroup implements Disposable {
boolean blocked = false;
Item cursorItem = Riiablo.cursor.getItem();
if (cursorItem != null) {
blocked = !ArrayUtils.contains(cursorItem.type.BodyLoc, bodyPart);
blocked = !ArrayUtils.contains(cursorItem.typeEntry.BodyLoc, bodyPart);
}
// TODO: red if does not meet item requirements