Files
sow-module-tilesets/wgt01/generator/make_itp.py
T
2026-07-04 18:03:35 +02:00

65 lines
2.1 KiB
Python

"""Generate the tileset palette `twu01palstd.itp` from tiles.py.
python make_itp.py [out.itp] # default: twu01palstd.itp
The toolset loads `<set>palstd.itp` when it registers a tileset; without it the
set fails to register (blank name in the New Area wizard, "could not create
area"). Every stock/custom set on disk ships one. It's a GFF `ITP ` file: a MAIN
list of palette categories, each a struct with an ID byte and a LIST of
{RESREF, STRREF} tile entries.
We emit one flat category listing all 40 tile model resrefs. Each entry carries
a local NAME cexostring (NOT a STRREF) — this is what stock/custom sets without a
tileset TLK do (verified against wut01palstd.itp). Entries with neither NAME nor
a valid STRREF render blank AND non-selectable in the toolset palette. Built as
JSON and converted to GFF with neverwinter.nim's nwn_gff (must be on PATH).
"""
import json
import os
import subprocess
import sys
import tempfile
import tiles
NO_STRREF = 0xFFFFFFFF # category folder: no dialog.tlk name (cosmetic, blank folder)
def tile_label(s):
"""Readable palette name, e.g. '[flat] cobble_plain'."""
return f"[{s['kind']}] {s['name']}"
def build():
entries = [{"__struct_id": 0,
"NAME": {"type": "cexostring", "value": tile_label(s)},
"RESREF": {"type": "resref", "value": tiles.resref(s)}}
for s in tiles.TILES]
return {
"__data_type": "ITP ",
"MAIN": {"type": "list", "value": [
{"__struct_id": 0,
"ID": {"type": "byte", "value": 0},
"STRREF": {"type": "dword", "value": NO_STRREF},
"LIST": {"type": "list", "value": entries}},
]},
}
def main():
out = sys.argv[1] if len(sys.argv) > 1 else f"{tiles.PREFIX}palstd.itp"
with tempfile.NamedTemporaryFile("w", suffix=".json", delete=False) as tf:
json.dump(build(), tf)
js = tf.name
try:
subprocess.run(["nwn_gff", "-i", js, "-l", "json", "-k", "gff", "-o", out],
check=True)
finally:
os.unlink(js)
print(f"wrote {out} ({len(tiles.TILES)} tile palette entries)")
if __name__ == "__main__":
main()