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:
204
inventory/inventory_overlay/InventoryOverlay.gd
Normal file
204
inventory/inventory_overlay/InventoryOverlay.gd
Normal 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
|
||||
Reference in New Issue
Block a user