121 lines
2.9 KiB
GDScript
121 lines
2.9 KiB
GDScript
@tool
|
|
class_name ItemGrid
|
|
extends GridContainer
|
|
|
|
signal item_selected
|
|
|
|
@export var slot_scene:PackedScene
|
|
@export var allow_selection:bool = false
|
|
@export var allow_drag_drop:bool = false
|
|
|
|
@export var rows:int:
|
|
get:
|
|
return rows
|
|
set(value):
|
|
if value == rows:
|
|
return
|
|
|
|
rows = value
|
|
|
|
if slot_scene == null or not is_node_ready():
|
|
return
|
|
|
|
resize_grid()
|
|
|
|
var _slots:Array = []
|
|
var _item_slot_to_index:Dictionary = {}
|
|
var _highlighted_slot_index = -1
|
|
var _highlighted_slot:ItemSlot = null
|
|
var selected_slot:ItemSlot = null
|
|
var _selected_slot_index:int = -1
|
|
|
|
func _ready() -> void:
|
|
resize_grid()
|
|
|
|
func resize_grid() -> void:
|
|
_item_slot_to_index.clear()
|
|
|
|
for child in get_children():
|
|
child.get_parent().remove_child(child)
|
|
child.queue_free()
|
|
|
|
_slots.clear()
|
|
while get_child_count() < rows * columns:
|
|
var slot_instance = slot_scene.instantiate()
|
|
if allow_drag_drop:
|
|
slot_instance.set_drag_drop_flags(ItemSlot.ALLOW_DRAG | ItemSlot.ALLOW_DROP)
|
|
add_child(slot_instance)
|
|
_slots.append(slot_instance)
|
|
if allow_selection and not Engine.is_editor_hint():
|
|
slot_instance.connect("mouse_entered_slot", _on_slot_mouse_entered)
|
|
slot_instance.connect("mouse_left_pressed", _on_slot_mouse_left_pressed)
|
|
_item_slot_to_index[slot_instance] = _item_slot_to_index.size()
|
|
|
|
func clear_slots() -> void:
|
|
for slot:ItemSlot in _slots:
|
|
slot.display(ItemStack.new())
|
|
|
|
func get_slot_index(slot:ItemSlot) -> int:
|
|
if _item_slot_to_index.has(slot):
|
|
return _item_slot_to_index[slot]
|
|
|
|
return -1
|
|
|
|
func _on_slot_mouse_entered(slot:ItemSlot):
|
|
if _highlighted_slot != null:
|
|
_highlighted_slot.highlighted = false
|
|
|
|
_highlighted_slot_index = -1
|
|
_highlighted_slot = null
|
|
|
|
if _item_slot_to_index.has(slot):
|
|
_highlighted_slot_index = _item_slot_to_index[slot]
|
|
_highlighted_slot = slot
|
|
_highlighted_slot.highlighted = true
|
|
|
|
func select_slot(index:int) -> void:
|
|
if index < 0 or index > _slots.size():
|
|
return
|
|
|
|
_selected_slot_index = index
|
|
selected_slot = _slots[_selected_slot_index]
|
|
selected_slot.selected = true
|
|
item_selected.emit(selected_slot)
|
|
|
|
func _on_slot_mouse_left_pressed(slot:ItemSlot):
|
|
if selected_slot:
|
|
selected_slot.selected = false
|
|
|
|
if slot == _highlighted_slot:
|
|
_highlighted_slot.highlighted = false
|
|
select_slot(get_slot_index(slot))
|
|
|
|
func displayStacks(item_stacks:Array[ItemStack]):
|
|
var item_stack_index = 0
|
|
|
|
for slot:ItemSlot in _slots:
|
|
if item_stack_index < item_stacks.size():
|
|
slot.display(item_stacks[item_stack_index])
|
|
else:
|
|
var item_stack:ItemStack = ItemStack.new()
|
|
item_stack.item = null
|
|
slot.display(item_stack)
|
|
|
|
item_stack_index = item_stack_index + 1
|
|
|
|
func display(item_stacks:Array[Item]):
|
|
var item_stack_index = 0
|
|
|
|
for slot:ItemSlot in _slots:
|
|
var item_stack:ItemStack = ItemStack.new()
|
|
|
|
if item_stack_index < item_stacks.size():
|
|
item_stack.item = item_stacks[item_stack_index]
|
|
item_stack.count = 1
|
|
else:
|
|
item_stack.item = null
|
|
|
|
item_stack_index = item_stack_index + 1
|
|
|
|
slot.display(item_stack)
|