sugary-panda (#1)

Reviewed-on: #1
Co-authored-by: Bryce <bryce@brycecovertoperations.com>
Co-committed-by: Bryce <bryce@brycecovertoperations.com>
This commit was merged in pull request #1.
This commit is contained in:
2026-04-28 22:05:11 -07:00
committed by notid
parent dee6216873
commit 639060fa7f
30 changed files with 2402 additions and 6 deletions

View File

@@ -0,0 +1,204 @@
extends Control
class_name InventoryOverlay
signal close_requested
signal item_confirmed(item_id: String)
signal combine_requested(item_a_id: String, item_b_id: String)
signal inspect_requested(item_id: String)
var input_active: bool = false
var _is_visible: bool = false
var _selected_slot: InventorySlot = null
var _drag_start_time: float = 0.0
var _is_dragging: bool = false
var _dragged_item: Control = null
var _hovered_slot: InventorySlot = null
var _fade_tween: Tween = null
const FADE_DURATION: float = 0.2
const LONG_PRESS_THRESHOLD: float = 0.5
const SLOTS_PER_ROW: int = 8
const SLOT_SIZE: Vector2i = Vector2i(64, 64)
@onready var background: ColorRect = $Background
@onready var panel: Control = $InventoryPanel
@onready var frame: ColorRect = $InventoryPanel/Frame
@onready var grid: GridContainer = $InventoryPanel/ItemGrid
@onready var hover_label: Label = $InventoryPanel/HoverLabel
func _ready() -> void:
hide()
background.mouse_filter = Control.MOUSE_FILTER_STOP
InventoryManager.inventory_changed.connect(_refresh_grid)
InventoryManager.combination_attempted.connect(_on_combination_attempted)
func show_overlay() -> void:
print("[OVERLAY] show_overlay called, inventory has %d items" % InventoryManager.inventory.size())
_refresh_grid()
if _fade_tween:
_fade_tween.kill()
_fade_tween = null
_is_visible = true
show()
modulate = Color(1, 1, 1, 0)
input_active = false
var tween = create_tween().bind_node(self)
_fade_tween = tween
tween.tween_property(self, "modulate", Color(1, 1, 1, 1), FADE_DURATION)
tween.tween_callback(_on_fade_in_complete)
func hide_overlay() -> void:
print("[OVERLAY] hide_overlay called")
if _fade_tween:
_fade_tween.kill()
_fade_tween = null
input_active = false
_clear_selection()
var tween = create_tween().bind_node(self)
_fade_tween = tween
tween.tween_property(self, "modulate", Color(1, 1, 1, 0), FADE_DURATION)
tween.tween_callback(_on_fade_out_complete)
func _on_fade_in_complete() -> void:
input_active = true
func _on_fade_out_complete() -> void:
_is_visible = false
hide()
input_active = false
func is_active() -> bool:
return _is_visible and input_active
func _refresh_grid() -> void:
for child in grid.get_children():
child.queue_free()
for item_id in InventoryManager.inventory:
var def = InventoryManager.get_item_definition(item_id)
if not def:
def = ItemDefinition.new()
def.id = item_id
def.name = item_id
var slot_scene = load("res://inventory/inventory_overlay/InventorySlot.tscn")
var slot: InventorySlot = slot_scene.instantiate()
grid.add_child(slot)
slot.set_item(def)
slot.clicked.connect(_on_slot_clicked)
slot.right_clicked.connect(_on_slot_right_clicked)
slot.hovered.connect(_on_slot_hovered)
slot.unhovered.connect(_on_slot_unhovered)
grid.columns = SLOTS_PER_ROW
func _on_slot_clicked(item_id: String) -> void:
print("[OVERLAY] _on_slot_clicked: '%s', input_active=%s" % [item_id, input_active])
if not input_active:
return
for child in grid.get_children():
if child is InventorySlot and child.item_id == item_id:
if _selected_slot == null:
InventoryManager.select_item(item_id)
item_confirmed.emit(item_id)
hide_overlay()
elif _selected_slot.item_id == item_id:
InventoryManager.select_item(item_id)
item_confirmed.emit(item_id)
hide_overlay()
else:
combine_requested.emit(_selected_slot.item_id, item_id)
_clear_selection()
break
func _on_slot_right_clicked(item_id: String) -> void:
if not input_active:
return
inspect_requested.emit(item_id)
hide_overlay()
func _on_slot_hovered(item_id: String) -> void:
if not input_active:
return
_hovered_slot = null
for child in grid.get_children():
if child is InventorySlot and child.item_id == item_id:
_hovered_slot = child
break
_update_hover_label()
func _on_slot_unhovered(item_id: String) -> void:
if _hovered_slot and _hovered_slot.item_id == item_id:
_hovered_slot = null
_update_hover_label()
func _create_drag_preview(slot: InventorySlot) -> void:
var preview = ColorRect.new()
preview.color = Color(1, 0.6, 0.2, 0.7)
preview.size = Vector2(48, 48)
preview.position = slot.global_position - global_position
panel.add_child(preview)
_dragged_item = preview
func _handle_release_same_item() -> void:
var elapsed = Time.get_ticks_msec() / 1000.0 - _drag_start_time
if elapsed <= LONG_PRESS_THRESHOLD:
item_confirmed.emit(_selected_slot.item_id)
hide_overlay()
else:
_clear_selection()
func _clear_selection() -> void:
_selected_slot = null
_is_dragging = false
if _dragged_item:
_dragged_item.queue_free()
_dragged_item = null
_update_hover_label()
func _update_hover_label() -> void:
if _selected_slot and _hovered_slot and _selected_slot.item_id != _hovered_slot.item_id:
var def_a = InventoryManager.get_item_definition(_selected_slot.item_id)
var def_b = InventoryManager.get_item_definition(_hovered_slot.item_id)
var name_a = _selected_slot.item_id
var name_b = _hovered_slot.item_id
if def_a:
name_a = def_a.name
if def_b:
name_b = def_b.name
hover_label.text = "Use %s with %s" % [name_a, name_b]
elif _hovered_slot:
var def = InventoryManager.get_item_definition(_hovered_slot.item_id)
if def:
hover_label.text = def.name
else:
hover_label.text = _hovered_slot.item_id
else:
hover_label.text = ""
func _on_background_gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.button_index == 1 and event.pressed:
hide_overlay()
close_requested.emit()
func _gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.button_index == 1 and event.pressed:
var panel_rect = panel.get_global_rect()
if not panel_rect.has_point(get_global_mouse_position()):
hide_overlay()
close_requested.emit()
func _on_combination_attempted(item_a_id: String, item_b_id: String) -> void:
pass
func _notification(what: int) -> void:
if what == NOTIFICATION_PREDELETE:
if _fade_tween:
_fade_tween.kill()
_fade_tween = null