Fix sector drag and drop
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
extends Control
|
||||
|
||||
## A draggable modifier piece in the tray. Follows the cursor directly (no
|
||||
## ghost). On release over the board it asks DropCatcher to apply itself.
|
||||
## A draggable modifier piece. Follows the cursor directly — no ghost, no
|
||||
## Godot drag-and-drop API (which fights with 3D raycasting).
|
||||
##
|
||||
## Was TrapezoidSwatch.gd — renamed because modifiers now attach to whole
|
||||
## sectors, not individual segments.
|
||||
## While dragging it asks the DropCatcher which slot is under the cursor, so
|
||||
## the player can SEE what they're about to hit before committing.
|
||||
|
||||
@export var paint_texture: Texture2D:
|
||||
set(value):
|
||||
@@ -13,7 +13,7 @@ extends Control
|
||||
|
||||
@export_range(0.0, 1.0) var top_width_ratio := 0.55
|
||||
|
||||
# Set by the tray when it spawns this piece.
|
||||
# Injected by the tray on spawn.
|
||||
var drop_catcher: Control
|
||||
var tray: Node
|
||||
var modifier: Modifier
|
||||
@@ -21,6 +21,7 @@ var modifier: Modifier
|
||||
var _dragging := false
|
||||
var _home_position := Vector2.ZERO
|
||||
var _drag_offset := Vector2.ZERO
|
||||
var _hovered_slot: StringName = &""
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -50,9 +51,17 @@ func _draw() -> void:
|
||||
else:
|
||||
draw_colored_polygon(points, Color(0.8, 0.8, 0.8))
|
||||
|
||||
# Outline turns green when hovering a valid slot — the player's only cue
|
||||
# that the drop will land.
|
||||
var outline_col := Color(0, 0, 0, 0.6)
|
||||
var outline_w := 2.0
|
||||
if _dragging and _hovered_slot != &"":
|
||||
outline_col = Color(0.3, 1.0, 0.4, 0.9)
|
||||
outline_w = 4.0
|
||||
|
||||
var outline := points
|
||||
outline.append(points[0])
|
||||
draw_polyline(outline, Color(0, 0, 0, 0.6), 2.0)
|
||||
draw_polyline(outline, outline_col, outline_w)
|
||||
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
@@ -67,6 +76,7 @@ func _start_drag() -> void:
|
||||
_dragging = true
|
||||
_home_position = global_position
|
||||
_drag_offset = global_position - get_global_mouse_position()
|
||||
|
||||
# top_level lets us move by global_position without reparenting.
|
||||
# Reparenting mid-drag breaks the release event.
|
||||
top_level = true
|
||||
@@ -77,31 +87,39 @@ func _start_drag() -> void:
|
||||
func _end_drag() -> void:
|
||||
if not _dragging:
|
||||
return
|
||||
|
||||
_dragging = false
|
||||
_hovered_slot = &""
|
||||
modulate.a = 1.0
|
||||
z_index = 0
|
||||
|
||||
var applied := false
|
||||
if drop_catcher == null:
|
||||
push_error("SectorSwatch has no drop_catcher (tray export not set?).")
|
||||
elif not drop_catcher.has_method(&"apply_modifier_at_screen_pos"):
|
||||
push_error("drop_catcher has no apply_modifier_at_screen_pos method.")
|
||||
push_error("SectorSwatch has no drop_catcher.")
|
||||
else:
|
||||
applied = drop_catcher.apply_modifier_at_screen_pos(
|
||||
get_global_mouse_position(), modifier
|
||||
)
|
||||
|
||||
if applied:
|
||||
if tray != null and tray.has_method(&"consume"):
|
||||
tray.consume()
|
||||
else:
|
||||
queue_free()
|
||||
else:
|
||||
# Missed — snap home.
|
||||
top_level = false
|
||||
global_position = _home_position
|
||||
# Always snap home. The tray decides whether to consume the piece.
|
||||
top_level = false
|
||||
global_position = _home_position
|
||||
queue_redraw()
|
||||
|
||||
if applied and tray != null and tray.has_method(&"on_piece_used"):
|
||||
tray.on_piece_used(self)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _dragging:
|
||||
global_position = get_global_mouse_position() + _drag_offset
|
||||
if not _dragging:
|
||||
return
|
||||
|
||||
var mouse := get_global_mouse_position()
|
||||
global_position = mouse + _drag_offset
|
||||
|
||||
# Live hover feedback — which slot would this land on right now?
|
||||
if drop_catcher != null and drop_catcher.has_method(&"hover"):
|
||||
var slot: StringName = drop_catcher.hover(mouse)
|
||||
if slot != _hovered_slot:
|
||||
_hovered_slot = slot
|
||||
queue_redraw()
|
||||
|
||||
Reference in New Issue
Block a user