Implemented item attr lists

This commit is contained in:
Collin Smith 2019-03-21 15:36:43 -07:00
parent c31f4a969c
commit 0429e456d8
2 changed files with 62 additions and 20 deletions

View File

@ -28,6 +28,7 @@ import com.riiablo.widget.Label;
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.Arrays;
import java.util.EnumMap;
import static com.riiablo.item.Quality.SET;
@ -77,7 +78,7 @@ public class Item extends Actor implements Disposable {
public int runewordData;
public String inscription;
public EnumMap<Stat, Integer> stats;
public EnumMap<Stat, Stat.Instance> stats[];
public ItemEntry base;
public ItemTypes.Entry type;
@ -198,24 +199,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.)
stats = new EnumMap<>(Stat.class);
stats = (EnumMap<Stat, Stat.Instance>[]) new EnumMap[7];
stats[0] = new EnumMap<>(Stat.class);
if (type.is("armo")) {
int defense = Stat.armorclass.read(bitStream);
stats.put(Stat.armorclass, defense);
stats[0].put(Stat.armorclass, Stat.armorclass.read(bitStream));
}
if (type.is("armo") || type.is("weap")) {
int maxdurability = Stat.maxdurability.read(bitStream);
stats.put(Stat.maxdurability, maxdurability);
if (maxdurability > 0) {
int durability = Stat.durability.read(bitStream);
stats.put(Stat.durability, durability);
Stat.Instance maxdurability = Stat.maxdurability.read(bitStream);
stats[0].put(Stat.maxdurability, maxdurability);
if (maxdurability.value > 0) {
stats[0].put(Stat.durability, Stat.durability.read(bitStream));
}
}
if ((flags & SOCKETED) == SOCKETED && (type.is("armo") || type.is("weap"))) {
int sockets = Stat.item_numsockets.read(bitStream);
stats.put(Stat.item_numsockets, sockets);
stats[0].put(Stat.item_numsockets, Stat.item_numsockets.read(bitStream));
}
if (type.is("book")) {
@ -224,7 +223,7 @@ public class Item extends Actor implements Disposable {
if (base.stackable) {
int quantity = bitStream.readUnsigned15OrLess(9);
stats.put(Stat.quantity, quantity);
stats[0].put(Stat.quantity, new Stat.Instance(Stat.quantity, quantity, 0));
}
if (quality == SET) {
@ -232,13 +231,26 @@ public class Item extends Actor implements Disposable {
listsFlags |= (lists << 1);
}
if (type.is("book")) {
listsFlags = 0;
}
for (int i = 0; i < 7; i++) {
if ((listsFlags & (1 << i)) != 0) {
// TODO: READ PROPERTY LIST
if (((listsFlags >> i) & 1) == 1) {
if (i > 0) stats[i] = new EnumMap<>(Stat.class);
EnumMap<Stat, 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.put(stat, stat.read(bitStream));
}
}
}
}
System.out.println(getName() + " : " + stats.toString() + " : " + Integer.toBinaryString(listsFlags));
//System.out.println(getName() + " : " + Arrays.toString(stats) + " : " + Integer.toBinaryString(listsFlags));
}
return this;
@ -307,7 +319,8 @@ public class Item extends Actor implements Disposable {
.append("qualityData", qualityData)
.append("runewordData", String.format("0x%04X", runewordData))
.append("inscription", inscription)
.append("socketed", socketed);
.append("socketed", socketed)
.append("attrs", Arrays.toString(stats));
} else {
builder.append("location", location);
switch (location) {
@ -378,6 +391,8 @@ public class Item extends Actor implements Disposable {
if ((flags & SOCKETED) == SOCKETED && socketsFilled > 0) {
builder.append("socketed", socketed);
}
builder.append("attrs", Arrays.toString(stats));
}
}

View File

@ -382,6 +382,12 @@ public enum Stat {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1
};
private final ItemStatCost.Entry entry;
Stat() {
entry = Riiablo.files.ItemStatCost.get(ordinal());
}
public static int getStatCount(int stat) {
return ENCODED_COUNT[stat];
}
@ -393,11 +399,32 @@ public enum Stat {
}
public ItemStatCost.Entry entry() {
return Riiablo.files.ItemStatCost.get(ordinal());
return entry;
}
public int read(BitStream bitStream) {
ItemStatCost.Entry entry = entry();
return bitStream.readUnsigned31OrLess(entry.Save_Bits) - entry.Save_Add;
public Instance read(BitStream bitStream) {
int value = bitStream.readUnsigned31OrLess(entry.Save_Bits) - entry.Save_Add; // TODO: Support entry.ValShift
int param = entry.Save_Param_Bits > 0 ? bitStream.readUnsigned31OrLess(entry.Save_Param_Bits) : 0;
return new Instance(this, value, param);
}
public static class Instance {
final Stat stat;
final int value;
final int param;
Instance(Stat stat, int value, int param) {
this.stat = stat;
this.value = value;
this.param = param;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(value);
if (stat.entry.Save_Param_Bits > 0) builder.append(':').append(param);
return builder.toString();
}
}
}