Files
mplus-routes/tools/check_boss_alignment.py
T

66 lines
2.2 KiB
Python

#!/usr/bin/env python3
"""
Render every classic dungeon's webp with AtlasLoot boss coords overlaid as
red rings, side-by-side with the bare texture. Output to /tmp/alignment/ for
human review.
"""
from __future__ import annotations
import json
import re
import sys
from pathlib import Path
from PIL import Image, ImageDraw
ROOT = Path(__file__).resolve().parent.parent
WEB_MAPS = ROOT / "web" / "assets" / "maps"
DUNGEONS_JSON = ROOT / "web" / "assets" / "dungeons.json"
OUT_DIR = Path("/tmp/alignment")
def main() -> int:
if not DUNGEONS_JSON.exists():
print("dungeons.json missing, run build_data.py first", file=sys.stderr)
return 1
OUT_DIR.mkdir(parents=True, exist_ok=True)
data = json.loads(DUNGEONS_JSON.read_text())
rendered = []
for d in data["dungeons"]:
if d.get("expansion") != "OriginalWoW":
continue
# Use bosses from the first map (single-floor) or unassignedBosses (multi)
bosses = d["maps"][0]["bosses"] if d["maps"] and d["maps"][0]["bosses"] else d.get("unassignedBosses", [])
if not d["maps"]:
continue
# Pick the first map for the alignment check
m = d["maps"][0]
src = WEB_MAPS / Path(m["image"]).name
if not src.exists():
continue
with Image.open(src) as im:
im = im.convert("RGBA")
W, H = im.size
draw = ImageDraw.Draw(im)
for b in bosses:
px = int((b["x"] / 100) * W)
py = int((b["y"] / 100) * H)
r = 80
draw.ellipse([px - r, py - r, px + r, py + r], outline="red", width=14)
draw.ellipse([px - 4, py - 4, px + 4, py + 4], fill="red")
# Scale down for review
scale = 1024 / W
im_small = im.resize((1024, int(H * scale)), Image.LANCZOS)
out = OUT_DIR / f"{d['id']}.png"
im_small.save(out)
rendered.append((d["id"], d["name"], len(bosses), out))
print(f"Rendered {len(rendered)} dungeons → {OUT_DIR}")
for did, name, n, p in rendered:
print(f" {did:30s} {n:>2d} bosses → {p.name}")
return 0
if __name__ == "__main__":
raise SystemExit(main())