scopedvr-map-core/svmap/svmap_migration.gd
slyphax 17a8927fec Map-Kern aus dem Editor übernommen (Stand e8ab954)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 15:30:18 +01:00

67 lines
2.7 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends RefCounted
class_name SvmapMigration
## Migration veralteter Objekt-IDs beim Laden (Karte 25.10.: test.svmap mit
## gelöschten Pilz-Objekten ließ sich nicht mehr öffnen, V7).
##
## Regel: Eine ID, die nicht (mehr) in der Bibliothek steht, wird per Ersatz-Tabelle
## durch ein passendes Pack-Objekt ersetzt (Position, Drehung, Skalierung, Gruppe
## bleiben). Gibt es keinen Ersatz, wird das Objekt übersprungen und gemeldet —
## nie ein Absturz, nie stilles Verschwinden. Die Datei selbst ändert sich erst
## beim Speichern (Undo/Neu-Laden bleibt möglich).
## Präfix → Ersatz-ID (Pilze waren kleine kollisionslose Bodendeko → Gras 003).
const ERSATZ_PRAEFIX := {
"pilz_": "grass_003",
}
## Ersatz-ID für eine unbekannte ID ("" = keiner).
static func ersatz_fuer(oid: String, lib: Dictionary) -> String:
for praefix in ERSATZ_PRAEFIX:
if oid.begins_with(praefix):
var neu: String = ERSATZ_PRAEFIX[praefix]
return neu if lib.has(neu) else ""
return ""
## Migriert data["objects"] in place. Rückgabe:
## {"ersetzt": {alt_id: {"neu": id, "anzahl": n}}, "entfernt": {alt_id: n}, "gesamt": n}
static func migriere_objekte(data: Dictionary, manifest: Dictionary) -> Dictionary:
var bericht := {"ersetzt": {}, "entfernt": {}, "gesamt": 0}
var objects: Variant = data.get("objects", null)
if not (objects is Array):
return bericht
var lib: Dictionary = manifest.get("objects", {})
var neu_liste: Array = []
for obj in (objects as Array):
if not (obj is Dictionary) or not (obj.get("id", null) is String) \
or lib.has(obj["id"]):
neu_liste.append(obj)
continue
var alt: String = obj["id"]
var ersatz := ersatz_fuer(alt, lib)
bericht["gesamt"] += 1
if ersatz.is_empty():
bericht["entfernt"][alt] = int(bericht["entfernt"].get(alt, 0)) + 1
continue
var kopie: Dictionary = (obj as Dictionary).duplicate(true)
kopie["id"] = ersatz
neu_liste.append(kopie)
var eintrag: Dictionary = bericht["ersetzt"].get(alt, {"neu": ersatz, "anzahl": 0})
eintrag["anzahl"] = int(eintrag["anzahl"]) + 1
bericht["ersetzt"][alt] = eintrag
if int(bericht["gesamt"]) > 0:
data["objects"] = neu_liste
return bericht
## Menschenlesbare Zusammenfassung (deutsch) für die Statuszeile.
static func zusammenfassung(bericht: Dictionary, lib: Dictionary) -> String:
var teile: PackedStringArray = []
for alt in bericht.get("ersetzt", {}):
var e: Dictionary = bericht["ersetzt"][alt]
var neu_name := str(lib.get(e["neu"], {}).get("name_de", e["neu"]))
teile.append("%d× „%s“ durch „%s“ ersetzt" % [e["anzahl"], alt, neu_name])
for alt in bericht.get("entfernt", {}):
teile.append("%d× „%s“ übersprungen (kein Ersatz)" % [bericht["entfernt"][alt], alt])
return ", ".join(teile)