wip
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Convert an EncounterJournal JSON dump into a Lua file the
|
||||
MoonWellClient EncounterJournal addon can `loadstring`/`include`.
|
||||
|
||||
Field order, key sort and structure mirror what the C++ exporter
|
||||
in mod-encounter-journal writes via .ej export. Use this when the
|
||||
JSON is produced outside the worldserver (e.g., from a CI job that
|
||||
queries acore_world directly).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any, Iterable
|
||||
|
||||
|
||||
def lua_str(value: Any) -> str:
|
||||
s = str(value)
|
||||
s = s.replace("\\", "\\\\")
|
||||
s = s.replace("'", "\\'")
|
||||
s = s.replace("\n", "\\n")
|
||||
s = s.replace("\r", "\\r")
|
||||
return f"'{s}'"
|
||||
|
||||
|
||||
def lua_value(value: Any) -> str:
|
||||
if isinstance(value, bool):
|
||||
return "true" if value else "false"
|
||||
if isinstance(value, (int, float)):
|
||||
# Integers stay int; floats use repr for round-trip stability.
|
||||
if isinstance(value, float) and value.is_integer():
|
||||
return str(int(value))
|
||||
return repr(value) if isinstance(value, float) else str(value)
|
||||
if value is None:
|
||||
return "nil"
|
||||
return lua_str(value)
|
||||
|
||||
|
||||
def lua_array(values: Iterable[Any]) -> str:
|
||||
return "{ " + ", ".join(lua_value(v) for v in values) + " }"
|
||||
|
||||
|
||||
def emit_keyed_rows(out: list[str], name: str, mapping: dict, indent: str) -> None:
|
||||
out.append(f"{indent}{name} = {{\n")
|
||||
for key in sorted(mapping.keys(), key=lambda k: int(k)):
|
||||
rows = mapping[key]
|
||||
if rows and isinstance(rows[0], list):
|
||||
out.append(f"{indent} [{int(key)}] = {{\n")
|
||||
for row in rows:
|
||||
out.append(f"{indent} {lua_array(row)},\n")
|
||||
out.append(f"{indent} }},\n")
|
||||
else:
|
||||
# Single row OR flat list of ids (tierInstances).
|
||||
out.append(f"{indent} [{int(key)}] = {lua_array(rows)},\n")
|
||||
out.append(f"{indent}}},\n")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--input", "-i", required=True,
|
||||
help="Path to EncounterJournalData.json")
|
||||
parser.add_argument("--output", "-o", required=True,
|
||||
help="Path to write EncounterJournalData.lua")
|
||||
parser.add_argument("--global", "-g", dest="global_name",
|
||||
default="MoonWellEncounterJournalData",
|
||||
help="Name of the Lua global to assign")
|
||||
args = parser.parse_args()
|
||||
|
||||
src = Path(args.input)
|
||||
if not src.exists():
|
||||
print(f"input file not found: {src}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
with src.open("r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
out: list[str] = []
|
||||
out.append("-- Generated by mod-encounter-journal/tools/json_to_lua.py.\n")
|
||||
out.append("-- Source of truth: custom_ej_* tables in acore_world.\n\n")
|
||||
out.append(f"{args.global_name} = {{\n")
|
||||
|
||||
# tiers (flat array)
|
||||
out.append(" tiers = {\n")
|
||||
for tier in data.get("tiers", []):
|
||||
out.append(f" {lua_array(tier)},\n")
|
||||
out.append(" },\n")
|
||||
|
||||
# instances : map id -> single row
|
||||
instances = data.get("instances", {})
|
||||
out.append(" instances = {\n")
|
||||
for key in sorted(instances.keys(), key=lambda k: int(k)):
|
||||
out.append(f" [{int(key)}] = {lua_array(instances[key])},\n")
|
||||
out.append(" },\n")
|
||||
|
||||
# tierInstances : map tier_id -> [instance_id, ...]
|
||||
emit_keyed_rows(out, "tierInstances", data.get("tierInstances", {}), " ")
|
||||
|
||||
# encounters : map instance_id -> [[row], ...]
|
||||
emit_keyed_rows(out, "encounters", data.get("encounters", {}), " ")
|
||||
|
||||
# creatures : map encounter_id -> [[row], ...]
|
||||
emit_keyed_rows(out, "creatures", data.get("creatures", {}), " ")
|
||||
|
||||
# sections : map section_id -> single row
|
||||
sections = data.get("sections", {})
|
||||
out.append(" sections = {\n")
|
||||
for key in sorted(sections.keys(), key=lambda k: int(k)):
|
||||
out.append(f" [{int(key)}] = {lua_array(sections[key])},\n")
|
||||
out.append(" },\n")
|
||||
|
||||
# items : map encounter_id -> [[row], ...]
|
||||
emit_keyed_rows(out, "items", data.get("items", {}), " ")
|
||||
|
||||
out.append("}\n")
|
||||
|
||||
Path(args.output).write_text("".join(out), encoding="utf-8")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user