first commit
This commit is contained in:
289
tests/input_test.gd
Normal file
289
tests/input_test.gd
Normal file
@@ -0,0 +1,289 @@
|
||||
extends Node
|
||||
## Prüft die tatsächliche Eingabekette: Events -> GUI -> _unhandled_input.
|
||||
var main
|
||||
var step := 0
|
||||
var wait := 0.0
|
||||
var ok := 0
|
||||
var fail := 0
|
||||
var y0 := 0.0
|
||||
var p0 := 0.0
|
||||
var s0 := 0.0
|
||||
var x0 := 0.0
|
||||
var m0 := 0
|
||||
var n0 := 0
|
||||
|
||||
func chk(name: String, cond: bool, info := "") -> void:
|
||||
if cond:
|
||||
ok += 1
|
||||
print(" OK %s %s" % [name, info])
|
||||
else:
|
||||
fail += 1
|
||||
print(" FAIL %s %s" % [name, info])
|
||||
|
||||
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 _mouse(dx: float, dy: float) -> void:
|
||||
var e := InputEventMouseMotion.new()
|
||||
e.relative = Vector2(dx, dy)
|
||||
e.position = get_viewport().get_visible_rect().size * 0.5
|
||||
e.global_position = e.position
|
||||
Input.parse_input_event(e)
|
||||
|
||||
## Stellt den Spieler vor einen Hotspot und laesst ihn hinsehen.
|
||||
func goto(car_index: int, kind: String) -> bool:
|
||||
var car = main.train.cars[car_index]
|
||||
for h in car.hotspots:
|
||||
if String(h["kind"]) != kind:
|
||||
continue
|
||||
var pos: Vector3 = h["pos"]
|
||||
var hs: float = car.center_s + pos.z
|
||||
var p = main.player
|
||||
for dz in [-1.0, 1.0, -1.4, 1.4, -0.7, 0.7]:
|
||||
for px in [pos.x * 0.35, 0.0, pos.x * 0.6, -pos.x * 0.35]:
|
||||
if p._blocked(px, hs + dz):
|
||||
continue
|
||||
p.x = px
|
||||
p.s = hs + dz
|
||||
p.yaw = atan2(pos.x - px, hs - p.s)
|
||||
p.pitch = clampf(atan2(pos.y - (2.72), Vector2(pos.x - px, hs - p.s).length()), -1.2, 1.2)
|
||||
return true
|
||||
return false
|
||||
|
||||
func _process(d):
|
||||
if main == null:
|
||||
main = get_tree().current_scene
|
||||
return
|
||||
if not main.started:
|
||||
main._start_solo()
|
||||
return
|
||||
if wait > 0.0:
|
||||
wait -= d
|
||||
return
|
||||
var p = main.player
|
||||
match step:
|
||||
0:
|
||||
chk("Maus gefangen", Input.mouse_mode == Input.MOUSE_MODE_CAPTURED,
|
||||
"mode=%d" % Input.mouse_mode)
|
||||
y0 = p.yaw
|
||||
p0 = p.pitch
|
||||
_mouse(120.0, 60.0)
|
||||
wait = 0.3
|
||||
1:
|
||||
chk("Mausblick horizontal", absf(p.yaw - y0) > 0.05,
|
||||
"yaw %.3f -> %.3f" % [y0, p.yaw])
|
||||
chk("Mausblick vertikal", absf(p.pitch - p0) > 0.05,
|
||||
"pitch %.3f -> %.3f" % [p0, p.pitch])
|
||||
p.yaw = 0.0
|
||||
p.pitch = 0.0
|
||||
s0 = p.s
|
||||
_key(KEY_W, true)
|
||||
wait = 1.0
|
||||
2:
|
||||
_key(KEY_W, false)
|
||||
chk("Vorwärts laufen", p.s - s0 > 0.5, "ds=%.2f" % (p.s - s0))
|
||||
x0 = p.x
|
||||
_key(KEY_D, true)
|
||||
wait = 0.6
|
||||
3:
|
||||
_key(KEY_D, false)
|
||||
chk("Seitwärts laufen", absf(p.x - x0) > 0.2, "dx=%.2f" % (p.x - x0))
|
||||
# Ans Fahrpult stellen und E drücken
|
||||
var loco = main.train.cars[0]
|
||||
p.s = loco.center_s + loco.inner_z1 - 1.7
|
||||
p.x = 0.0
|
||||
p.yaw = 0.0
|
||||
p.pitch = 0.0
|
||||
wait = 0.3
|
||||
4:
|
||||
chk("Hotspot erkannt", String(p.hotspot.get("kind", "")) == "drive",
|
||||
"kind=%s" % String(p.hotspot.get("kind", "-")))
|
||||
_key(KEY_E, true)
|
||||
wait = 0.3
|
||||
5:
|
||||
_key(KEY_E, false)
|
||||
chk("E übernimmt Steuerung", main.driver_id == 1, "driver=%d" % main.driver_id)
|
||||
chk("Spieler im Fahrmodus", p.mode == 1, "mode=%d" % p.mode)
|
||||
_key(KEY_W, true)
|
||||
wait = 1.5
|
||||
6:
|
||||
_key(KEY_W, false)
|
||||
chk("W gibt Gas", main.train.speed > 1.0, "v=%.1f" % main.train.speed)
|
||||
_key(KEY_S, true)
|
||||
wait = 3.0
|
||||
7:
|
||||
_key(KEY_S, false)
|
||||
chk("S bremst", main.train.speed < 0.05, "v=%.2f" % main.train.speed)
|
||||
_key(KEY_E, true)
|
||||
wait = 0.3
|
||||
8:
|
||||
_key(KEY_E, false)
|
||||
chk("E gibt Steuerung frei", main.driver_id == 0)
|
||||
_key(KEY_V, true)
|
||||
_key(KEY_V, false)
|
||||
wait = 0.3
|
||||
9:
|
||||
chk("V schaltet auf Außenkamera", main.cam_rig.is_active())
|
||||
_key(KEY_V, true)
|
||||
_key(KEY_V, false)
|
||||
wait = 0.3
|
||||
10:
|
||||
chk("V schaltet zurück", p.camera.current)
|
||||
_key(KEY_ESCAPE, true)
|
||||
_key(KEY_ESCAPE, false)
|
||||
wait = 0.3
|
||||
11:
|
||||
chk("Esc gibt Maus frei", Input.mouse_mode != Input.MOUSE_MODE_CAPTURED)
|
||||
p.capture_mouse(true)
|
||||
# Zweiter Spieler darf nicht dazwischenfunken
|
||||
main._srv_toggle_drive(1)
|
||||
main._srv_toggle_drive(2)
|
||||
chk("Führerstand exklusiv", main.driver_id == 1, "driver=%d" % main.driver_id)
|
||||
main._srv_toggle_drive(1)
|
||||
# Zug mit Speisewagen und Gästen ausstatten
|
||||
main.train.consist = ["coach", "dining", "freight"] as Array[String]
|
||||
main._rebuild_train()
|
||||
main._park_at(main.stations[0])
|
||||
for i in 4:
|
||||
main.spawn_passenger(0, 2)
|
||||
wait = 7.0
|
||||
12:
|
||||
chk("Gäste eingestiegen", _seated() >= 4, "seated=%d" % _seated())
|
||||
chk("Zum Depot-Terminal gelaufen", goto(0, "shop"))
|
||||
wait = 0.3
|
||||
13:
|
||||
chk("Terminal im Blick", String(p.hotspot.get("kind", "")) == "shop",
|
||||
"kind=%s" % String(p.hotspot.get("kind", "-")))
|
||||
_key(KEY_E, true); _key(KEY_E, false)
|
||||
wait = 0.4
|
||||
14:
|
||||
chk("Terminal offen", main.shop.is_open)
|
||||
main.shop._tabs.current_tab = 1
|
||||
wait = 0.3
|
||||
15:
|
||||
var btn := _find_button(main.shop, "Kaufen")
|
||||
chk("Kaufen-Knopf sichtbar", btn != null)
|
||||
m0 = main.money
|
||||
n0 = main.train.consist.size()
|
||||
if btn != null:
|
||||
_click(btn.get_global_rect().get_center())
|
||||
wait = 0.5
|
||||
16:
|
||||
chk("Klick im Laden kauft", main.train.consist.size() == n0 + 1 and main.money < m0,
|
||||
"consist %d->%d, geld %d->%d" % [n0, main.train.consist.size(), m0, main.money])
|
||||
_key(KEY_ESCAPE, true); _key(KEY_ESCAPE, false)
|
||||
wait = 0.4
|
||||
17:
|
||||
chk("Terminal geschlossen", not main.shop.is_open)
|
||||
chk("Gäste überleben den Umbau", _seated() >= 4, "seated=%d" % _seated())
|
||||
chk("Maus wieder gefangen", Input.mouse_mode == Input.MOUSE_MODE_CAPTURED)
|
||||
chk("Zur Theke gelaufen", goto(_car_of("tap"), "tap"))
|
||||
wait = 0.3
|
||||
18:
|
||||
chk("Theke im Blick", String(p.hotspot.get("kind", "")) == "tap",
|
||||
"kind=%s" % String(p.hotspot.get("kind", "-")))
|
||||
_key(KEY_E, true); _key(KEY_E, false)
|
||||
wait = 0.3
|
||||
19:
|
||||
chk("Getränk aufgenommen", p.carrying > 0, "carrying=%d" % p.carrying)
|
||||
chk("Zum Gast gelaufen", _goto_occupied_seat())
|
||||
wait = 0.3
|
||||
20:
|
||||
chk("Gast im Blick", String(p.hotspot.get("kind", "")) == "seat",
|
||||
"kind=%s" % String(p.hotspot.get("kind", "-")))
|
||||
m0 = main.money
|
||||
_key(KEY_E, true); _key(KEY_E, false)
|
||||
wait = 0.3
|
||||
21:
|
||||
chk("Ticket bringt Geld", main.money > m0, "+%d €" % (main.money - m0))
|
||||
var occ = _seat_occupant()
|
||||
chk("Gast erreichbar", occ != null)
|
||||
if occ != null:
|
||||
occ.wants_drink = true
|
||||
occ.served = false
|
||||
m0 = main.money
|
||||
_key(KEY_E, true); _key(KEY_E, false)
|
||||
wait = 0.3
|
||||
22:
|
||||
var occ2 = _seat_occupant()
|
||||
chk("Serviert", occ2 != null and occ2.served)
|
||||
chk("Trinkgeld", main.money > m0, "+%d €" % (main.money - m0))
|
||||
chk("Getränk verbraucht", p.carrying == 0, "carrying=%d" % p.carrying)
|
||||
chk("Zur Ladekonsole gelaufen", goto(_car_of("load"), "load"))
|
||||
wait = 0.3
|
||||
23:
|
||||
chk("Konsole im Blick", String(p.hotspot.get("kind", "")) == "load",
|
||||
"kind=%s" % String(p.hotspot.get("kind", "-")))
|
||||
main.stations[0].stock = 10.0
|
||||
_key(KEY_E, true)
|
||||
wait = 2.5
|
||||
24:
|
||||
_key(KEY_E, false)
|
||||
chk("E halten lädt Ware", main.train.total_cargo() > 0,
|
||||
"cargo=%d" % main.train.total_cargo())
|
||||
print("== %d ok, %d fail ==" % [ok, fail])
|
||||
get_tree().quit(1 if fail > 0 else 0)
|
||||
step += 1
|
||||
|
||||
func _seated() -> int:
|
||||
var n := 0
|
||||
for pa in main.passengers:
|
||||
if pa.state == 2:
|
||||
n += 1
|
||||
return n
|
||||
|
||||
func _seat_occupant():
|
||||
var h = main.player.hotspot
|
||||
if String(h.get("kind", "")) != "seat":
|
||||
return null
|
||||
return main.train.cars[int(h["car"])].seats[int(h["seat"])]["occupant"]
|
||||
|
||||
func _click(pos: Vector2) -> void:
|
||||
for pressed in [true, false]:
|
||||
var e := InputEventMouseButton.new()
|
||||
e.button_index = MOUSE_BUTTON_LEFT
|
||||
e.pressed = pressed
|
||||
e.position = pos
|
||||
e.global_position = pos
|
||||
Input.parse_input_event(e)
|
||||
|
||||
func _find_button(n: Node, text: String) -> Button:
|
||||
if n is Button and (n as Button).text == text and not (n as Button).disabled:
|
||||
return n
|
||||
for c in n.get_children():
|
||||
var r := _find_button(c, text)
|
||||
if r != null:
|
||||
return r
|
||||
return null
|
||||
|
||||
func _car_of(kind: String) -> int:
|
||||
for ci in main.train.cars.size():
|
||||
for h in main.train.cars[ci].hotspots:
|
||||
if String(h["kind"]) == kind:
|
||||
return ci
|
||||
return -1
|
||||
|
||||
func _goto_occupied_seat() -> bool:
|
||||
var pl = main.player
|
||||
for ci in main.train.cars.size():
|
||||
var car = main.train.cars[ci]
|
||||
for h in car.hotspots:
|
||||
if String(h["kind"]) != "seat":
|
||||
continue
|
||||
if car.seats[int(h["seat"])]["occupant"] == null:
|
||||
continue
|
||||
var pos: Vector3 = h["pos"]
|
||||
var hs: float = car.center_s + pos.z
|
||||
for dz in [0.0, -0.8, 0.8, -1.2, 1.2]:
|
||||
if pl._blocked(0.0, hs + dz):
|
||||
continue
|
||||
pl.x = 0.0
|
||||
pl.s = hs + dz
|
||||
pl.yaw = atan2(pos.x, hs - pl.s)
|
||||
pl.pitch = 0.0
|
||||
return true
|
||||
return false
|
||||
Reference in New Issue
Block a user