diff --git a/core/src/com/riiablo/attributes/StatListReader.java b/core/src/com/riiablo/attributes/StatListReader.java new file mode 100644 index 00000000..f7d8adad --- /dev/null +++ b/core/src/com/riiablo/attributes/StatListReader.java @@ -0,0 +1,66 @@ +package com.riiablo.attributes; + +import com.riiablo.codec.excel.ItemStatCost; +import com.riiablo.io.BitInput; +import com.riiablo.logger.LogManager; +import com.riiablo.logger.Logger; +import com.riiablo.logger.MDC; + +public class StatListReader { + private static final Logger log = LogManager.getLogger(StatListReader.class); + + public StatGetter read(StatListBuilder stats, short stat, BitInput bits) { + final ItemStatCost.Entry entry = Stat.entry(stat); + final int param, value; + log.trace("entry.Saved: {}", entry.Saved); + if (entry.Saved) { + assert !entry.CSvSigned : "entry.CSvSigned(" + entry.CSvSigned + ") unsupported"; + param = (int) bits.read63u(entry.CSvParam); + value = (int) bits.read63u(entry.CSvBits); + } else { + param = (int) bits.read63u(entry.Save_Param_Bits); + value = (int) bits.read63u(entry.Save_Bits) - entry.Save_Add; + } + return stats.put(stat, param, value).last(); + } + + public StatListGetter read(StatListBuilder stats, BitInput bits) { + log.traceEntry("read(stats: {}, bits: {})", stats, bits); + for (short stat; (stat = bits.read15u(Stat.BITS)) != Stat.NONE;) { + final byte numEncoded = Stat.getNumEncoded(stat); + try { + if (numEncoded > 1) MDC.put("numEncoded", numEncoded); + for (short j = stat, s = (short) (stat + numEncoded); j < s; j++) { + read(stats, j, bits); + } + } finally { + MDC.remove("numEncoded"); + } + } + + return stats.get(); + } + + public StatListGetter read(Attributes attrs, BitInput bits) { + final StatList stats = attrs.base().clear(); + final StatListBuilder builder = stats.buildList(); + return read(builder, bits); + } + + public StatList read(Attributes attrs, BitInput bits, int flags, int maxLists) { + final StatList stats = attrs.list().clear(); + for (int i = 0; i < maxLists; i++) { + final StatListBuilder builder = stats.buildList(); + if (((flags >> i) & 1) == 1) { + try { +// MDC.put("propList", Item.getPropListString(i)); + read(builder, bits); + } finally { +// MDC.remove("propList"); + } + } + } + + return stats.freeze(); + } +} diff --git a/core/test/com/riiablo/attributes/StatListReaderTest.java b/core/test/com/riiablo/attributes/StatListReaderTest.java new file mode 100644 index 00000000..58bccf95 --- /dev/null +++ b/core/test/com/riiablo/attributes/StatListReaderTest.java @@ -0,0 +1,59 @@ +package com.riiablo.attributes; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.badlogic.gdx.ApplicationAdapter; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.backends.headless.HeadlessApplication; + +import com.riiablo.Files; +import com.riiablo.Riiablo; +import com.riiablo.codec.StringTBLs; +import com.riiablo.io.BitInput; +import com.riiablo.io.ByteInput; +import com.riiablo.logger.Level; +import com.riiablo.logger.LogManager; +import com.riiablo.mpq.MPQFileHandleResolver; + +public class StatListReaderTest { + @BeforeClass + public static void setup() { + Gdx.app = new HeadlessApplication(new ApplicationAdapter() {}); + Riiablo.home = Gdx.files.absolute("C:\\Program Files (x86)\\Steam\\steamapps\\common\\Diablo II"); + Riiablo.mpqs = new MPQFileHandleResolver(); + Riiablo.string = new StringTBLs(Riiablo.mpqs); + Riiablo.files = new Files(); + } + + @AfterClass + public static void teardown() { + Gdx.app.exit(); + } + + @BeforeClass + public static void before() { + LogManager.setLevel("com.riiablo.attributes", Level.TRACE); + } + + @Test + public void read_char_stats() { + final byte[] bytes = { + (byte) 0x00, (byte) 0xD4, (byte) 0x08, (byte) 0x30, (byte) 0x82, + (byte) 0x80, (byte) 0x0C, (byte) 0x06, (byte) 0xD8, (byte) 0x65, + (byte) 0x80, (byte) 0x7B, (byte) 0xDA, (byte) 0x1C, (byte) 0x00, + (byte) 0xA0, (byte) 0x1C, (byte) 0x08, (byte) 0x2A, (byte) 0xC3, + (byte) 0x45, (byte) 0x02, (byte) 0x00, (byte) 0x6A, (byte) 0xA0, + (byte) 0xC0, (byte) 0xFD, (byte) 0x94, (byte) 0x2C, (byte) 0x00, + (byte) 0x70, (byte) 0x10, (byte) 0x0C, (byte) 0xB4, (byte) 0x0D, + (byte) 0x98, (byte) 0x73, (byte) 0x78, (byte) 0xCE, (byte) 0x1E, + (byte) 0xC4, (byte) 0x6C, (byte) 0x25, (byte) 0xF8, (byte) 0x0F + }; + + final BitInput bits = ByteInput.wrap(bytes).unalign(); + final Attributes attrs = Attributes.aggregateAttributes(); + final StatListReader reader = new StatListReader(); + reader.read(attrs.base().buildList(), bits); + } +} \ No newline at end of file