extends Node const GAME := preload("res://scenes/game/game.tscn") var held := false var _last_mouse := Vector2.ZERO func motion(point: Vector2) -> void: var event := InputEventMouseMotion.new() event.position = point event.global_position = point event.relative = point - _last_mouse _last_mouse = point event.button_mask = MOUSE_BUTTON_MASK_LEFT if held else 0 get_viewport().push_input(event, true) func mouse(point: Vector2, down: bool) -> void: held = down var event := InputEventMouseButton.new() event.position = point event.global_position = point event.button_index = MOUSE_BUTTON_LEFT event.pressed = down event.button_mask = MOUSE_BUTTON_MASK_LEFT if held else 0 get_viewport().push_input(event, true) func _ready() -> void: GameState.start_new_run() var game := GAME.instantiate() add_child(game) await get_tree().process_frame await get_tree().process_frame game.set_physics_process(false) var player := game.get_node("PlayerShip") as CharacterBody2D player.set_physics_process(false) player.get_node("WeaponController").set_physics_process(false) for enemy in get_tree().get_nodes_in_group("enemies"): enemy.set_physics_process(false) var hud := game.get_node("HUD") hud.call("_toggle_inventory") var drawer: Control = hud.get("_inventory_clip") drawer.set_meta("floating_window_dragged", true) drawer.global_position = Vector2(32, 100) var inventory: ShipInventory = player.get_node("ShipInventory") var item := preload("res://scripts/items/item_generator.gd").generate_for_definition(preload("res://resources/items/hull_plating.tres"), 1) assert(inventory.add_item(item)) await get_tree().process_frame await get_tree().process_frame var panel: Control = hud.get("inventory_panel") var source := panel.get_node("Contents/CargoGrid").get_child(0) as Control var origin := source.get_global_rect().get_center() var cursor := hud.get_node("FlightCursor") # The aiming cursor is only active in free game space. motion(Vector2(650, 150)) await get_tree().process_frame cursor.call("_process", 0.0) assert(cursor.aiming) motion(origin) await get_tree().process_frame cursor.call("_process", 0.0) assert(not cursor.aiming) # Start a real native drag, then pass over a raised crafting window. mouse(origin, true) motion(origin + Vector2(24, 6)) await get_tree().process_frame assert(get_viewport().gui_is_dragging()) var craft: Control = hud.get("_crafting_window") craft.position = Vector2(420, 160) craft.show() hud.get_node("HUDRoot/FloatingWindows").call("focus_window", craft) motion(Vector2(660, 300)) await get_tree().process_frame await get_tree().process_frame var overlay := get_tree().get_first_node_in_group("item_drag_overlay") as CanvasLayer assert(overlay != null) assert(overlay.layer > hud.layer and overlay.layer > 50) var icon: Control = overlay.get_node("DragIcon") assert(icon.visible) assert((icon.position + icon.size * 0.5).is_equal_approx(Vector2(660, 300))) assert(icon.mouse_filter == Control.MOUSE_FILTER_IGNORE) assert(not cursor.should_aim()) if "--capture-preview" in OS.get_cmdline_user_args(): await RenderingServer.frame_post_draw get_viewport().get_texture().get_image().save_png("res://artifacts/item_drag_preview.png") mouse(Vector2(660, 300), false) await get_tree().process_frame await get_tree().process_frame assert(not icon.visible and inventory.cargo[0] == item) # A subsequent drag still delivers the module to its equipment slot. craft.hide() hud.get_node("HUDRoot/FloatingWindows").call("focus_window", drawer) motion(origin) mouse(origin, true) motion(origin + Vector2(24, 6)) await get_tree().process_frame var target: Control = hud.get("_sidebar").get_node("Scroll/Contents/ShipEquipmentPanel/Contents/EquipmentLayout/Module2") await get_tree().process_frame assert(target.get("_drop_highlight")) assert(not target.get_parent().get_node("Module1").get("_drop_highlight")) assert(not target.get_parent().get_node("Extension1").get("_drop_highlight")) var sidebar: Control = hud.get("_sidebar") assert(not sidebar.get_node("Scroll").get_v_scroll_bar().visible) assert(sidebar.position.y + sidebar.size.y * sidebar.scale.y <= 720.0) var destination := target.get_global_rect().get_center() motion(destination) await get_tree().process_frame mouse(destination, false) await get_tree().process_frame await get_tree().process_frame assert(inventory.module_slots[1] == item and inventory.cargo[0] == null) assert(not icon.visible) # Modal UI, defeat, docking and pause all suppress the aiming cursor. var skills: CanvasLayer = hud.get("_captain_skills_ui") skills.call("open_management") motion(Vector2(650, 350)) await get_tree().process_frame assert(not cursor.should_aim()) skills.call("_close") motion(Vector2(650, 150)) await get_tree().process_frame player.set("_is_destroyed", true) assert(not cursor.should_aim()) player.set("_is_destroyed", false) player.set("is_docked", true) assert(not cursor.should_aim()) player.set("is_docked", false) get_tree().paused = true assert(not cursor.should_aim()) get_tree().paused = false cursor.call("_process", 0.0) game.queue_free() await get_tree().process_frame print("DRAG_CURSOR_TEST: PASS centered overlay above windows, cancel/drop, UI/space cursor and cleanup") get_tree().quit()