114 lines
2.6 KiB
GDScript
114 lines
2.6 KiB
GDScript
class_name Inventory
|
|
|
|
enum ItemSortType {
|
|
NAME,
|
|
TYPE
|
|
};
|
|
|
|
class ItemStackNameComparator:
|
|
static func _sort(a, b):
|
|
return ITEM.getItemName(a).to_lower() < ITEM.getItemName(b).to_lower()
|
|
|
|
class ItemStackTypeComparator:
|
|
static func _sort(a, b):
|
|
return a.item.getCategory() < b.item.getCategory()
|
|
|
|
const ITEM_STACK_SIZE_MAX = 99;
|
|
|
|
var contents:Array[ItemStack] = [];
|
|
signal inventoryUpdated()
|
|
|
|
func isPlayerInventory() -> bool:
|
|
return self == ITEM.PLAYER_INVENTORY
|
|
|
|
func addItem(type:Item.Type, quantity: int = 1) -> void:
|
|
if !ITEM.isStackable(type):
|
|
# Item cannot be stacked, add each item to inv
|
|
for i in range(quantity):
|
|
contents.append(ItemStack.new(type, 1))
|
|
_contentsUpdated()
|
|
return
|
|
|
|
# Check for existing stacks
|
|
for stack in contents:
|
|
if stack.type != type or stack.quantity >= ITEM_STACK_SIZE_MAX:
|
|
continue
|
|
|
|
var spaceAvailable = ITEM_STACK_SIZE_MAX - stack.quantity
|
|
|
|
if quantity <= spaceAvailable:
|
|
stack.quantity += quantity;
|
|
_contentsUpdated()
|
|
return
|
|
|
|
stack.quantity = ITEM_STACK_SIZE_MAX;
|
|
quantity -= spaceAvailable;
|
|
|
|
# Add any remaining inventory as new stack.
|
|
while quantity > 0:
|
|
var newStackQuantity = min(quantity, ITEM_STACK_SIZE_MAX);
|
|
contents.append(ItemStack.new(type, newStackQuantity));
|
|
quantity -= newStackQuantity;
|
|
_contentsUpdated()
|
|
|
|
func removeItem(type:Item.Type, quantity:int) -> void:
|
|
var totalQuantity = 0
|
|
|
|
# Calculate total quantity of the item in the inventory
|
|
for stack in contents:
|
|
if stack.type != type:
|
|
continue
|
|
totalQuantity += stack.quantity
|
|
|
|
if totalQuantity < quantity:
|
|
push_error("Not enough quantity to remove");
|
|
return
|
|
|
|
# Remove the quantity from the stacks
|
|
for stack in contents:
|
|
if stack.type != type:
|
|
continue
|
|
|
|
if stack.quantity < quantity:
|
|
quantity -= stack.quantity
|
|
contents.erase(stack)
|
|
|
|
stack.quantity -= quantity
|
|
if stack.quantity == 0:
|
|
contents.erase(stack)
|
|
|
|
if quantity == 0:
|
|
self._contentsUpdated()
|
|
return
|
|
|
|
func removeStack(stack: ItemStack) -> void:
|
|
self.removeItem(stack.item, stack.quantity);
|
|
|
|
func hasItem(type:Item.Type, quantity: int = 1) -> bool:
|
|
var totalQuantity = 0
|
|
|
|
for stack in contents:
|
|
if stack.type != type:
|
|
continue
|
|
|
|
totalQuantity += stack.quantity
|
|
|
|
if totalQuantity >= quantity:
|
|
return true
|
|
|
|
return false
|
|
|
|
func sortBy(by:ItemSortType) -> void:
|
|
match by:
|
|
ItemSortType.NAME:
|
|
contents.sort_custom(ItemStackNameComparator._sort)
|
|
ItemSortType.TYPE:
|
|
contents.sort_custom(ItemStackTypeComparator._sort)
|
|
_:
|
|
assert(false, "Invalid sort type: %s" % by)
|
|
|
|
func _contentsUpdated() -> void:
|
|
inventoryUpdated.emit()
|
|
if isPlayerInventory():
|
|
QUEST.playerInventoryUpdated.emit()
|