extends SceneTree # Exercise viewport GUI hit testing; do not emit button signals or call map handlers. var checks := 0 var failures := 0 var main: Control var runtime: Variant var clock: Variant func expect(ok: bool, message: String) -> void: checks += 1 if not ok: failures += 1 push_error(message) func _initialize() -> void: call_deferred("run") func click_at(point: Vector2) -> void: var motion := InputEventMouseMotion.new() motion.position = point motion.global_position = point root.push_input(motion, true) for pressed: bool in [true, false]: var event := InputEventMouseButton.new() event.position = point event.global_position = point event.button_index = MOUSE_BUTTON_LEFT event.pressed = pressed event.button_mask = MOUSE_BUTTON_MASK_LEFT if pressed else 0 root.push_input(event, true) await process_frame func run() -> void: runtime = root.get_node("SimulationRuntime") clock = root.get_node("GameClock") var state: Variant = root.get_node("GameState") clock.reset(1,6,0);state.reset();runtime.initialize(clock,state,42508);clock.set_paused(true) root.size = Vector2i(1440,810) main = load("res://scenes/main/main.tscn").instantiate() main.set("manual_save_path", "user://tests/build_pointer_%d" % Time.get_ticks_usec()) root.add_child(main) runtime.configure_save_policy({&"enabled":false, &"daily_checkpoint_enabled":false}) await process_frame;await process_frame await click_at((main.get("palette_toggle_button") as Button).get_global_rect().get_center()) expect(main.get("palette_scroll").visible, "viewport click opens construction palette") for item: Dictionary in [ {&"id": &"reception", &"cell": Vector3i(-6,0,0), &"cells":8}, {&"id": &"premium_room", &"cell": Vector3i(-6,2,0), &"cells":4}, {&"id": &"guest_stairs", &"cell": Vector3i(-7,1,0), &"cells":1}, {&"id": &"guest_stairs", &"cell": Vector3i(-7,2,0), &"cells":1}, ]: var button: Button = main.get("build_buttons")[item[&"id"]] var scroll: ScrollContainer = main.get("palette_scroll") for attempt in 8: if scroll.get_global_rect().has_point(button.get_global_rect().get_center()): break var bar := scroll.get_h_scroll_bar() await click_at(bar.global_position + Vector2(bar.size.x-3,bar.size.y/2)) # Clicking an already selected toggle would deselect the tool. if not button.button_pressed: await click_at(button.get_global_rect().get_center()) expect(main.get("_selected_definition_id") == item[&"id"], "viewport click selects %s" % item[&"id"]) var preview: WorldPreview = main.get("world_preview") var point := preview.global_position + preview.cell_to_canvas(item[&"cell"]) expect(preview.get_global_rect().has_point(point), "placement target is visible") var before: int = runtime.construction_service.get_jobs().size() await click_at(point) expect(runtime.construction_service.get_jobs().size() == before+1, "viewport placement creates exactly one %s job" % item[&"id"]) if runtime.construction_service.get_jobs().size() != before+1: print("Placement diagnostic: ", main.get("build_status_label").text) finish();return if item[&"id"] == &"premium_room": expect((main.find_child("InnOpeningGuide", true, false) as InnOpeningGuide).get_progress()[&"action"] == &"resume", "guide recognizes premium construction in progress") clock.advance_minutes(runtime.definition_registry.get_facility(item[&"id"]).build_minutes) var found := false for room: Dictionary in runtime.construction_service.get_facilities(): if room[&"definition_id"] == item[&"id"] and room[&"origin"] == item[&"cell"]: found = room[&"occupied_cells"].size() == item[&"cells"] expect(found, "clicked construction completes with original geometry") expect((main.find_child("InnOpeningGuide", true, false) as InnOpeningGuide).get_progress()[&"stage"] == &"staff", "premium room advances opening guide to staff instead of requesting a standard room") await operate_day() if OS.get_environment("THE_TREE_POINTER_CAPTURE") == "1": await process_frame;await RenderingServer.frame_post_draw expect(root.get_texture().get_image().save_png(ProjectSettings.globalize_path("res://artifacts/facility-dimensions-2026-09-29/original-pointer.png")) == OK, "capture viewport-built room") finish() func finish() -> void: SaveService.delete_save(main.get("manual_save_path")) main.queue_free() print("Original build viewport input: %d checks, %d failures" % [checks,failures]) quit(failures) func press_key(code: Key, target: Window = root) -> void: for pressed: bool in [true,false]: var event := InputEventKey.new() event.keycode = code event.physical_keycode = code event.window_id = target.get_window_id() event.pressed = pressed Input.parse_input_event(event) await process_frame func operate_day() -> void: await press_key(KEY_ESCAPE) await press_key(KEY_H) var hire: Button = main.get("staff_candidate_buttons")[&"staff_akane"] await click_at(hire.get_global_rect().get_center()) var staff: Array = runtime.staff_service.get_staff_members() expect(staff.size() == 1, "pointer hires ordinary receptionist from candidates") if staff.is_empty(): return await click_at((main.get("staff_management_toggle_button") as Button).get_global_rect().get_center()) var panel: StaffManagementPanel = main.get("staff_management_panel") await click_at((panel.roster_buttons[staff[0].staff_id] as Button).get_global_rect().get_center()) var reception_id: StringName = &"" var room_id: StringName = &"" for room: FacilityInstance in runtime.facility_service.get_instances(): if room.definition_id == &"reception": reception_id = room.instance_id if room.definition_id == &"premium_room": room_id = room.instance_id var option_index := -1 for i in panel.facility_option.item_count: if StringName(panel.facility_option.get_item_metadata(i)) == reception_id: option_index = i expect(option_index >= 0, "reception appears in assignment options") if option_index < 0: return await click_at(panel.facility_option.get_global_rect().get_center()) var popup := panel.facility_option.get_popup() await press_key(KEY_HOME, popup) for attempt in panel.facility_option.item_count + 1: if popup.get_focused_item() == option_index: break await press_key(KEY_DOWN, popup) await press_key(KEY_ENTER, popup) await click_at(panel.apply_button.get_global_rect().get_center()) clock.advance_minutes(2) expect(runtime.staff_service.get_staff(staff[0].staff_id).assigned_facility_id == reception_id, "pointer/dropdown keyboard assigns receptionist") print("ASSIGNMENT_UI selected=",panel.facility_option.selected," expected=",option_index," result=",panel.result_label.text," popup=",popup.visible) if runtime.staff_service.get_staff(staff[0].staff_id).assigned_facility_id != reception_id: return await press_key(KEY_ESCAPE) expect(runtime.get_facility_access_report(room_id)[&"reachable"], "clicked stairs connect the premium room") while clock.absolute_minute < 1440: var before: int = clock.absolute_minute clock.advance_minutes(mini(30,1440-clock.absolute_minute)) if clock.absolute_minute == before: expect(false, "ordinary clock did not advance: %s" % runtime.get_operations_report());return if clock.absolute_minute % 120 == 52: print("PREMIUM_DAY minute=",clock.absolute_minute) await process_frame var sales := 0 for entry: LedgerEntry in runtime.economy_service.get_entries(): if entry.category == &"SERVICE_SALE" and entry.source_entity_id == room_id: sales += entry.amount expect(sales > 0, "natural arrivals complete paid premium lodging before first midnight") expect(runtime.operations_coordinator.get_day_summaries().size() == 1 and runtime.economy_service.validate_ledger()[&"ok"], "natural premium day closes with balanced ledger") expect((main.find_child("InnOpeningGuide", true, false) as InnOpeningGuide).get_progress()[&"stage"] == &"complete", "premium revenue and midnight close complete the opening guide") print("PREMIUM_POINTER_DAY sales=", sales, " minute=", clock.absolute_minute) # Close the daily ledger before clicking the ordinary save control. await press_key(KEY_ESCAPE) for button: Node in main.find_children("*", "Button", true, false): if button.text == "保存": await click_at(button.get_global_rect().get_center()) break var saved: Dictionary = SaveService.load_snapshot(main.get("manual_save_path")) expect(saved[&"ok"], "pointer saves normal premium-day progress") if saved[&"ok"]: clock.advance_minutes(2) await click_at((main.find_child("SaveLoadMenu",true,false) as MenuButton).get_global_rect().get_center()) var load_popup := (main.find_child("SaveLoadMenu",true,false) as MenuButton).get_popup() await press_key(KEY_HOME,load_popup) await press_key(KEY_ENTER,load_popup) expect(clock.absolute_minute == 1440, "load-menu input restores saved day boundary") expect((main.find_child("InnOpeningGuide", true, false) as InnOpeningGuide).get_progress()[&"stage"] == &"complete", "load preserves completed premium opening guidance") var loaded: Dictionary = runtime.create_snapshot() for section: StringName in [&"facilities", &"economy", &"guests", &"staff", &"construction"]: expect(loaded[&"systems"][&"runtime"][section] == saved[&"snapshot"][&"systems"][&"runtime"][section], "load-menu input restores %s state" % section) clock.advance_minutes(30) var continued: Dictionary = runtime.create_snapshot() expect(runtime.restore_snapshot(loaded), "loaded next-day state can be replayed") clock.advance_minutes(30) expect(runtime.create_snapshot() == continued, "loaded inn continues thirty minutes with deterministic guest/staff/economy replay")