Move contrib folder
This commit is contained in:
27
contrib/runewords.py
Normal file
27
contrib/runewords.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
path = sys.argv[1] if len(sys.argv) >= 2 else "."
|
||||
|
||||
runewords = {}
|
||||
id = 0
|
||||
with open(os.path.join(path, "runes.txt")) as f:
|
||||
dr = csv.DictReader(f, delimiter="\t")
|
||||
for row in dr:
|
||||
id += 1
|
||||
if row["complete"] != "1":
|
||||
continue
|
||||
runewords[id + 26] = {
|
||||
"name": row["*Rune Name"],
|
||||
"itembases": [
|
||||
row[f"itype{i}"] for i in range(1, 7) if len(row[f"itype{i}"]) > 0
|
||||
],
|
||||
"runes": [row[f"Rune{i}"] for i in range(1, 7) if len(row[f"Rune{i}"]) > 0],
|
||||
}
|
||||
|
||||
with open("runewords.json", "w", newline="\n") as f:
|
||||
json.dump(runewords, f, indent=4)
|
||||
f.write("\n")
|
||||
111
contrib/stats.py
Normal file
111
contrib/stats.py
Normal file
@@ -0,0 +1,111 @@
|
||||
# Parse itemstatcost.txt and properties.txt into aggregated json.
|
||||
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
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 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",
|
||||
"firemaxdam": None,
|
||||
"lightmindam": "dmg-ltng",
|
||||
"lightmaxdam": None,
|
||||
"magicmindam": "dmg-mag",
|
||||
"magicmaxdam": None,
|
||||
"coldmindam": "dmg-cold",
|
||||
"coldmaxdam": None,
|
||||
"coldlength": None,
|
||||
"poisonmindam": "dmg-pois",
|
||||
"poisonmaxdam": None,
|
||||
"poisonlength": None,
|
||||
"mindamage": "dmg-norm",
|
||||
"maxdamage": None,
|
||||
"item_maxdamage_percent": "dmg%", # max before min for this stat
|
||||
"item_mindamage_percent": None,
|
||||
}
|
||||
|
||||
# Patching of missing data in properties.txt
|
||||
# NOTE: Ideally we should implement the description functions referenced in itemstatcost.txt
|
||||
# instead of relying on the debug tooltips of properties.txt, since the game does not
|
||||
# actually use those, but rather they are present for the excel developers.
|
||||
properties_patches = {
|
||||
"dmg-min": {"stat1": "secondary_mindamage"},
|
||||
"dmg-max": {"stat1": "secondary_maxdamage"},
|
||||
"dmg%": {"stat1": "item_maxdamage_percent", "stat2": "item_mindamage_percent"},
|
||||
}
|
||||
|
||||
properties = {}
|
||||
stat_to_prop = {}
|
||||
with open(os.path.join(path, "properties.txt")) as f:
|
||||
reader = csv.DictReader(f, delimiter="\t")
|
||||
for row in reader:
|
||||
if row["code"] in properties_patches:
|
||||
row.update(properties_patches[row["code"]])
|
||||
if len(row["stat1"]) == 0 or len(row["*Tooltip"]) == 0:
|
||||
continue
|
||||
prop = {
|
||||
"stats": [row[f"stat{i}"] for i in range(1, 8) if len(row[f"stat{i}"]) > 0],
|
||||
"tooltip": row["*Tooltip"],
|
||||
}
|
||||
properties[row["code"]] = prop
|
||||
if len(prop["stats"]) == 1 and prop["stats"][0] not in stat_to_prop:
|
||||
stat_to_prop[prop["stats"][0]] = row["code"]
|
||||
|
||||
itemstatcost = {}
|
||||
with open(os.path.join(path, "itemstatcost.txt")) as f:
|
||||
reader = csv.DictReader(f, delimiter="\t")
|
||||
for row in reader:
|
||||
itemstatcost[row["Stat"]] = {
|
||||
"id": row["*ID"],
|
||||
"save_bits": 0 if len(row["Save Bits"]) == 0 else int(row["Save Bits"]),
|
||||
"save_add": 0 if len(row["Save Add"]) == 0 else int(row["Save Add"]),
|
||||
"save_param_bits": None
|
||||
if len(row["Save Param Bits"]) == 0
|
||||
else int(row["Save Param Bits"]),
|
||||
}
|
||||
|
||||
stats = {}
|
||||
for stat, statdat in itemstatcost.items():
|
||||
if stat in special_stats:
|
||||
if special_stats[stat] is None:
|
||||
continue
|
||||
else:
|
||||
prop = properties[special_stats[stat]]
|
||||
obj = {
|
||||
"text": prop["tooltip"],
|
||||
"save_bits": [],
|
||||
"save_add": itemstatcost[prop["stats"][0]]["save_add"],
|
||||
"save_param_bits": itemstatcost[prop["stats"][0]]["save_param_bits"],
|
||||
}
|
||||
for prop_stat in prop["stats"]:
|
||||
if itemstatcost[prop_stat]["save_add"] != obj["save_add"]:
|
||||
print(
|
||||
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 = {
|
||||
"text": prop["tooltip"],
|
||||
"save_bits": [statdat["save_bits"]],
|
||||
"save_add": statdat["save_add"],
|
||||
"save_param_bits": statdat["save_param_bits"],
|
||||
}
|
||||
stats[statdat["id"]] = obj
|
||||
|
||||
with open("stats.json", "w", newline="\n") as f:
|
||||
json.dump(stats, f, indent=4)
|
||||
f.write("\n")
|
||||
59
contrib/uniques.py
Normal file
59
contrib/uniques.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
path = sys.argv[1] if len(sys.argv) >= 2 else "."
|
||||
|
||||
category = "Base"
|
||||
setitems = {}
|
||||
with open(os.path.join(path, "setitems.txt")) as f:
|
||||
dr = csv.DictReader(f, delimiter="\t")
|
||||
for row in dr:
|
||||
if row["index"] == "Expansion":
|
||||
category = row["index"]
|
||||
continue
|
||||
setitems[row["*ID"]] = {
|
||||
"name": row["index"],
|
||||
"set": row["set"],
|
||||
"itembase": row["item"],
|
||||
"req_lvl": int(row["lvl req"]),
|
||||
"ilvl": int(row["lvl"]),
|
||||
"rarity": int(row["rarity"]),
|
||||
"category": category,
|
||||
}
|
||||
|
||||
category = "Base"
|
||||
uniqueitems = {}
|
||||
with open(os.path.join(path, "uniqueitems.txt")) as f:
|
||||
dr = csv.DictReader(f, delimiter="\t")
|
||||
for row in dr:
|
||||
if row["index"] in [
|
||||
"Expansion",
|
||||
"Armor",
|
||||
"Elite Uniques",
|
||||
"Rings",
|
||||
"Class Specific",
|
||||
]:
|
||||
category = row["index"]
|
||||
continue
|
||||
if row["*ID"] == "288":
|
||||
category = "Patch 1.10+"
|
||||
if len(row["lvl req"]) == 0:
|
||||
continue # deleted uniques
|
||||
uniqueitems[row["*ID"]] = {
|
||||
"name": row["index"],
|
||||
"itembase": row["code"],
|
||||
"req_lvl": int(row["lvl req"]),
|
||||
"ilvl": int(row["lvl"]),
|
||||
"rarity": int(row["rarity"]),
|
||||
"category": category,
|
||||
}
|
||||
|
||||
with open("uniques.json", "w", newline="\n") as f:
|
||||
json.dump(uniqueitems, f, indent=4)
|
||||
f.write("\n")
|
||||
|
||||
with open("sets.json", "w", newline="\n") as f:
|
||||
json.dump(setitems, f, indent=4)
|
||||
f.write("\n")
|
||||
Reference in New Issue
Block a user