Preserve production code, regression fixtures, audio assets and provenance, test infrastructure, and the original-completion plan and progress ledger. Final game and Windows acceptance remain pending; excluded local artifacts and native experiments are not part of this snapshot.
129 lines
6.8 KiB
GDScript
129 lines
6.8 KiB
GDScript
extends SceneTree
|
|
const FixtureCleanup := preload("res://tests/helpers/ui_audio_fixture_cleanup.gd")
|
|
var checks := 0
|
|
var failures := 0
|
|
var runtime: Variant
|
|
var clock: Variant
|
|
var main: Control
|
|
var elevator_mode := OS.get_environment("THE_TREE_RESCUE_ELEVATOR") == "1"
|
|
func _initialize() -> void: call_deferred("run")
|
|
func expect(ok: bool, text: String) -> void:
|
|
checks += 1
|
|
if not ok: failures += 1; push_error(text)
|
|
func command(kind: StringName, payload: Dictionary) -> bool:
|
|
var result: CommandResult = runtime.submit_command(kind,payload,&"player")
|
|
expect(result.is_success(), "normal command succeeds: %s (%s)" % [kind,result.message])
|
|
return result.is_success()
|
|
func run() -> void:
|
|
root.size = Vector2i(1440,810)
|
|
runtime = root.get_node("SimulationRuntime")
|
|
clock = root.get_node("GameClock")
|
|
clock.reset(1,6,0)
|
|
root.get_node("GameState").reset()
|
|
runtime.initialize(clock,root.get_node("GameState"),711)
|
|
clock.set_paused(true)
|
|
main = load("res://scenes/main/main.tscn").instantiate()
|
|
root.add_child(main)
|
|
await process_frame
|
|
runtime.configure_save_policy({&"enabled": false})
|
|
main._set_layer(1)
|
|
expect(main.build_buttons.has(&"infirmary"), "infirmary is selectable in the real build palette")
|
|
main.build_buttons[&"infirmary"].button_pressed = true
|
|
main._on_map_cell_clicked(Vector3i(-6,0,1))
|
|
expect(runtime.construction_service.get_jobs().size() == 1, "map click starts infirmary construction")
|
|
if not command(&"build_facility",{&"definition_id":&"staff_door",&"origin":Vector3i(-1,0,1) if elevator_mode else Vector3i(0,0,1)}):
|
|
var _audio_cleanup_early_0: Dictionary = await FixtureCleanup.free_owner_and_wait(self, main)
|
|
if not bool(_audio_cleanup_early_0.get(&"passed", false)):
|
|
push_error("Ordinary fixture audio cleanup failed: %s" % str(_audio_cleanup_early_0))
|
|
quit(96)
|
|
return
|
|
quit(1); return
|
|
if elevator_mode:
|
|
if not command(&"build_facility",{&"definition_id":&"service_elevator",&"origin":Vector3i(0,0,1)}):
|
|
var _audio_cleanup_early_1: Dictionary = await FixtureCleanup.free_owner_and_wait(self, main)
|
|
if not bool(_audio_cleanup_early_1.get(&"passed", false)):
|
|
push_error("Ordinary fixture audio cleanup failed: %s" % str(_audio_cleanup_early_1))
|
|
quit(96)
|
|
return
|
|
quit(1); return
|
|
clock.advance_minutes(400 if elevator_mode else 180)
|
|
var clinic: FacilityInstance
|
|
for room: FacilityInstance in runtime.facility_service.get_instances():
|
|
if room.definition_id == &"infirmary": clinic = room
|
|
expect(clinic != null and clinic.operation_state == FacilityInstance.OperationState.OPERATING, "paid infirmary completes and operates")
|
|
if clinic == null:
|
|
var _audio_cleanup_early_2: Dictionary = await FixtureCleanup.free_owner_and_wait(self, main)
|
|
if not bool(_audio_cleanup_early_2.get(&"passed", false)):
|
|
push_error("Ordinary fixture audio cleanup failed: %s" % str(_audio_cleanup_early_2))
|
|
quit(96)
|
|
return
|
|
quit(1); return
|
|
if not command(&"hire_staff_candidate",{&"candidate_id":&"staff_tessa"}):
|
|
var _audio_cleanup_early_3: Dictionary = await FixtureCleanup.free_owner_and_wait(self, main)
|
|
if not bool(_audio_cleanup_early_3.get(&"passed", false)):
|
|
push_error("Ordinary fixture audio cleanup failed: %s" % str(_audio_cleanup_early_3))
|
|
quit(96)
|
|
return
|
|
quit(1); return
|
|
if not command(&"set_staff_work_assignment",{&"staff_id":&"staff_tessa",&"facility_id":clinic.instance_id,&"template_id":&"DAY"}):
|
|
var _audio_cleanup_early_4: Dictionary = await FixtureCleanup.free_owner_and_wait(self, main)
|
|
if not bool(_audio_cleanup_early_4.get(&"passed", false)):
|
|
push_error("Ordinary fixture audio cleanup failed: %s" % str(_audio_cleanup_early_4))
|
|
quit(96)
|
|
return
|
|
quit(1); return
|
|
# Injury is the only fixture injection; the rescuer is hired and commutes normally.
|
|
if not command(&"register_staff",{&"staff_id":&"injured_worker",&"role_id":&"porter",&"options":{&"health":0,&"current_cell":Vector3i(0,1,1) if elevator_mode else Vector3i(3,0,1)}}):
|
|
var _audio_cleanup_early_5: Dictionary = await FixtureCleanup.free_owner_and_wait(self, main)
|
|
if not bool(_audio_cleanup_early_5.get(&"passed", false)):
|
|
push_error("Ordinary fixture audio cleanup failed: %s" % str(_audio_cleanup_early_5))
|
|
quit(96)
|
|
return
|
|
quit(1); return
|
|
main._activate_management_mode(&"staff")
|
|
main.staff_management_panel.select_staff(&"injured_worker")
|
|
main.world_preview.focus_operating_area()
|
|
var carried := false
|
|
var treated := false
|
|
var saw_cabin := false
|
|
for minute: int in 150:
|
|
clock.advance_minutes(1)
|
|
main.staff_management_panel.refresh()
|
|
var report: Dictionary = runtime.get_staff_rescue_report()
|
|
if elevator_mode and not saw_cabin:
|
|
var trip: Dictionary = runtime.elevators.get_actor_trip(&"staff:injured_worker")
|
|
for shaft: Dictionary in runtime.elevators.get_report()[&"shafts"]:
|
|
if trip.get(&"state", &"") == PathService.ELEVATOR_REQUEST_BOARDED and shaft[&"phase"] == &"TRAVEL":
|
|
saw_cabin = true
|
|
expect(shaft[&"passenger_count"] == 2, "normally hired medic and patient occupy two cabin seats")
|
|
await capture("paired-cabin")
|
|
if not carried and report[&"transporting"] > 0 and runtime.staff_service.get_staff(&"injured_worker").current_cell.x <= -1:
|
|
carried = true
|
|
expect("搬送中" in main.staff_management_panel.staff_detail_label.text, "staff UI shows actual transport status")
|
|
await capture("transport")
|
|
if not treated and report[&"treating"] > 0:
|
|
treated = true
|
|
expect("治療中" in main.staff_management_panel.staff_detail_label.text, "staff UI shows actual treatment status")
|
|
await capture("treatment")
|
|
if carried and treated and runtime.staff_service.get_staff(&"injured_worker").health > 0: break
|
|
if minute%10 == 0: await process_frame
|
|
if elevator_mode: expect(saw_cabin, "normal medical assignment uses the elevator for rescue")
|
|
expect(carried and treated, "a normally hired medical worker picks up and treats the patient")
|
|
expect(runtime.staff_service.get_staff(&"injured_worker").health == 100, "treatment completes through normal Runtime ticks")
|
|
expect(runtime.economy_service.get_balance(&"PLAYER_CASH") < 5000, "medical building and hiring are actually paid")
|
|
expect(runtime.staff_service.validate_invariants()[&"ok"], "normal rescue preserves ownership")
|
|
var _audio_cleanup_final: Dictionary = await FixtureCleanup.free_owner_and_wait(self, main)
|
|
if not bool(_audio_cleanup_final.get(&"passed", false)):
|
|
push_error("Ordinary fixture audio cleanup failed: %s" % str(_audio_cleanup_final))
|
|
quit(96)
|
|
return
|
|
await process_frame
|
|
print("Rescue UI: %d checks, %d failures" % [checks,failures])
|
|
quit(failures)
|
|
func capture(label: String) -> void:
|
|
if OS.get_environment("THE_TREE_RESCUE_CAPTURE") != "1": return
|
|
main.world_preview.queue_redraw()
|
|
await process_frame
|
|
await RenderingServer.frame_post_draw
|
|
root.get_texture().get_image().save_png(("res://artifacts/remaining-2026-09-29/%s.png" if elevator_mode else "res://artifacts/rescue-2026-09-29/%s.png") % label)
|