101 lines
2.9 KiB
Python
101 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
def crop_icon(icon: str | None) -> list[int | str] | None:
|
|
if not icon:
|
|
return None
|
|
|
|
lines = icon.split("\n")
|
|
xs: list[int] = []
|
|
ys: list[int] = []
|
|
|
|
for y, line in enumerate(lines):
|
|
for x, char in enumerate(line):
|
|
if char != " ":
|
|
xs.append(x)
|
|
ys.append(y)
|
|
|
|
if not xs:
|
|
return [0, 0, ""]
|
|
|
|
min_x = min(xs)
|
|
max_x = max(xs)
|
|
min_y = min(ys)
|
|
max_y = max(ys)
|
|
cropped_lines = [line[min_x : max_x + 1].rstrip() for line in lines[min_y : max_y + 1]]
|
|
return [min_x, min_y, "\n".join(cropped_lines)]
|
|
|
|
|
|
def compact_chains(data: object) -> list[list[object]]:
|
|
if isinstance(data, dict):
|
|
chains = data.get("chains")
|
|
else:
|
|
chains = data
|
|
|
|
if not isinstance(chains, list):
|
|
raise ValueError("Input JSON does not contain a valid chains array")
|
|
|
|
compact: list[list[object]] = []
|
|
|
|
for chain in chains:
|
|
if isinstance(chain, list):
|
|
if len(chain) == 2 and isinstance(chain[1], list):
|
|
compact.append(chain)
|
|
continue
|
|
if len(chain) == 3 and isinstance(chain[1], int) and isinstance(chain[2], list):
|
|
compact.append([chain[0], chain[2]])
|
|
continue
|
|
raise ValueError("Invalid compact chain entry")
|
|
|
|
if not isinstance(chain, dict):
|
|
raise ValueError("Expected verbose or compact chain entries as input")
|
|
|
|
items = chain.get("items")
|
|
if not isinstance(items, list) or not items:
|
|
continue
|
|
|
|
base_id = chain["base_id"]
|
|
compact_items: list[list[object]] = []
|
|
|
|
for item in items:
|
|
compact_items.append([
|
|
item["item_id"],
|
|
crop_icon(item.get("icon_nfp_16x16")),
|
|
])
|
|
|
|
compact.append([base_id, compact_items])
|
|
|
|
return compact
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(
|
|
description="Rewrite atc_chains.json into a compact format used by compcount.lua."
|
|
)
|
|
parser.add_argument("source", nargs="?", default="atc_chains_uncompressed.json")
|
|
parser.add_argument("destination", nargs="?", default="atc_chains.json")
|
|
args = parser.parse_args()
|
|
|
|
source_path = Path(args.source)
|
|
destination_path = Path(args.destination)
|
|
original_text = source_path.read_text(encoding="utf-8")
|
|
data = json.loads(original_text)
|
|
compact = {"chains": compact_chains(data)}
|
|
compact_text = json.dumps(compact, separators=(",", ":"))
|
|
destination_path.write_text(compact_text, encoding="utf-8")
|
|
|
|
print(f"Compacted {source_path} -> {destination_path}")
|
|
print(f"Old size: {len(original_text.encode('utf-8'))} bytes")
|
|
print(f"New size: {len(compact_text.encode('utf-8'))} bytes")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|