Move guard look handling to the _input stage, recapture the cursor on window-focus return and when clicking back into gameplay, and make HUD controls mouse-transparent. Add regression tests for yaw/pitch and HUD mouse filters. Verified under Xvfb with real relative mouse motion. Headless 237/237, Python 94/94, movement smoke 60 fps.
39 lines
1.5 KiB
GDScript
39 lines
1.5 KiB
GDScript
extends RefCounted
|
|
## Regression tests for the first-person mouse-look path and non-blocking HUD.
|
|
|
|
const GameManager := preload("res://src/game/game_manager.gd")
|
|
const GuardController := preload("res://src/game/guard_controller.gd")
|
|
const Hud := preload("res://src/game/ui/hud.gd")
|
|
|
|
func test_mouse_look_rotates_yaw_and_pitch() -> bool:
|
|
var root := Node3D.new()
|
|
var gm: Node = GameManager.new()
|
|
var guard: GuardController = gm.call("_build_guard")
|
|
guard._ready()
|
|
var yaw0 := guard.rotation.y
|
|
var pitch0 := guard.head.rotation.x
|
|
guard._apply_mouse_look(Vector2(100, 50))
|
|
var a := TestUtils.check(guard.rotation.y < yaw0 - 0.1, "horizontal motion yaws the guard")
|
|
var b := TestUtils.check(guard.head.rotation.x < pitch0 - 0.1, "vertical motion pitches the head")
|
|
guard._apply_mouse_look(Vector2(0, 100000))
|
|
var c := TestUtils.check(absf(rad_to_deg(guard.head.rotation.x)) <= 80.01,
|
|
"pitch stays clamped")
|
|
guard.free()
|
|
gm.free()
|
|
root.free()
|
|
return a and b and c
|
|
|
|
func test_hud_does_not_capture_mouse_input() -> bool:
|
|
var hud: Hud = Hud.new()
|
|
var root := hud.get_child(0) as Control
|
|
var a := TestUtils.check(root != null and root.mouse_filter == Control.MOUSE_FILTER_IGNORE,
|
|
"full-screen HUD root ignores mouse input")
|
|
var labels := hud.find_children("*", "Label", true, false)
|
|
var blocking := 0
|
|
for node in labels:
|
|
if (node as Control).mouse_filter != Control.MOUSE_FILTER_IGNORE:
|
|
blocking += 1
|
|
var b := TestUtils.check(blocking == 0, "HUD labels do not swallow mouse motion")
|
|
hud.free()
|
|
return a and b
|