extends SceneTree ## Blickrichtung an Spawn-Punkten und Conquest-Zonen (optionales Feld yaw_deg). ## Ausführen: godot --headless --path . --script res://tests/test_spawn_yaw.gd var failures := 0 func _check(cond: bool, label: String) -> void: if not cond: failures += 1 print("FAIL: ", label) func _fwd(deg: float) -> Vector2: var r := deg_to_rad(deg) return Vector2(-sin(r), -cos(r)) func _init() -> void: SpawnOps.edit_set = ModusKatalog.SPAWN_SET_BASE var doc := SvmapDocument.create_new("Blick", 512.0, "mittag") var p := SpawnOps.add_zone(doc, 0, -50.0, 0.0) var pid := str(p["id"]) _check(not SpawnOps.has_yaw(p), "neuer Punkt ohne Feld (alte Karten bleiben gleich)") # Standard: zur Kartenmitte (0,0) — von -50 aus also nach +X. _check(_fwd(SpawnOps.effective_yaw(doc, p)).distance_to(Vector2(1, 0)) < 0.01, "Standard zeigt zur Mitte") _check(SpawnOps.set_point_yaw(doc, 0, pid, 450.0), "setzen") _check(is_equal_approx(float(p["yaw_deg"]), 90.0), "normalisiert auf 0–360") SpawnOps.set_point_yaw(doc, 0, pid, null) _check(not p.has("yaw_deg"), "null räumt das Feld weg") _check(not SpawnOps.set_point_yaw(doc, 0, "gibtsnicht", 1.0), "unbekannte ID") # Spiegeln: die Blickrichtung muss wirklich gespiegelt sein. for yaw in [0.0, 30.0, 135.0, 290.0]: var f := _fwd(yaw) _check(_fwd(SymmetryCore.mirror_facing(SymmetryCore.Mode.AXIS_X, yaw)).distance_to(Vector2(-f.x, f.y)) < 0.01, "Achse X %d" % int(yaw)) _check(_fwd(SymmetryCore.mirror_facing(SymmetryCore.Mode.AXIS_Z, yaw)).distance_to(Vector2(f.x, -f.y)) < 0.01, "Achse Z %d" % int(yaw)) _check(_fwd(SymmetryCore.mirror_facing(SymmetryCore.Mode.POINT, yaw)).distance_to(-f) < 0.01, "Punkt %d" % int(yaw)) # Zwilling erbt und folgt. var doc2 := SvmapDocument.create_new("Blick2", 512.0, "mittag") var a := SpawnOps.add_zone(doc2, 0, -40.0, 10.0) SpawnOps.write_yaw(a, 30.0) var tool_script := load("res://src/editor/spawn_tool.gd") tool_script.spawn_mirror_add(doc2, 0, str(a["id"]), SymmetryCore.Mode.POINT) var twin_id: String = tool_script.spawn_mirror_partner(doc2, str(a["id"])) var twin: Dictionary = tool_script._spawn_point_of(doc2, 1, twin_id) _check(is_equal_approx(float(twin.get("yaw_deg", -1.0)), 210.0), "Zwilling schaut gespiegelt") tool_script.spawn_mirror_yaw(doc2, str(a["id"]), null, SymmetryCore.Mode.POINT) _check(not twin.has("yaw_deg"), "Standard gilt auch für den Zwilling") # Prüfung: Unsinn wird abgelehnt, das Feld selbst nicht. var bounds: Dictionary = doc["bounds"] var zone := {"id": "Z1", "pos": [0.0, 0.0, 0.0], "radius_m": 12.0, "yaw_deg": 45.0} _check(ModusKatalog._validate_zone_list([zone], "V22", "Zone", bounds).is_empty(), "Zone mit yaw_deg gültig") zone["yaw_deg"] = "Norden" _check(not ModusKatalog._validate_zone_list([zone], "V22", "Zone", bounds).is_empty(), "Zone mit Text-yaw abgelehnt") print("ALL OK" if failures == 0 else "FAILED: %d" % failures) quit(0 if failures == 0 else 1)