Randoloot/tests/ships/drag_cursor_test.gd
2026-10-17 16:51:07 +02:00

134 lines
5.2 KiB
GDScript

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()