forked from omicron/d2warehouse
Fix extracting +X to Class Skills with param value
This commit is contained in:
@@ -8,27 +8,30 @@ import sys
|
||||
|
||||
path = sys.argv[1] if len(sys.argv) >= 2 else "."
|
||||
|
||||
# NOTE: These map "linked stats" to code in properties.txt.
|
||||
# If None is given, the stat is excluded from the output.
|
||||
# NOTE: Special handling of stats. None = Skip stat.
|
||||
# Note that All Resistance is actually 4 stats in the save files, that the game combines
|
||||
# into one. Same applies for all stats.
|
||||
special_stats = {
|
||||
"firemindam": "dmg-fire",
|
||||
"firemindam": {"template": "dmg-fire"},
|
||||
"firemaxdam": None,
|
||||
"lightmindam": "dmg-ltng",
|
||||
"lightmindam": {"template": "dmg-ltng"},
|
||||
"lightmaxdam": None,
|
||||
"magicmindam": "dmg-mag",
|
||||
"magicmindam": {"template": "dmg-mag"},
|
||||
"magicmaxdam": None,
|
||||
"coldmindam": "dmg-cold",
|
||||
"coldmindam": {"template": "dmg-cold"},
|
||||
"coldmaxdam": None,
|
||||
"coldlength": None,
|
||||
"poisonmindam": "dmg-pois",
|
||||
"poisonmindam": {"template": "dmg-pois"},
|
||||
"poisonmaxdam": None,
|
||||
"poisonlength": None,
|
||||
"mindamage": "dmg-norm",
|
||||
"mindamage": {"template": "dmg-norm"},
|
||||
"maxdamage": None,
|
||||
"item_maxdamage_percent": "dmg%", # max before min for this stat
|
||||
"item_maxdamage_percent": {"template": "dmg%"}, # max before min for this stat
|
||||
"item_mindamage_percent": None,
|
||||
"item_addclassskills": {
|
||||
"template": "ama",
|
||||
"param_tooltips": ["ama", "pal", "nec", "sor", "bar", "dru", "ass"],
|
||||
},
|
||||
}
|
||||
|
||||
# Patching of missing data in properties.txt
|
||||
@@ -53,6 +56,7 @@ with open(os.path.join(path, "properties.txt")) as f:
|
||||
prop = {
|
||||
"stats": [row[f"stat{i}"] for i in range(1, 8) if len(row[f"stat{i}"]) > 0],
|
||||
"tooltip": row["*Tooltip"],
|
||||
"val1": None if len(row["val1"]) == 0 else int(row["val1"]),
|
||||
}
|
||||
properties[row["code"]] = prop
|
||||
if len(prop["stats"]) == 1 and prop["stats"][0] not in stat_to_prop:
|
||||
@@ -72,12 +76,24 @@ with open(os.path.join(path, "itemstatcost.txt")) as f:
|
||||
}
|
||||
|
||||
stats = {}
|
||||
for stat, statdat in itemstatcost.items():
|
||||
if stat in special_stats:
|
||||
if special_stats[stat] is None:
|
||||
for stat in itemstatcost:
|
||||
try:
|
||||
special = (
|
||||
special_stats[stat]
|
||||
if stat in special_stats
|
||||
else {"template": stat_to_prop[stat]}
|
||||
)
|
||||
except KeyError:
|
||||
print(
|
||||
f"Failed getting property for stat {stat}. Skipping! (See `special_stats` for fixing)"
|
||||
)
|
||||
continue
|
||||
else:
|
||||
prop = properties[special_stats[stat]]
|
||||
# special = None -> Skip
|
||||
if special is None:
|
||||
continue
|
||||
|
||||
# special.template: properties.txt row
|
||||
prop = properties[special["template"]]
|
||||
obj = {
|
||||
"text": prop["tooltip"],
|
||||
"save_bits": [],
|
||||
@@ -90,21 +106,21 @@ for stat, statdat in itemstatcost.items():
|
||||
f"Unexpected divergence in save_add for stats in prop {special_stats[stat]}"
|
||||
)
|
||||
obj["save_bits"].append(itemstatcost[prop_stat]["save_bits"])
|
||||
else:
|
||||
try:
|
||||
prop = properties[stat_to_prop[stat]]
|
||||
except KeyError:
|
||||
print(
|
||||
f"Failed getting property for stat {stat}. Skipping! (See `special_stats` for fixing)"
|
||||
)
|
||||
continue
|
||||
obj = {
|
||||
|
||||
# special.param_tooltips: extra tooltips depending on param value
|
||||
if "param_tooltips" in special:
|
||||
tooltips = []
|
||||
for id in special["param_tooltips"]:
|
||||
prop = properties[id]
|
||||
tooltips.append(
|
||||
{
|
||||
"param": prop["val1"],
|
||||
"text": prop["tooltip"],
|
||||
"save_bits": [statdat["save_bits"]],
|
||||
"save_add": statdat["save_add"],
|
||||
"save_param_bits": statdat["save_param_bits"],
|
||||
}
|
||||
stats[statdat["id"]] = obj
|
||||
)
|
||||
obj["text"] = tooltips
|
||||
|
||||
stats[itemstatcost[stat]["id"]] = obj
|
||||
|
||||
with open("stats.json", "w", newline="\n") as f:
|
||||
json.dump(stats, f, indent=4)
|
||||
|
||||
@@ -393,7 +393,36 @@
|
||||
"save_param_bits": null
|
||||
},
|
||||
"83": {
|
||||
"text": "+# to Amazon Skill Levels",
|
||||
"text": [
|
||||
{
|
||||
"param": 0,
|
||||
"text": "+# to Amazon Skill Levels"
|
||||
},
|
||||
{
|
||||
"param": 3,
|
||||
"text": "+# to Paladin Skill Levels"
|
||||
},
|
||||
{
|
||||
"param": 2,
|
||||
"text": "+# to Necromancer Skill Levels"
|
||||
},
|
||||
{
|
||||
"param": 1,
|
||||
"text": "+# to Sorceress Skill Levels"
|
||||
},
|
||||
{
|
||||
"param": 4,
|
||||
"text": "+# to Barbarian Skill Levels"
|
||||
},
|
||||
{
|
||||
"param": 5,
|
||||
"text": "+# to Druid Skill Levels"
|
||||
},
|
||||
{
|
||||
"param": 6,
|
||||
"text": "+# to Assassin Skill Levels"
|
||||
}
|
||||
],
|
||||
"save_bits": [
|
||||
3
|
||||
],
|
||||
|
||||
@@ -65,11 +65,16 @@ class Stat:
|
||||
print(" " * indent, str(self))
|
||||
|
||||
def __str__(self):
|
||||
param = self.parameter
|
||||
if isinstance(self.text, list):
|
||||
subst_text = next(filter(lambda v: v["param"] == param, self.text))["text"]
|
||||
param = None
|
||||
else:
|
||||
subst_text = self.text
|
||||
for val in self.values:
|
||||
subst_text = subst_text.replace("#", str(val), 1)
|
||||
if self.parameter:
|
||||
subst_text = re.sub(r"\[[^\]]*\]", str(self.parameter), subst_text, 1)
|
||||
if param:
|
||||
subst_text = re.sub(r"\[[^\]]*\]", str(param), subst_text, 1)
|
||||
return subst_text
|
||||
|
||||
|
||||
|
||||
@@ -123,4 +123,19 @@ class ParseItemTest(unittest.TestCase):
|
||||
# this is one of the items that had stackable "0" instead of ""
|
||||
data = bytes.fromhex("100080000524d4fc5f308dc1e10908fe03")
|
||||
data, item = parse_item(data)
|
||||
|
||||
def test_stat_to_class_skills(self):
|
||||
# Redeemer with +2 to Paladin skill levels
|
||||
data = bytes.fromhex(
|
||||
"1000800005c4d593081e37d107dfa330c868881031e29429cb6d415953466bf8eccd1c3aa13ce9fe03"
|
||||
)
|
||||
data, item = parse_item(data)
|
||||
self.assertEqual(data, b"")
|
||||
self.assertEqual(str(item.stats[1]), "+2 to Paladin Skill Levels")
|
||||
# Jalal with +2 to Druid skills levels
|
||||
data = bytes.fromhex(
|
||||
"1000800005c4753c2f5c4c4e3d638f8fd0068a08006802d020ac3a612e85b915e65a989b528d91dd41a1a8c02b0540ff01"
|
||||
)
|
||||
data, item = parse_item(data)
|
||||
self.assertEqual(data, b"")
|
||||
self.assertEqual(str(item.stats[7]), "+2 to Druid Skill Levels")
|
||||
|
||||
Reference in New Issue
Block a user