This commit is contained in:
Team3
2026-09-16 12:08:04 +02:00
parent 936773c4e9
commit 89fad5dc7a
12 changed files with 493 additions and 167 deletions

View File

@@ -760,7 +760,8 @@ func _wege_pruefen(welt_name: String, places: Dictionary, liste: Array,
var nach: String = String(r[i][1])
if von == nach:
continue
var dauer := _weg_laenge(places, von, nach, netz, anker) / Bewohner.GEHTEMPO
var dauer := _weg_laenge(places, von, nach, m.get("etage", {}), netz, anker) \
/ Bewohner.GEHTEMPO
var slot_h: float = (float(r[i + 1][0]) - float(r[i][0])) if i + 1 < r.size() \
else (24.0 - float(r[i][0]))
var fenster := slot_h * sek_pro_stunde
@@ -775,11 +776,11 @@ func _wege_pruefen(welt_name: String, places: Dictionary, liste: Array,
p(alles_ok, "%s — jeder Weg passt, engster Fall: %s" % [welt_name, engste_text])
func _weg_laenge(places: Dictionary, von: String, nach: String,
func _weg_laenge(places: Dictionary, von: String, nach: String, etagen: Dictionary,
netz: Netz = null, anker: Dictionary = {}) -> float:
var pts: Array = Orte.route(places, von, nach, Vector3.ZERO, netz, anker)
var pts: Array = Orte.route_voll(places, von, nach, Vector3.ZERO, etagen, netz, anker)
var l := 0.0
var pos := Orte.center(places, von)
var pos := Orte.center(places, von) + Vector3(0, Orte.hoehe(int(etagen.get(von, 0))), 0)
for pt in pts:
l += pos.distance_to(pt)
pos = pt
@@ -789,15 +790,14 @@ func _weg_laenge(places: Dictionary, von: String, nach: String,
func test_geist() -> void:
abschnitt("Geist-Bewegung")
p(main.player.mode == Player.Mode.GEIST, "Spieler ist auf der Erde ein Geist")
p(main.player.collision_layer == 0 and main.player.collision_mask == 0,
"Der Geist kollidiert mit nichts — er schwebt durch Wände")
var vor: Vector3 = main.player.global_position
p(main.player.collision_mask == 1, "Der Geist stößt an Wände wie ein Mensch")
main.player.global_position = Vector3(0, 8.0, 0)
main.player.velocity = Vector3(6, 0, 0)
for i in range(30):
for i in range(60):
await get_tree().physics_frame
p(main.player.global_position.x > 0.5, "Der Geist bewegt sich frei durch den Raum")
p(absf(main.player.global_position.y - 8.0) < 0.5, "Ohne Schwerkraft fällt er nicht")
p(main.player.global_position.x > 0.5, "Der Geist bewegt sich durch den Park")
p(main.player.global_position.y < 0.6 and main.player.is_on_floor(),
"Die Schwerkraft holt ihn auf den Boden (y = %.2f)" % main.player.global_position.y)
var lena: Bewohner = welt().humans[0]
var davor: Vector3 = lena.global_position
@@ -817,6 +817,8 @@ func test_charakter() -> void:
sp.set_mode(Player.Mode.GEIST)
sp.look_enabled = true
sp.folgt = null
var moment_merker: Dictionary = Game.situation.duplicate(true)
Game.situation = {} # ein laufender Moment ließe die Farbe flackern
p(sp._augen.size() == 2 and sp._augen[0].position.z < 0.0, "Zwei Augen, vorn am Kopf")
p(sp._funken.size() == Player.FUNKEN_MAX, "%d Funken stehen bereit" % Player.FUNKEN_MAX)
for i in range(60):
@@ -835,7 +837,11 @@ func test_charakter() -> void:
for i in range(90):
await get_tree().physics_frame
p(_farbabstand(sp._farbe, Player.FARBE_FOLGE) < 0.1, "Beim Verfolgen leuchtet er warm")
Game.situation = moment_merker
sp.folgt = null
sp.global_position = Vector3(0, 0.5, 9.0) # freier Rasen im Park
sp.velocity = Vector3.ZERO
sp.yaw = 0.0
Input.action_press("vor")
for i in range(40):
await get_tree().physics_frame
@@ -1016,12 +1022,23 @@ func test_kamera_und_etagen() -> void:
p(wand_weg >= 2 and wand_weg < (bau["waende"][0] as Array).size(),
"Die Wände zur Kamera hin sind weg, die hinteren bleiben (%d von %d Teile)" %
[wand_weg, (bau["waende"][0] as Array).size()])
Input.action_press("steigen")
for i in range(60):
var stufen: Array = Orte.treppen_lauf(HumanDB.PLACES, heim, 0)
sp.global_position = (stufen[0] as Vector3) + Vector3(0, 0.3, 0)
sp.velocity = Vector3.ZERO
var lauf: Vector3 = stufen[1] - stufen[0]
lauf.y = 0.0
sp.yaw = atan2(-lauf.x, -lauf.z)
Input.action_press("vor")
var hoechste := 0.0
for i in range(70):
await get_tree().physics_frame
Input.action_release("steigen")
p(absf(sp.global_position.y - (1.4 + Orte.ETAGE)) < 0.1,
"Leertaste hebt den Geist genau ein Stockwerk (y = %.1f)" % sp.global_position.y)
hoechste = maxf(hoechste, sp.global_position.y)
Input.action_release("vor")
p(hoechste > Orte.ETAGE - 0.3,
"Über die Treppe kommt der Geist in den ersten Stock (y = %.1f)" % hoechste)
sp.global_position = t1 + Vector3(0, 0.3, 0)
sp.velocity = Vector3.ZERO
await get_tree().physics_frame
welt()._process(0.05)
p((bau["etagen"][0] as Node3D).visible and (bau["etagen"][1] as Node3D).visible
and (n < 3 or not (bau["etagen"][2] as Node3D).visible),
@@ -1102,7 +1119,14 @@ func test_verfolgung() -> void:
main.player.yaw = 0.0
var mensch: Bewohner = welt().humans[0]
Game.active_mission = str(mensch.data["id"])
main.player.global_position = mensch.global_position + Vector3(0, 1.5, 2.0)
# kurz vor seinem nächsten Ortswechsel einsteigen, damit er auch losgeht
var routine: Array = mensch.data["routine"]
for k in range(routine.size()):
if str(routine[k][1]) != mensch.place and float(routine[k][0]) > 0.5:
Game.time_h = float(routine[k][0]) - 0.4
break
schritte(5)
main.player.global_position = mensch.global_position + Vector3(0, 0.3, 0)
main.player.velocity = Vector3.ZERO
main._process(0.05)
p(main._fokus_mensch == mensch, "Der Mensch ist im Fokus")
@@ -1114,9 +1138,8 @@ func test_verfolgung() -> void:
var weiteste := 0.0
var gelaufen := false
var im_fokus := 0
for i in range(900):
schritte(1)
await get_tree().physics_frame
for i in range(2400):
await get_tree().physics_frame # nur die Engine steppt: sonst laufen die Menschen doppelt
if not mensch._path.is_empty():
gelaufen = true
if main._fokus_mensch == mensch:
@@ -1124,8 +1147,8 @@ func test_verfolgung() -> void:
weiteste = maxf(weiteste,
main.player.global_position.distance_to(mensch.global_position))
p(gelaufen, "Er wechselt in dieser Zeit den Ort")
p(weiteste < 6.0, "Der Geist bleibt die ganze Zeit dicht dabei (höchstens %.1f)" % weiteste)
p(im_fokus > 850, "Und behält ihn im Fokus (%d von 900 Schritten)" % im_fokus)
p(weiteste < 8.0, "Der Geist bleibt die ganze Zeit dicht dabei (höchstens %.1f)" % weiteste)
p(im_fokus > 2000, "Und behält ihn im Fokus (%d von 2400 Schritten)" % im_fokus)
p(main._fokus_mensch == mensch or main.player.folgt == mensch,
"Unterwegs bleibt er notierbar")
@@ -2203,8 +2226,8 @@ func test_journal_ueberall() -> void:
func test_steuerung() -> void:
abschnitt("Steuerung")
var aktionen := ["vor", "zurueck", "links", "rechts", "steigen", "sinken",
"interagieren", "journal", "tempo_1", "tempo_2", "tempo_3"]
var aktionen := ["vor", "zurueck", "links", "rechts", "steigen", "drehen",
"interagieren", "folgen", "notieren", "journal", "tempo_1", "tempo_2", "tempo_3"]
var alle := true
for a in aktionen:
if not InputMap.has_action(a) or InputMap.action_get_events(a).is_empty():
@@ -2236,23 +2259,39 @@ func test_steuerung() -> void:
p(main.player.global_position.x > 1.0,
"D schiebt den Spieler nach rechts (x = %.1f)" % main.player.global_position.x)
main.player.global_position = Vector3(0, 8.0, 0)
# Ein geschlossener Klotz hält ihn auf: von der Straße aus gegen die Wand
var war_erde := main.auf_erde
if not war_erde:
main._erde()
await get_tree().process_frame
main.player.look_enabled = true
var klotz: Dictionary = {}
var richtung := Vector3.ZERO
for b in welt()._bauten:
if not bool(b.get("voll", false)):
continue
for pz in HumanDB.PARZELLEN:
if (pz["pos"] as Vector3).distance_to(b["c"]) < 0.1:
klotz = b
richtung = Orte.DIR_VEC[pz["dir"]]
if not klotz.is_empty():
break
p(not klotz.is_empty(), "Es gibt geschlossene Klötze")
var kc: Vector3 = klotz["c"]
var kg: Vector2 = klotz["size"]
var halb: float = (kg.y if absf(richtung.z) > 0.0 else kg.x) * 0.5
main.player.global_position = kc + richtung * (halb + 2.0) + Vector3(0, 0.3, 0)
main.player.velocity = Vector3.ZERO
Input.action_press("steigen")
for i in range(40):
main.player.yaw = atan2(richtung.x, richtung.z) # "vor" zeigt zum Klotz
Input.action_press("vor")
for i in range(60):
await get_tree().physics_frame
Input.action_release("steigen")
p(main.player.global_position.y > 9.0,
"Leertaste lässt den Geist steigen (y = %.1f)" % main.player.global_position.y)
main.player.velocity = Vector3.ZERO
var hoch: float = main.player.global_position.y
Input.action_press("sinken")
for i in range(40):
await get_tree().physics_frame
Input.action_release("sinken")
p(main.player.global_position.y < hoch - 1.0,
"Umschalt lässt den Geist sinken (y = %.1f)" % main.player.global_position.y)
Input.action_release("vor")
var tiefe_im_klotz: float = halb - (main.player.global_position - kc).dot(richtung)
p(tiefe_im_klotz < 0.6, "Wände halten den Geist auf (%.1f m in der Wand)" % maxf(0.0, tiefe_im_klotz))
if not war_erde:
main._traumwelt() # die folgenden Messungen erwarten die Traumwelt
await get_tree().process_frame
## Nach jedem Einsatz braucht eine Technik Ruhe. Ein Weg allein deckt daher