176 lines
5.4 KiB
GDScript
176 lines
5.4 KiB
GDScript
extends Node
|
|
## Weichen: Route wählen, Übergang ohne Sprung, Bergstrecke erreichbar.
|
|
var main
|
|
var step := 0
|
|
var wait := 0.0
|
|
var ok := 0
|
|
var fail := 0
|
|
var last_pos := Vector3.ZERO
|
|
var worst_jump := 0.0
|
|
var jump_frames := 0
|
|
var _dbg := 0.0
|
|
var _cam_hits := 0
|
|
var _cam_pulled := 0
|
|
var _cam_yaw := 0
|
|
|
|
func chk(n: String, c: bool, i := "") -> void:
|
|
if c: ok += 1; print(" OK %s %s" % [n, i])
|
|
else: fail += 1; print(" FAIL %s %s" % [n, i])
|
|
|
|
func _key(c: int, d: bool) -> void:
|
|
var e := InputEventKey.new(); e.physical_keycode = c; e.keycode = c; e.pressed = d
|
|
Input.parse_input_event(e)
|
|
|
|
func _watch(d: float) -> void:
|
|
var t = main.train
|
|
var p: Vector3 = t.cars[t.cars.size() - 1].global_position
|
|
if last_pos != Vector3.ZERO and d > 0.0:
|
|
var jump := p.distance_to(last_pos)
|
|
var allowed: float = t.speed * d * 1.5 + 0.05
|
|
if jump > allowed:
|
|
jump_frames += 1
|
|
worst_jump = maxf(worst_jump, jump - t.speed * d)
|
|
last_pos = p
|
|
|
|
## Im Physik-Takt messen: dort bewegt sich der Zug genau einmal pro Aufruf.
|
|
func _physics_process(d: float) -> void:
|
|
if main != null and main.started and step >= 1 and step <= 8:
|
|
_watch(d)
|
|
|
|
func _process(d):
|
|
if main == null:
|
|
main = get_tree().current_scene
|
|
return
|
|
if not main.started:
|
|
main._start_solo()
|
|
return
|
|
var t = main.train
|
|
if wait > 0.0:
|
|
wait -= d
|
|
return
|
|
match step:
|
|
0:
|
|
chk("Drei Abschnitte", main.track.segments.size() == 3)
|
|
chk("Heimstrecke hat Weiche", main.track.is_switch(2))
|
|
chk("Sechs Bahnhöfe", main.stations.size() == 6)
|
|
main._park_at(main.stations[4]) # Ahornstadt, Heimstrecke
|
|
chk("Start auf Heimstrecke", t.seg == 2, "seg=%d" % t.seg)
|
|
chk("Weiche voraus erkannt", t.upcoming_switch() == 2)
|
|
var nxt: Array = t.next_station()
|
|
chk("Nächster Halt Waldkirch (links)", nxt[0].station_name == "Waldkirch",
|
|
"%s" % nxt[0].station_name)
|
|
t.switch_choice = 1
|
|
var nxt2: Array = t.next_station()
|
|
chk("Nächster Halt Bergblick (rechts)", nxt2[0].station_name == "Bergblick",
|
|
"%s" % nxt2[0].station_name)
|
|
t.switch_choice = 0
|
|
main.driver_id = 1
|
|
_key(KEY_W, true)
|
|
last_pos = Vector3.ZERO
|
|
wait = 1.0
|
|
1:
|
|
wait = 0.5
|
|
2:
|
|
if t.seg != 0:
|
|
step -= 1
|
|
wait = 0.3
|
|
_dbg += 0.3
|
|
if _dbg >= 2.0:
|
|
_dbg = 0.0
|
|
print("[dbg] seg=%d prog=%.1f/%.1f v=%.1f thr=%.1f driver=%d mode=%d" % [t.seg, t.progress,
|
|
main.track.seg_length(t.seg), t.speed, t.throttle, main.driver_id, main.player.mode])
|
|
else:
|
|
_key(KEY_W, false)
|
|
_key(KEY_S, true)
|
|
chk("Links -> Talstrecke", t.seg == 0, "seg=%d" % t.seg)
|
|
chk("Historie geführt", t.history.size() > 0 and t.history[t.history.size() - 1] == 2,
|
|
"%s" % [t.history])
|
|
chk("Letzter Wagen ohne Sprung", jump_frames == 0,
|
|
"Sprungframes=%d, größter Sprung %.2f m" % [jump_frames, worst_jump])
|
|
wait = 4.0
|
|
3:
|
|
_key(KEY_S, false)
|
|
main._park_at(main.stations[4])
|
|
t.switch_choice = 1
|
|
last_pos = Vector3.ZERO
|
|
jump_frames = 0
|
|
worst_jump = 0.0
|
|
_key(KEY_D, true)
|
|
_key(KEY_W, true)
|
|
wait = 1.0
|
|
4:
|
|
wait = 0.5
|
|
5:
|
|
if t.seg != 1:
|
|
step -= 1
|
|
wait = 0.3
|
|
else:
|
|
chk("Rechts -> Bergstrecke", t.seg == 1, "seg=%d" % t.seg)
|
|
chk("D hält die Weiche rechts", t.switch_choice == 1)
|
|
chk("Übergang rechts ohne Sprung", jump_frames == 0,
|
|
"Sprungframes=%d" % jump_frames)
|
|
_key(KEY_D, false)
|
|
wait = 0.5
|
|
6:
|
|
var nxt: Array = t.next_station()
|
|
chk("Bergblick voraus", nxt[0].station_name == "Bergblick", "%s" % nxt[0].station_name)
|
|
wait = 0.5
|
|
7:
|
|
# bis kurz vor Bergblick fahren, dann bremsen
|
|
var berg = main.stations[5]
|
|
var ahead: float = t.distance_ahead(berg)
|
|
if ahead > t.speed * t.speed / 16.0 + 8.0:
|
|
step -= 1
|
|
wait = 0.2
|
|
else:
|
|
_key(KEY_W, false)
|
|
_key(KEY_S, true)
|
|
wait = 6.0
|
|
8:
|
|
_key(KEY_S, false)
|
|
chk("Zug steht", t.speed < 0.05, "v=%.2f" % t.speed)
|
|
chk("Am Bergblick angekommen", t.docked_at != null and t.docked_at.station_name == "Bergblick",
|
|
"dock=%s" % ("-" if t.docked_at == null else t.docked_at.station_name))
|
|
# Sichtkontrolle: Kreuzung von oben
|
|
main._park_at(main.stations[4])
|
|
t.place_head(2, main.track.seg_length(2) - 6.0)
|
|
main._toggle_camera()
|
|
main.cam_rig.distance = 95.0
|
|
main.cam_rig.pitch = deg_to_rad(-70.0)
|
|
main.cam_rig.yaw = 0.4
|
|
wait = 1.0
|
|
9:
|
|
get_viewport().get_texture().get_image().save_png("user://junction.png")
|
|
t.place_head(0, main.track.seg_length(0) - 20.0)
|
|
main.cam_rig.snap_to(t.cars[0].global_position)
|
|
wait = 1.0
|
|
10:
|
|
get_viewport().get_texture().get_image().save_png("user://junction2.png")
|
|
# Kamera-Kollision: Fokus auf den Bahnsteig, rundherum drehen
|
|
var st = main.stations[0]
|
|
main.cam_rig.target = null
|
|
main.cam_rig.snap_to(st.global_position + Vector3(0, 0, 0))
|
|
main.cam_rig.distance = 30.0
|
|
main.cam_rig.pitch = deg_to_rad(-10.0)
|
|
_cam_hits = 0
|
|
_cam_yaw = 0
|
|
wait = 0.2
|
|
11:
|
|
if _cam_yaw < 12:
|
|
main.cam_rig.yaw = _cam_yaw * TAU / 12.0
|
|
_cam_yaw += 1
|
|
step -= 1
|
|
wait = 0.15
|
|
if main.cam_rig.blocked:
|
|
_cam_hits += 1
|
|
var dist: float = main.cam_rig._cam.global_position.distance_to(main.cam_rig.global_position)
|
|
if dist < 29.0:
|
|
_cam_pulled += 1
|
|
else:
|
|
chk("Kamera stößt am Gebäude an", _cam_hits > 0, "%d von 12 Richtungen" % _cam_hits)
|
|
chk("Kamera rückt davor", _cam_pulled == _cam_hits, "%d/%d" % [_cam_pulled, _cam_hits])
|
|
12:
|
|
print("== %d ok, %d fail ==" % [ok, fail])
|
|
get_tree().quit(1 if fail > 0 else 0)
|
|
step += 1
|