per-floor extras + Ascension overrides + layer toggles
- atlasloot_extras: fit one transform per (kg_dungeon, floor_id) instead of mixing all kg bosses into one fit. Each AL extra is assigned to whichever floor's anchors it's nearest to (in AL coord space). Strat's Stonespine now correctly lands on floor 235 (Undead) instead of being hidden because the mixed-floor fit pushed it off. - new data/ascension_overrides.json: per-name position/floor patches for places where Ascension diverges from retail. Seeded with Magistrate Barthilas → moved to the southern courtyard (3498, 3300 on Undead Side) per Ascension spawns. - frontend renders extras only on their assigned floor; previously hard-coded to floor 0. - new layer-toggle checkboxes (Enemies / Packs / Patrols / Icons) in the toolbar — flip patrols off if mob routes are noise for your route.
This commit is contained in:
@@ -26,6 +26,7 @@ REGISTRY = DATA / "kg_dungeons.json"
|
||||
WEB_ASSETS = ROOT / "web" / "assets"
|
||||
WEB_MAPS = WEB_ASSETS / "maps"
|
||||
EXTRAS_PATH = DATA / "atlasloot_extras.json"
|
||||
OVERRIDES_PATH = DATA / "ascension_overrides.json"
|
||||
OUT_PATH = WEB_ASSETS / "dungeons.json"
|
||||
|
||||
# Map kg's mapIconType names → simple labels we render in the UI.
|
||||
@@ -223,6 +224,22 @@ def main() -> int:
|
||||
if EXTRAS_PATH.exists():
|
||||
extras_db = json.loads(EXTRAS_PATH.read_text()).get("extras", {})
|
||||
|
||||
overrides = []
|
||||
if OVERRIDES_PATH.exists():
|
||||
overrides = json.loads(OVERRIDES_PATH.read_text()).get("overrides", [])
|
||||
|
||||
def apply_overrides(tile_key, name, pos, floor_id):
|
||||
"""Return (pos, floor_id) possibly replaced by an Ascension override."""
|
||||
for o in overrides:
|
||||
if o["tile_key"] != tile_key:
|
||||
continue
|
||||
if o["name"].lower() not in name.lower():
|
||||
continue
|
||||
new_floor = o.get("kg_floor_id", floor_id)
|
||||
new_pos = o.get("pos", pos)
|
||||
return new_pos, new_floor
|
||||
return pos, floor_id
|
||||
|
||||
# Build a global icon-type index from the static.js if present, else
|
||||
# fall back to known IDs.
|
||||
icon_index: dict[int, str] = {
|
||||
@@ -261,9 +278,25 @@ def main() -> int:
|
||||
"pos": [e["x"], e["y"]],
|
||||
"rare": bool(e.get("rare")),
|
||||
"source": e.get("source", "atlasloot"),
|
||||
"kg_floor_id": e.get("kg_floor_id"),
|
||||
}
|
||||
for e in extras
|
||||
]
|
||||
|
||||
# Ascension overrides: swap pos / floor for a specific named entity
|
||||
for m in entry["maps"]:
|
||||
for e in m["enemies"]:
|
||||
new_pos, new_floor = apply_overrides(d["tile_key"], e["name"], e["pos"], m.get("kg_floor_id"))
|
||||
if new_pos is not e["pos"]:
|
||||
e["pos"] = list(new_pos)
|
||||
e["ascension_override"] = True
|
||||
for ex in entry.get("extras", []):
|
||||
new_pos, new_floor = apply_overrides(d["tile_key"], ex["name"], ex["pos"], ex.get("kg_floor_id"))
|
||||
if new_pos is not ex["pos"]:
|
||||
ex["pos"] = list(new_pos)
|
||||
ex["kg_floor_id"] = new_floor
|
||||
ex["ascension_override"] = True
|
||||
|
||||
dungeons.append(entry)
|
||||
|
||||
dungeons.sort(key=lambda d: d["name"])
|
||||
|
||||
Reference in New Issue
Block a user