From 2d4b2a72a959665c95621a5bd981d239eeb25569 Mon Sep 17 00:00:00 2001 From: Collin Smith Date: Sat, 18 Jan 2020 15:10:44 -0800 Subject: [PATCH] Added support for updating stats Implemented support for updating items, item stats, and applying stats to ItemData attributes field Added reference to CharStats.Entry to ItemData -- this may be removed when hireling stats are implemented more thoroughly Added clear method in CharData to support chaining CharData reset methods clear().load(D2S) Added empty base stats for hireling -- fixes issues with applying hireling stats to their own Attributes --- core/src/com/riiablo/save/CharData.java | 39 +++++++++++++++++++++++-- core/src/com/riiablo/save/D2S.java | 4 ++- core/src/com/riiablo/save/ItemData.java | 38 +++++++++++++----------- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/core/src/com/riiablo/save/CharData.java b/core/src/com/riiablo/save/CharData.java index 80665ab6..99903c09 100644 --- a/core/src/com/riiablo/save/CharData.java +++ b/core/src/com/riiablo/save/CharData.java @@ -63,7 +63,7 @@ public class CharData implements ItemData.UpdateListener, Pool.Poolable { final long npcReturnData[] = new long[Riiablo.MAX_DIFFS]; final Attributes statData = new Attributes(); final IntIntMap skillData = new IntIntMap(); - final ItemData itemData = new ItemData(statData); + final ItemData itemData = new ItemData(statData, null); Item golemItemData; public int diff; @@ -123,6 +123,11 @@ public class CharData implements ItemData.UpdateListener, Pool.Poolable { CharData() {} + public CharData clear() { + reset(); + return this; + } + public CharData load(D2S d2s) { d2s.copyTo(this); preprocessItems(); @@ -190,6 +195,36 @@ public class CharData implements ItemData.UpdateListener, Pool.Poolable { base.put(Stat.maxlightresist, 75); base.put(Stat.maxcoldresist, 75); base.put(Stat.maxpoisonresist, 75); + + // TODO: set base merc stats based on hireling tables and level + base = mercData.statData.base(); + base.put(Stat.strength, 0); + base.put(Stat.energy, 0); + base.put(Stat.dexterity, 0); + base.put(Stat.vitality, 0); + base.put(Stat.statpts, 0); + base.put(Stat.newskills, 0); + base.put(Stat.hitpoints, 0); + base.put(Stat.maxhp, 0); + base.put(Stat.mana, 0); + base.put(Stat.maxmana, 0); + base.put(Stat.stamina, 0); + base.put(Stat.maxstamina, 0); + base.put(Stat.level, 0); + base.put(Stat.experience, 0); + base.put(Stat.gold, 0); + base.put(Stat.goldbank, 0); + base.put(Stat.armorclass, 0); + base.put(Stat.damageresist, 0); + base.put(Stat.magicresist, 0); + base.put(Stat.fireresist, diff.ResistPenalty); + base.put(Stat.lightresist, diff.ResistPenalty); + base.put(Stat.coldresist, diff.ResistPenalty); + base.put(Stat.poisonresist, diff.ResistPenalty); + base.put(Stat.maxfireresist, 75); + base.put(Stat.maxlightresist, 75); + base.put(Stat.maxcoldresist, 75); + base.put(Stat.maxpoisonresist, 75); } public boolean isManaged() { @@ -424,7 +459,7 @@ public class CharData implements ItemData.UpdateListener, Pool.Poolable { public int xp; final Attributes statData = new Attributes(); - final ItemData itemData = new ItemData(statData); + final ItemData itemData = new ItemData(statData, null); public Attributes getStats() { return statData; diff --git a/core/src/com/riiablo/save/D2S.java b/core/src/com/riiablo/save/D2S.java index 89a569f3..a3609873 100644 --- a/core/src/com/riiablo/save/D2S.java +++ b/core/src/com/riiablo/save/D2S.java @@ -207,12 +207,14 @@ public class D2S { base.put(Stat.gold, stats.gold); base.put(Stat.goldbank, stats.goldbank); - for (int spellId = data.classId.firstSpell, s = data.classId.lastSpell, i = 0; spellId < s; spellId++, i++) { + CharacterClass classId = data.classId; + for (int spellId = classId.firstSpell, s = classId.lastSpell, i = 0; spellId < s; spellId++, i++) { data.skillData.put(spellId, skills.data[i]); } data.itemData.clear(); data.itemData.addAll(items.items); + data.itemData.charStats = classId.entry(); data.itemData.alternate = header.alternate; data.golemItemData = golem.item; return data; diff --git a/core/src/com/riiablo/save/ItemData.java b/core/src/com/riiablo/save/ItemData.java index 488b61b7..843b3988 100644 --- a/core/src/com/riiablo/save/ItemData.java +++ b/core/src/com/riiablo/save/ItemData.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.IntArray; import com.badlogic.gdx.utils.IntIntMap; import com.riiablo.Riiablo; +import com.riiablo.codec.excel.CharStats; import com.riiablo.codec.excel.SetItems; import com.riiablo.item.Attributes; import com.riiablo.item.BodyLoc; @@ -19,6 +20,7 @@ public class ItemData { public static final int INVALID_ITEM = -1; final Attributes stats; + CharStats.Entry charStats; final Array itemData = new Array<>(Item.class); @@ -38,12 +40,14 @@ public class ItemData { final Array updateListeners = new Array<>(false, 16); - ItemData(Attributes stats) { + ItemData(Attributes stats, CharStats.Entry charStats) { this.stats = stats; + this.charStats = charStats; } public void clear() { cursor = INVALID_ITEM; + charStats = null; alternate = D2S.PRIMARY; alternateListeners.clear(); itemData.clear(); @@ -59,6 +63,12 @@ public class ItemData { Item[] items = itemData.items; for (int i = 0, s = itemData.size; i < s; i++) { Item item = items[i]; + if (item.quality == Quality.SET) { + setItemsOwned.getAndIncrement(item.qualityId, 0, 1); + if (item.location == Location.EQUIPPED && isActive(item)) { + updateSet(item, 1); + } + } switch (item.location) { case EQUIPPED: equipped.put(item.bodyLoc, i); @@ -77,8 +87,9 @@ public class ItemData { case SOCKET: default: } - if (item.quality == Quality.SET) setItemsOwned.getAndIncrement(item.qualityId, 0, 1); } + + updateStats(); } public Item getItem(int i) { @@ -202,7 +213,7 @@ public class ItemData { item.bodyLoc = bodyLoc; int j = equipped.put(bodyLoc, i); assert j == INVALID_ITEM : "Item " + j + " should have been unequipped by this point."; - update(bodyLoc); + updateStats(); // TODO: add support for appending to existing stats if this is an additional item updateSet(item, 1); notifyEquip(bodyLoc, item); } @@ -210,24 +221,13 @@ public class ItemData { int unequip(BodyLoc bodyLoc) { int i = equipped.remove(bodyLoc); Item item = itemData.get(i); -// update(bodyLoc); + updateStats(); updateSet(item, -1); notifyUnequip(bodyLoc, item); return i; } - void update(BodyLoc bodyLoc) { - int i = equipped.get(bodyLoc); - update(i); - } - - void update(int i) { - Item item = itemData.get(i); -// item.update(this); - updateStats(); - } - - private void updateStats() { + void updateStats() { Stat stat; stats.reset(); int[] cache = equipped.values(); @@ -236,6 +236,7 @@ public class ItemData { if (j == ItemData.INVALID_ITEM) continue; Item item = itemData.get(j); if (isActive(item)) { + item.update(stats, charStats, equippedSets); stats.add(item.props.remaining()); if ((stat = item.props.get(Stat.armorclass)) != null) { stats.aggregate().addCopy(stat); @@ -250,10 +251,13 @@ public class ItemData { if (j == ItemData.INVALID_ITEM) continue; Item item = itemData.get(j); if (item.type.is(Type.CHAR)) { + item.update(stats, charStats, equippedSets); stats.add(item.props.remaining()); + } else if (item.type.is(Type.BOOK)) { // TODO: may not be needed since not stat -- calculate elsewhere? + item.update(stats, charStats, equippedSets); } } -// stats.update(this); // TODO: uncomment + stats.update(stats, charStats); notifyUpdated(); }