|
extends Node
|
|
|
|
signal next_quick_slot
|
|
signal previous_quick_slot
|
|
signal select_quick_slot(slot_index: int)
|
|
signal quick_slot_item_changed(item_id: String)
|
|
signal item_picked_up(item: DBItemResource)
|
|
signal item_dropped(item: DBItemResource)
|
|
signal inventory_opened
|
|
signal inventory_closed
|
|
|
|
signal add_to_inventory(item_id: String, amount: int)
|
|
signal remove_from_inventory(item_id: String, amount: int)
|
|
signal item_added(item_id: String, amount: int)
|
|
signal item_removed(item_id: String, amount: int)
|
|
|
|
var quick_slot_item_id: String = "001"
|
|
|
|
var max_inventory_items: int = 40 # 4 rows of 10
|
|
|
|
var inventory: Array[DBItemResource] = []
|
|
|
|
|
|
func _ready() -> void:
|
|
self.quick_slot_item_changed.connect(_on_quick_slot_item_changed)
|
|
self.item_picked_up.connect(_on_item_picked_up)
|
|
self.item_dropped.connect(_on_item_dropped)
|
|
|
|
self.add_to_inventory.connect(_on_add_to_inventory)
|
|
self.remove_from_inventory.connect(_on_remove_from_inventory)
|
|
|
|
|
|
# TODO: REMOVE ME
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if event.is_action_pressed("ui_up"):
|
|
add_to_inventory.emit("003", 1)
|
|
elif event.is_action_pressed("ui_down"):
|
|
remove_from_inventory.emit("003", 1)
|
|
|
|
|
|
## Find the stack where at least one item can be added
|
|
func _find_available_stack(item_resource: DBItemResource, item_id: String) -> bool:
|
|
return (
|
|
item_resource.id == item_id and
|
|
item_resource.amount < item_resource.max_stack_size
|
|
)
|
|
|
|
## Find the stack in which we can remove a specific item
|
|
## The inventory has a stack, then it should have at least 1 item. Empty stacks are not kept in the inventory.
|
|
func _find_removable_stack(item_resource: DBItemResource, item_id: String) -> bool:
|
|
return item_resource.id == item_id
|
|
|
|
|
|
func _on_add_to_inventory(item_id: String, amount: int = 1) -> void:
|
|
if not DBItems.data.get(item_id):
|
|
printerr("Cannot add item, ", item_id, ", to inventory. Could not find item within DBItems.data.")
|
|
return
|
|
if amount < 1:
|
|
printerr("Cannot add item, ", item_id, ", to inventory. Amount to add cannot be less then 1.")
|
|
return
|
|
|
|
var item_resource: DBItemResource = DBItems.data[item_id]
|
|
|
|
# This logic seems overly complicated and is a mess.
|
|
# Should look into fixing/simplifying this in the future
|
|
var amount_remaining: int = amount
|
|
while amount_remaining > 0:
|
|
var first_stack_index: int = inventory.find_custom(_find_available_stack.bind(item_id))
|
|
|
|
if first_stack_index == -1 and inventory.size() < max_inventory_items:
|
|
var stack_resource: DBItemResource = item_resource.duplicate()
|
|
inventory.append(stack_resource)
|
|
|
|
if amount_remaining <= stack_resource.max_stack_size:
|
|
inventory[-1].amount += amount_remaining
|
|
amount_remaining = 0
|
|
else:
|
|
inventory[-1].amount = stack_resource.max_stack_size
|
|
amount_remaining -= stack_resource.max_stack_size
|
|
|
|
elif first_stack_index > -1:
|
|
var stack_resource: DBItemResource = inventory[first_stack_index]
|
|
var current_amount: int = stack_resource.amount
|
|
var total_amount: int = current_amount + amount_remaining
|
|
if total_amount < stack_resource.max_stack_size: # Stack not full and can hold
|
|
inventory[first_stack_index].amount = total_amount
|
|
amount_remaining = 0
|
|
else:
|
|
inventory[first_stack_index].amount = stack_resource.max_stack_size
|
|
amount_remaining -= stack_resource.max_stack_size
|
|
|
|
item_added.emit(item_id, amount - amount_remaining)
|
|
|
|
func _on_remove_from_inventory(item_id: String, amount: int = 1) -> void:
|
|
var amount_remaining: int = amount
|
|
while amount_remaining > 0:
|
|
var last_stack_index: int = inventory.rfind_custom(_find_removable_stack.bind(item_id))
|
|
|
|
if last_stack_index > -1:
|
|
var stack_resource: DBItemResource = inventory[last_stack_index]
|
|
var current_stack_amount: int = stack_resource.amount
|
|
var total_amount: int = current_stack_amount - amount_remaining
|
|
|
|
if total_amount > 0: # Stack will not be empty after removing
|
|
inventory[last_stack_index].amount -= amount_remaining
|
|
amount_remaining = 0
|
|
else:
|
|
var remaining: int = stack_resource.max_stack_size - current_stack_amount
|
|
inventory.remove_at(last_stack_index)
|
|
amount_remaining -= remaining
|
|
else: # Received more to remove than we had stacks of
|
|
amount_remaining = 0
|
|
|
|
item_removed.emit(item_id, amount - amount_remaining)
|
|
|
|
func _on_item_dropped(item_id: String) -> void:
|
|
_on_remove_from_inventory(item_id, 1)
|
|
|
|
func _on_item_picked_up(item_id: String) -> void:
|
|
_on_add_to_inventory(item_id, 1)
|
|
|
|
func _on_quick_slot_item_changed(item_id: String) -> void:
|
|
quick_slot_item_id = item_id
|