67 lines
2.7 KiB
GDScript
67 lines
2.7 KiB
GDScript
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)
|