Connect physical elevators and staff commutes to construction, saves, and cutaway UI

This commit is contained in:
Takeshi
2026-09-09 12:58:40 +09:00
parent 4d72de8973
commit 0f12c748e9
46 changed files with 3267 additions and 165 deletions
+101
View File
@@ -0,0 +1,101 @@
extends SceneTree
var _checks := 0
var _failures := 0
var _main: Control
var _runtime: Variant
var _clock: Variant
var _module_id: StringName = &""
var _shaft_id: StringName = &""
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
_clock = root.get_node("GameClock")
_runtime = root.get_node("SimulationRuntime")
var state: Variant = root.get_node("GameState")
_clock.reset(1, 6, 0)
state.reset()
_runtime.initialize(_clock, state, 924263)
_clock.set_paused(true)
root.size = Vector2i(1280, 720)
_main = load("res://scenes/main/main.tscn").instantiate() as Control
_main.set("manual_save_path", "user://tests/elevator_ui_%d/manual" % OS.get_process_id())
root.add_child(_main)
_runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false})
await process_frame
await process_frame
_expect(not _main.get("selected_elevator_controls").visible, "empty inspector hides lift controls")
_main.call("_select_build_definition", &"guest_elevator")
_main.call("_on_map_cell_clicked", Vector3i(0, 0, 0))
_expect(_runtime.construction_service.get_jobs().size() == 1, "normal build UI pays for lift construction")
_clock.advance_minutes(300)
_main.call("_clear_build_selection")
var report: Dictionary = _runtime.elevators.get_report()
_expect(report[&"shafts"].size() == 1, "completed paid lift registers one real car")
if report[&"shafts"].size() != 1:
_finish()
return
_shaft_id = report[&"shafts"][0][&"shaft_id"]
_module_id = report[&"shafts"][0][&"module_ids"][0]
_main.call("_on_facility_selected", _module_id)
_expect(_main.get("selected_elevator_controls").visible and _main.get("management_panel").visible, "selecting finished lift opens existing inspector controls")
_expect(_main.get("selected_heading_label").text == "客用昇降機", "proxy lift gets localized title instead of syncing placeholder")
var detail: String = _main.get("selected_detail_label").text
_expect("現在階" in detail and "目的階" in detail and "乗客" in detail and "待機" in detail and "1F 〜 2F" in detail, "inspector displays real cabin floors, occupancy, queue and stops")
var button: Button = _main.get("elevator_operation_button")
_expect(not button.disabled and button.text == "昇降機を停止", "idle powered car exposes stop command")
button.pressed.emit()
_expect(not _shaft()[&"operator_open"] and button.text == "運行を再開", "paused stop applies real operator state and swaps button")
_expect("手動停止" in _main.get("selected_detail_label").text, "stopped inspector state is explicit")
_expect(_runtime.path_service.find_path(Vector3i(0, 0, 0), Vector3i(0, 1, 0)).is_empty(), "UI stop removes usable ride route while shaft blocks climbing")
button.pressed.emit()
_expect(_shaft()[&"operator_open"] and bool(_shaft()[&"operational"]) == bool(_shaft()[&"powered"]), "UI resume respects actual cabin power availability")
_expect(bool(_shaft()[&"powered"]) or "魔力供給なし" in _main.get("selected_detail_label").text, "unpowered cabin cannot appear as running after operator resume")
_clock.set_paused(false)
button.pressed.emit()
_expect(button.disabled and _runtime.command_queue.pending_count() == 1, "running-clock command locks further submission")
_main.call("_on_elevator_operation_pressed")
_expect(_runtime.command_queue.pending_count() == 1, "repeated stop press cannot enqueue duplicate command")
_main.call("_save_manual")
_clock.advance_minutes(1)
_expect(not _shaft()[&"operator_open"], "queued command applies at next simulation minute")
_main.call("_load_manual")
_main.call("_on_facility_selected", _module_id)
_expect(_runtime.command_queue.pending_count() == 1 and button.disabled, "manual load restores queued lift command and disables duplicate submission")
_clock.advance_minutes(1)
_clock.set_paused(true)
_expect(not _shaft()[&"operator_open"] and not button.disabled, "restored command applies exactly once and unlocks control")
button.pressed.emit()
_expect(_shaft()[&"operator_open"], "post-load UI uses fresh idempotency sequence and can resume")
_main.call("_on_map_cell_clicked", Vector3i(10, 0, 0))
_expect(not _main.get("selected_elevator_controls").visible, "selecting empty ground removes obsolete operation control")
_main.call("_on_facility_selected", _module_id)
await process_frame
await process_frame
var panel_rect: Rect2 = _main.get("management_panel").get_global_rect()
_expect(panel_rect.encloses(button.get_global_rect()) and _main.get_global_rect().encloses(panel_rect), "operation button remains visible inside inspector at a 1280 by 720 window")
if OS.get_environment("THE_TREE_ELEVATOR_UI_CAPTURE") == "1":
await RenderingServer.frame_post_draw
var image_value := root.get_texture().get_image()
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path("res://artifacts/transport"))
image_value.save_png("res://artifacts/transport/elevator-inspector.png")
_finish()
func _shaft() -> Dictionary:
for row: Dictionary in _runtime.elevators.get_report()[&"shafts"]:
if row[&"shaft_id"] == _shaft_id:
return row
return {}
func _finish() -> void:
_clock.set_paused(true)
print("Elevator management UI: %d checks, %d failures" % [_checks, _failures])
quit(_failures)
func _expect(ok: bool, label: String) -> void:
_checks += 1
if not ok:
_failures += 1
push_error(label)
+1
View File
@@ -0,0 +1 @@
uid://cl4r811l5vs7i
+4
View File
@@ -69,6 +69,10 @@ func _run() -> void:
_panel.apply_button.pressed.emit()
_expect(_assignment(&"staff_akane").get(&"facility_id") == _receptions[0],
"paused Apply assigns the receptionist to the chosen completed facility")
_expect(_runtime.staff_service.get_staff(&"staff_akane").state == StaffRuntime.State.COMMUTING
and _runtime.facility_service.get_instance(_receptions[0]).active_staff_ids.is_empty(),
"paused Apply visibly starts a commute and does not invent facility attendance")
_expect("出勤中" in _panel.staff_detail_label.text, "staff panel distinguishes physical commuting from active duty")
_expect("変更しました" in _panel.result_label.text and "毎日" in _panel.staff_detail_label.text,
"assignment success and recurring schedule are visible in Japanese")
_test_rejected_assignment()