extends SceneTree ## Editor-Test (headless): Map-Loadout (V18) — Katalog, Validierung, Panel mit ## Undo/Redo und Speichern/Laden. Ausführen: ## godot --headless --path . --script res://tests/test_loadout.gd var failures := 0 var checks := 0 var main: Control func _initialize() -> void: _run_all.call_deferred() func _check(cond: bool, label: String) -> void: checks += 1 if cond: print(" ok: %s" % label) else: failures += 1 print(" FAIL: %s" % label) func _run_all() -> void: _test_katalog() await _test_panel() if failures == 0: print("ALL OK: %d checks" % checks) quit(0) else: print("FAILED: %d/%d checks" % [failures, checks]) quit(1) func _test_katalog() -> void: print("Testgruppe: Katalog + Validierung") _check(LoadoutKatalog.waffen_ids().size() >= 50, "Katalog hat Waffen") _check(LoadoutKatalog.hat_waffe("m40") and LoadoutKatalog.hat_waffe("pistol1"), "m40 + pistol1 bekannt") _check(LoadoutKatalog.validate(null).is_empty(), "fehlend gültig") _check(LoadoutKatalog.validate({"mode": "player"}).is_empty(), "player gültig") _check(not LoadoutKatalog.validate({"mode": "fixed"}).is_empty(), "fixed ohne Primär ungültig") _check(not LoadoutKatalog.validate({"mode": "fixed", "primary": "nix"}).is_empty(), "unbekannte Waffe ungültig") _check(not LoadoutKatalog.validate({"mode": "x"}).is_empty(), "unbekannter Modus ungültig") _check(LoadoutKatalog.validate({"mode": "fixed", "primary": "sr1", "secondary": ""}).is_empty(), "fixed ohne Sekundär gültig") _check(not LoadoutKatalog.validate({"mode": "fixed", "primary": "sr1", "attachments": {"ar1": ""}}).is_empty(), "Aufsatz für Fremdwaffe ungültig") _check(not LoadoutKatalog.validate({"mode": "fixed", "primary": "sr1", "attachments": {"sr1": "sight=nix"}}).is_empty(), "unbekanntes Teil ungültig") var sel := LoadoutKatalog.auswahl("sr1", "") sel["muzzle"] = "muzzle_suppressor_01" var wire := LoadoutKatalog.encode("sr1", sel) _check(wire == "muzzle=muzzle_suppressor_01", "encode nur Abweichungen: " + wire) _check(LoadoutKatalog.pruefe_aufsaetze("sr1", wire) == "", "encodierter Text gültig") func _test_panel() -> void: print("Testgruppe: Panel") var scene: PackedScene = load("res://scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame await process_frame main.doc = SvmapDocument.create_new("LoadoutTest", 512.0, "mittag") main.history.doc = main.doc main.call("_refresh_all") var panel: Node = main.map_mod.sections_host().get_node_or_null("loadout") _check(panel != null, "Loadout-Panel hängt im Map-Tab") if panel == null: return _check(not panel.is_fixed() and not main.doc.has("loadout"), "Start: Spieler-Loadout, kein Block") _check(not panel.fixed_box.visible, "Waffen-Auswahl verborgen") panel.set_fixed(true) _check(panel.is_fixed() and main.doc["loadout"]["primary"] == "m40", "fest: M40 als Start") _check(panel.fixed_box.visible, "Waffen-Auswahl sichtbar") panel.set_weapons("sr1", "") _check(main.doc["loadout"]["primary"] == "sr1" and main.doc["loadout"]["secondary"] == "", "Waffen gesetzt, Sekundär leer") panel.set_part("sr1", "muzzle", "muzzle_suppressor_01") _check(main.doc["loadout"]["attachments"].get("sr1", "") == "muzzle=muzzle_suppressor_01", "Aufsatz gespeichert") panel.set_part("ar1", "muzzle", "muzzle_suppressor_01") _check(not main.doc["loadout"]["attachments"].has("ar1"), "Aufsatz für Nicht-Loadout-Waffe ignoriert") _check(SvmapIO.validate_map(_signed(main.doc)).is_empty(), "Map mit Loadout besteht V1–V18") panel.set_weapons("ar1", "") _check(not main.doc["loadout"]["attachments"].has("sr1"), "Waffenwechsel verwirft Aufsätze der alten Waffe") # Undo/Redo main.history.undo() main.call("_refresh_all") _check(main.doc["loadout"]["primary"] == "sr1" and main.doc["loadout"]["attachments"].has("sr1"), "Undo: Waffenwechsel zurück") main.history.undo() main.history.undo() main.history.undo() main.call("_refresh_all") _check(not main.doc.has("loadout") and not panel.fixed_box.visible, "Undo bis Start: Block weg, UI nachgezogen") main.history.redo() main.call("_refresh_all") _check(main.doc.has("loadout") and panel.is_fixed(), "Redo: fest wieder da") # Zurück auf Spieler-Loadout entfernt den Block panel.set_fixed(false) _check(not main.doc.has("loadout"), "Spieler-Loadout entfernt den Block") # Speichern/Laden panel.set_fixed(true) panel.set_weapons("sr2", "pistol2") var path := "user://loadout_test.svmap" var doc2: Dictionary = main.doc.duplicate(true) SvmapIO.sign_map(doc2) var res := SvmapIO.save_to_file(path, doc2) _check(res["ok"], "Speichern ok: " + str(res["errors"])) var back := SvmapIO.load_from_file(path) _check(back["ok"] and back["data"]["loadout"]["primary"] == "sr2", "Laden: Loadout bleibt erhalten") func _signed(d: Dictionary) -> Dictionary: var c := d.duplicate(true) SvmapIO.sign_map(c) return c