Files
dauphincraft/scripts/inventory/Inventory.gd

104 lines
2.6 KiB
GDScript

class_name Inventory
extends RefCounted
const MAX_STACK: int = 64
const TOTAL_SLOTS: int = 36
const HOTBAR_SIZE: int = 9
signal inventory_changed
var slots: Array = []
var selected_hotbar: int = 0
func _init() -> void:
slots.resize(TOTAL_SLOTS)
for i: int in range(TOTAL_SLOTS):
slots[i] = null
func add_item(item_id: int, count: int = 1) -> int:
var remaining: int = count
# First pass: stack into existing slots
for i: int in range(TOTAL_SLOTS):
if remaining <= 0:
break
if slots[i] != null and slots[i]["item_id"] == item_id:
var space: int = MAX_STACK - slots[i]["count"]
if space > 0:
var add_amount: int = mini(space, remaining)
slots[i]["count"] += add_amount
remaining -= add_amount
# Second pass: fill empty slots
for i: int in range(TOTAL_SLOTS):
if remaining <= 0:
break
if slots[i] == null:
var add_amount: int = mini(MAX_STACK, remaining)
slots[i] = {"item_id": item_id, "count": add_amount}
remaining -= add_amount
inventory_changed.emit()
return remaining
func remove_item_from_slot(slot_index: int, count: int = 1) -> bool:
if slot_index < 0 or slot_index >= TOTAL_SLOTS:
return false
if slots[slot_index] == null:
return false
if slots[slot_index]["count"] < count:
return false
slots[slot_index]["count"] -= count
if slots[slot_index]["count"] <= 0:
slots[slot_index] = null
inventory_changed.emit()
return true
func get_selected_item() -> Variant:
return slots[selected_hotbar]
func scroll_hotbar(direction: int) -> void:
selected_hotbar = (selected_hotbar + direction + HOTBAR_SIZE) % HOTBAR_SIZE
inventory_changed.emit()
func has_items(requirements: Array) -> bool:
for req: Dictionary in requirements:
var needed: int = req["count"]
for i: int in range(TOTAL_SLOTS):
if slots[i] != null and slots[i]["item_id"] == req["item_id"]:
needed -= slots[i]["count"]
if needed > 0:
return false
return true
func get_all_slots() -> Array:
return slots.duplicate(true)
func load_slots(saved_slots: Array) -> void:
for i: int in range(min(saved_slots.size(), TOTAL_SLOTS)):
slots[i] = saved_slots[i]
inventory_changed.emit()
func consume_items(requirements: Array) -> bool:
if not has_items(requirements):
return false
for req: Dictionary in requirements:
var to_consume: int = req["count"]
for i: int in range(TOTAL_SLOTS):
if to_consume <= 0:
break
if slots[i] != null and slots[i]["item_id"] == req["item_id"]:
var take: int = mini(slots[i]["count"], to_consume)
slots[i]["count"] -= take
to_consume -= take
if slots[i]["count"] <= 0:
slots[i] = null
inventory_changed.emit()
return true