extends Control ## Spawns draggable modifier pieces along the bottom of the screen. ## ## For now it spawns ALL modifiers in the registry, one of each, and they never ## run out. That's a debug affordance — the real economy (random draws, rounds, ## consumption) is a later phase. Right now we just want to prove drag-and-drop ## works. @export var drop_catcher: Control @export_group("Layout") @export var piece_size := Vector2(90, 110) @export var spacing := 24.0 @export var bottom_margin := 30.0 @export_group("Behaviour") ## If false, pieces stay in the tray after a successful drop. Useful while ## testing; set true when the real economy lands. @export var consume_on_use := false const SectorSwatch := preload("res://core/ui/sector_swatch.gd") var _pieces: Array[Control] = [] func _ready() -> void: # The tray itself must not eat mouse events — only its pieces should. mouse_filter = Control.MOUSE_FILTER_IGNORE if drop_catcher == null: push_error("ModifierTray: `drop_catcher` export is not set.") return spawn_all() ## Spawn one piece per registered modifier. func spawn_all() -> void: _clear_pieces() var mods: Array[Modifier] = ModRegistry.modifiers if mods.is_empty(): push_warning("ModifierTray: registry has no modifiers. Nothing to spawn.") return for mod in mods: _spawn_piece(mod) _layout() func _spawn_piece(mod: Modifier) -> void: var piece := Control.new() piece.set_script(SectorSwatch) piece.custom_minimum_size = piece_size piece.size = piece_size piece.modifier = mod piece.paint_texture = mod.texture piece.drop_catcher = drop_catcher piece.tray = self add_child(piece) _pieces.append(piece) func _layout() -> void: var count := _pieces.size() if count == 0: return var total_w := count * piece_size.x + (count - 1) * spacing var screen := get_viewport_rect().size var start_x := (screen.x - total_w) * 0.5 var y := screen.y - piece_size.y - bottom_margin for i in count: _pieces[i].position = Vector2(start_x + i * (piece_size.x + spacing), y) ## Called by a piece after a successful drop. func on_piece_used(piece: Control) -> void: if not consume_on_use: return # piece snaps home; it's reusable _pieces.erase(piece) piece.queue_free() _layout() func _clear_pieces() -> void: for p in _pieces: if is_instance_valid(p): p.queue_free() _pieces.clear() func _notification(what: int) -> void: if what == NOTIFICATION_RESIZED: _layout()