update
This commit is contained in:
91
tests/_probe.gd
Normal file
91
tests/_probe.gd
Normal file
@@ -0,0 +1,91 @@
|
||||
extends Node
|
||||
var main: Node3D
|
||||
|
||||
func _ready() -> void:
|
||||
seed(20240)
|
||||
main = load("res://scenes/main.tscn").instantiate()
|
||||
add_child(main)
|
||||
await get_tree().process_frame
|
||||
main.ui.schliessen()
|
||||
main._erde()
|
||||
await get_tree().process_frame
|
||||
# B: engste Wege mit Türen und Treppen
|
||||
var liste: Array = []
|
||||
for m in HumanDB.LIST:
|
||||
var r: Array = m["routine"]
|
||||
for i in range(r.size()):
|
||||
var von: String = String(r[i - 1][1]) if i > 0 else String(r[r.size() - 1][1])
|
||||
var nach: String = String(r[i][1])
|
||||
if von == nach:
|
||||
continue
|
||||
var pts: Array = Orte.route_voll(HumanDB.PLACES, von, nach, Vector3.ZERO, m.get("etage", {}), HumanDB.NETZ, HumanDB.ANKER)
|
||||
var l := 0.0
|
||||
var pos := Orte.center(HumanDB.PLACES, von) + Vector3(0, Orte.hoehe(int(m.get("etage", {}).get(von, 0))), 0)
|
||||
for pt in pts:
|
||||
l += pos.distance_to(pt)
|
||||
pos = pt
|
||||
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]))
|
||||
liste.append([slot_h * 15.0 - l / 8.0, "%s %s->%s %.1fs / %.0fs" % [m["name"], von, nach, l / 8.0, slot_h * 15.0]])
|
||||
liste.sort_custom(func(a, b): return a[0] < b[0])
|
||||
for k in range(6):
|
||||
print("ENG %s" % liste[k][1])
|
||||
# C: Treppe hoch, was blockiert?
|
||||
var sp: Player = main.player
|
||||
var oben: Bewohner = null
|
||||
for m in main.welt.humans:
|
||||
if m.etage(str(m.data["heim"])) > 0:
|
||||
oben = m
|
||||
break
|
||||
var heim := str(oben.data["heim"])
|
||||
var pl: Dictionary = HumanDB.PLACES[heim]
|
||||
print("HAUS %s size=%s dir=%s etagen=%d" % [heim, str(pl["size"]), pl["dir"], Orte.etagen(HumanDB.PLACES, heim)])
|
||||
var t1 := Orte.treppe(HumanDB.PLACES, heim, 1)
|
||||
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
|
||||
hoechste = maxf(hoechste, sp.global_position.y)
|
||||
if i % 10 == 9 or i == 69:
|
||||
var k := sp.get_last_slide_collision()
|
||||
var txt := "-"
|
||||
if k != null and k.get_collider() != null:
|
||||
var body: Node = k.get_collider()
|
||||
var mi: Node = body.get_parent()
|
||||
txt = "%s pos=%s size=%s normal=%s" % [mi.name, str(mi.global_position), str((mi as MeshInstance3D).mesh.get("size")) if mi is MeshInstance3D else "?", str(k.get_normal())]
|
||||
print("TREPPE f=%d pos=%s y=%.2f koll=%s" % [i, str(sp.global_position), sp.global_position.y, txt])
|
||||
Input.action_release("vor")
|
||||
print("TREPPE hoechste=%.2f t1=%s" % [hoechste, str(t1)])
|
||||
# E: Verfolgung -- wo reißt die Leine?
|
||||
var mensch: Bewohner = main.welt.humans[0]
|
||||
sp.global_position = mensch.global_position + Vector3(0, 0.3, 0)
|
||||
sp.velocity = Vector3.ZERO
|
||||
sp.folgt = mensch
|
||||
var weiteste := 0.0
|
||||
for i in range(2400):
|
||||
await get_tree().physics_frame
|
||||
var d := sp.global_position.distance_to(mensch.global_position)
|
||||
if d > weiteste:
|
||||
weiteste = d
|
||||
if d > 6.0 and i % 5 == 0:
|
||||
var k := sp.get_last_slide_collision()
|
||||
var txt := "-"
|
||||
if k != null and k.get_collider() != null:
|
||||
var mi: Node = (k.get_collider() as Node).get_parent()
|
||||
txt = "%s pos=%s" % [mi.name, str(mi.global_position)]
|
||||
print("LEINE f=%d d=%.1f geist=%s mensch=%s ort=%s pfad=%d koll=%s" % [i, d, str(sp.global_position), str(mensch.global_position), mensch.place, mensch._path.size(), txt])
|
||||
print("LEINE weiteste=%.1f" % weiteste)
|
||||
# D: wieder anhängen
|
||||
sp.folgt = null
|
||||
sp.global_position = mensch.global_position + Vector3(0, 1.5, 2.0)
|
||||
sp.velocity = Vector3.ZERO
|
||||
main._process(0.05)
|
||||
print("ANHAENGEN fokus_mensch=%s fokus=%s d=%.2f geist=%s mensch=%s auf_erde=%s offen=%s" % [
|
||||
str(main._fokus_mensch), str(main._fokus), sp.global_position.distance_to(mensch.global_position + Vector3(0, 1, 0)),
|
||||
str(sp.global_position), str(mensch.global_position), str(main.auf_erde), str(main.ui.offen)])
|
||||
get_tree().quit()
|
||||
6
tests/_probe.tscn
Normal file
6
tests/_probe.tscn
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://tests/_probe.gd" id="1_p"]
|
||||
|
||||
[node name="Probe" type="Node"]
|
||||
script = ExtResource("1_p")
|
||||
54
tests/_probe2.gd
Normal file
54
tests/_probe2.gd
Normal file
@@ -0,0 +1,54 @@
|
||||
extends Node
|
||||
var main: Node3D
|
||||
const OUT := "user://treppe/"
|
||||
|
||||
func _ready() -> void:
|
||||
seed(7)
|
||||
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path(OUT))
|
||||
main = load("res://scenes/main.tscn").instantiate()
|
||||
add_child(main)
|
||||
await get_tree().process_frame
|
||||
main.ui.schliessen()
|
||||
Game.time_h = 11.0
|
||||
main._erde()
|
||||
await get_tree().process_frame
|
||||
var sp: Player = main.player
|
||||
var oben: Bewohner = null
|
||||
for m in main.welt.humans:
|
||||
if m.etage(str(m.data["heim"])) > 0 and Orte.etagen(HumanDB.PLACES, str(m.data["heim"])) >= 3:
|
||||
oben = m
|
||||
break
|
||||
var heim := str(oben.data["heim"])
|
||||
# 1 Erdgeschoss, am Fuß der Treppe
|
||||
var t0 := Orte.treppe(HumanDB.PLACES, heim, 0)
|
||||
var innen := Orte.innen_tuer(HumanDB.PLACES, heim)
|
||||
sp.global_position = innen + Vector3(0, 0.3, 0)
|
||||
sp.velocity = Vector3.ZERO
|
||||
await knipse("1_erdgeschoss_treppe")
|
||||
# 2 auf dem Wendepodest im ersten Stock
|
||||
sp.global_position = Orte.treppe(HumanDB.PLACES, heim, 1) + Vector3(0, 0.3, 0)
|
||||
sp.velocity = Vector3.ZERO
|
||||
await knipse("2_podest_erster_stock")
|
||||
# 3 Leine auf der Straße: an jemanden hängen, der unterwegs ist
|
||||
var laeufer: Bewohner = null
|
||||
for i in range(3000):
|
||||
await get_tree().process_frame
|
||||
for m in main.welt.humans:
|
||||
if m._path.size() > 3 and m.etage(m.place) == 0:
|
||||
laeufer = m
|
||||
break
|
||||
if laeufer != null:
|
||||
break
|
||||
sp.global_position = laeufer.global_position + Vector3(0, 0.3, 0)
|
||||
sp.folgt = laeufer
|
||||
for i in range(240):
|
||||
await get_tree().process_frame
|
||||
await knipse("3_leine_strasse")
|
||||
get_tree().quit()
|
||||
|
||||
func knipse(name: String) -> void:
|
||||
for i in range(30):
|
||||
await get_tree().process_frame
|
||||
await RenderingServer.frame_post_draw
|
||||
get_viewport().get_texture().get_image().save_png(OUT + name + ".png")
|
||||
print("Bild: " + name)
|
||||
6
tests/_probe2.tscn
Normal file
6
tests/_probe2.tscn
Normal file
@@ -0,0 +1,6 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://tests/_probe2.gd" id="1_p"]
|
||||
|
||||
[node name="Probe" type="Node"]
|
||||
script = ExtResource("1_p")
|
||||
115
tests/verify.gd
115
tests/verify.gd
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user