Files
ss14chemcalc/parse_extractables.py
2026-01-24 16:34:15 -05:00

133 lines
4.9 KiB
Python

import os
import yaml
import json
def parse_prototypes(root_dir):
all_entities = {}
# Recursively find all .yml files
for root, dirs, files in os.walk(root_dir):
for file in files:
if file.endswith(".yml"):
file_path = os.path.join(root, file)
try:
with open(file_path, 'r', encoding='utf-8') as f:
# Define a loader that ignores custom !type tags
class IgnoreTagsLoader(yaml.SafeLoader):
pass
def ignore_tag(loader, tag_suffix, node):
if isinstance(node, yaml.MappingNode):
return loader.construct_mapping(node)
elif isinstance(node, yaml.SequenceNode):
return loader.construct_sequence(node)
return loader.construct_scalar(node)
IgnoreTagsLoader.add_multi_constructor('!', ignore_tag)
# Some files have multiple YAML documents separated by ---
docs = yaml.load_all(f, Loader=IgnoreTagsLoader)
for doc in docs:
if not doc or not isinstance(doc, list):
continue
for entry in doc:
if entry.get('type') == 'entity' and 'id' in entry:
all_entities[entry['id']] = entry
except Exception as e:
print(f"Error parsing {file_path}: {e}")
# Helper to get components including from parents
def get_components(entity_id, seen=None):
if seen is None:
seen = set()
if entity_id in seen:
return {}
seen.add(entity_id)
entity = all_entities.get(entity_id)
if not entity:
return {}
merged_components = {}
parent = entity.get('parent')
if parent:
parents = [parent] if isinstance(parent, str) else parent
for p in parents:
parent_comps = get_components(p, seen)
# Merge parent components into our current set
for ctype, cdata in parent_comps.items():
if ctype not in merged_components:
merged_components[ctype] = cdata.copy()
else:
merged_components[ctype].update(cdata)
# Now add/override with local components
local_components = entity.get('components', [])
for comp in local_components:
ctype = comp.get('type')
if not ctype:
continue
if ctype not in merged_components:
merged_components[ctype] = comp.copy()
else:
merged_components[ctype].update(comp)
return merged_components
extractables = {}
for eid, entity in all_entities.items():
if entity.get('abstract'):
continue
components = get_components(eid)
extractable = components.get('Extractable')
solution_manager = components.get('SolutionContainerManager')
name = entity.get('name', eid)
if extractable:
data = {
"id": eid,
"name": name,
"grind": [],
"juice": []
}
# Grinding
grind_sol_name = extractable.get('grindableSolutionName')
if grind_sol_name and solution_manager:
sols = solution_manager.get('solutions', {})
target_sol = sols.get(grind_sol_name, {})
reagents = target_sol.get('reagents', [])
for r in reagents:
data['grind'].append({
"id": r['ReagentId'],
"amount": r['Quantity']
})
# Juicing
juice_sol = extractable.get('juiceSolution')
if juice_sol:
reagents = juice_sol.get('reagents', [])
for r in reagents:
data['juice'].append({
"id": r['ReagentId'],
"amount": r['Quantity']
})
if data['grind'] or data['juice']:
extractables[eid] = data
return extractables
if __name__ == "__main__":
root = "/home/laythe/Documents/ss14reagent/Prototypes"
results = parse_prototypes(root)
with open("extractables.json", "w", encoding="utf-8") as f:
json.dump(results, f, indent=2)
print(f"Successfully extracted {len(results)} items to extractables.json")