Add inventory.
All checks were successful
Build Dusk / run-tests (push) Successful in 2m12s
Build Dusk / build-linux (push) Successful in 1m49s
Build Dusk / build-psp (push) Successful in 1m52s

This commit is contained in:
2026-01-06 07:47:16 -06:00
parent 024ace1078
commit af5bf987c8
91 changed files with 1108 additions and 139 deletions

11
src/item/CMakeLists.txt Normal file
View File

@@ -0,0 +1,11 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
item.c
inventory.c
)

165
src/item/inventory.c Normal file
View File

@@ -0,0 +1,165 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "inventory.h"
#include "util/memory.h"
#include "assert/assert.h"
void inventoryInit(
inventory_t* inventory,
inventorystack_t* storage,
uint8_t storageSize
) {
assertNotNull(inventory, "Inventory pointer is NULL.");
assertNotNull(storage, "Storage pointer is NULL.");
assertTrue(storageSize > 0, "Storage size must be greater than zero.");
inventory->storage = storage;
inventory->storageSize = storageSize;
// Zero item ids.
memoryZero(inventory->storage, sizeof(inventorystack_t) * storageSize);
}
bool_t inventoryItemExists(const inventory_t *inventory, const itemid_t item) {
assertNotNull(inventory, "Inventory pointer is NULL.");
assertNotNull(inventory->storage, "Storage pointer is NULL.");
assertTrue(inventory->storageSize > 0, "Storage too small.");
assertTrue(item != ITEM_ID_NULL, "Item ID cannot be ITEM_ID_NULL.");
inventorystack_t *stack = inventory->storage;
inventorystack_t *end = stack + inventory->storageSize;
do {
if(stack->item == ITEM_ID_NULL) break;
if(stack->item != item) continue;
assertTrue(stack->quantity > 0, "Item has quantity zero.");
return true;
} while(++stack < end);
return false;
}
void inventorySet(
inventory_t *inventory,
const itemid_t item,
const uint8_t quantity
) {
assertNotNull(inventory, "Inventory pointer is NULL.");
assertNotNull(inventory->storage, "Storage pointer is NULL.");
assertTrue(inventory->storageSize > 0, "Storage too small.");
assertTrue(item != ITEM_ID_NULL, "Item ID cannot be ITEM_ID_NULL.");
// If quantity 0, remove.
if(quantity == 0) return inventoryRemove(inventory, item);
// Search for existing stack.
inventorystack_t *stack = inventory->storage;
inventorystack_t *end = stack + inventory->storageSize;
do {
// Not in inventory yet, add as new stack.
if(stack->item == ITEM_ID_NULL) {
stack->item = item;
stack->quantity = quantity;
return;
}
// Not the stack we're looking for.
if(stack->item != item) continue;
// Update existing stack.
stack->quantity = quantity;
return;
} while(++stack < end);
// No space in the inventory.
assertUnreachable("Inventory is full, cannot set more items.");
}
void inventoryAdd(
inventory_t *inventory,
const itemid_t item,
const uint8_t quantity
) {
uint8_t current = inventoryGetCount(inventory, item);
uint16_t newQuantity = (uint16_t)current + (uint16_t)quantity;
assertTrue(
newQuantity <= UINT8_MAX,
"Cannot add item, would overflow maximum quantity."
);
inventorySet(inventory, item, (uint8_t)newQuantity);
}
void inventoryRemove(inventory_t *inventory, const itemid_t item) {
assertNotNull(inventory, "Inventory pointer is NULL.");
assertNotNull(inventory->storage, "Storage pointer is NULL.");
assertTrue(inventory->storageSize > 0, "Storage too small.");
assertTrue(item != ITEM_ID_NULL, "Item ID cannot be ITEM_ID_NULL.");
inventorystack_t *stack = inventory->storage;
inventorystack_t *end = stack + inventory->storageSize;
// Search for existing stack.
do {
// End of inventory, item not present.
if(stack->item == ITEM_ID_NULL) break;
// Not matching stack.
if(stack->item != item) continue;
// Match found, shift everything else down
memoryMove(stack, stack + 1, end - (stack + 1));
// Clear last stack.
inventorystack_t *last = end - 1;
last->item = ITEM_ID_NULL;
break;
} while(++stack < end);
}
uint8_t inventoryGetCount(const inventory_t *inventory, const itemid_t item) {
assertNotNull(inventory, "Inventory pointer is NULL.");
assertNotNull(inventory->storage, "Storage pointer is NULL.");
assertTrue(inventory->storageSize > 0, "Storage too small.");
assertTrue(item != ITEM_ID_NULL, "Item ID cannot be ITEM_ID_NULL.");
inventorystack_t *stack = inventory->storage;
inventorystack_t *end = stack + inventory->storageSize;
do {
// End of inventory, item not present.
if(stack->item == ITEM_ID_NULL) break;
// Not matching stack.
if(stack->item != item) continue;
// Match found, return quantity.
return stack->quantity;
} while(++stack < end);
return 0;
}
bool_t inventoryIsFull(const inventory_t *inventory) {
assertNotNull(inventory, "Inventory pointer is NULL.");
assertNotNull(inventory->storage, "Storage pointer is NULL.");
assertTrue(inventory->storageSize > 0, "Storage too small.");
inventorystack_t *stack = inventory->storage;
inventorystack_t *end = stack + inventory->storageSize;
do {
// Found empty stack, not full.
if(stack->item == ITEM_ID_NULL) return false;
} while(++stack < end);
return true;
}
bool_t inventoryItemFull(const inventory_t *inventory, const itemid_t item) {
return inventoryGetCount(inventory, item) == ITEM_STACK_QUANTITY_MAX;
}

103
src/item/inventory.h Normal file
View File

@@ -0,0 +1,103 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "item.h"
#define ITEM_STACK_QUANTITY_MAX UINT8_MAX
typedef struct {
itemid_t item;
uint8_t quantity;
} inventorystack_t;
typedef struct {
inventorystack_t *storage;
uint8_t storageSize;
} inventory_t;
/**
* Initializes an inventory.
*
* @param inventory The inventory to initialize.
* @param storage The storage array for the inventory.
* @param storageSize The size of the storage array.
*/
void inventoryInit(
inventory_t* inventory,
inventorystack_t* storage,
uint8_t storageSize
);
/**
* Checks if a specific item exists in the inventory (and has quantity > 0).
*
* @param inventory The inventory to check.
* @param item The item ID to check.
* @return true if the item exists, false otherwise.
*/
bool_t inventoryItemExists(const inventory_t *inventory, const itemid_t item);
/**
* Sets the quantity of a specific item in the inventory.
*
* @param inventory The inventory to modify.
* @param item The item ID to set.
* @param quantity The quantity to set.
*/
void inventorySet(
inventory_t *inventory,
const itemid_t item,
const uint8_t quantity
);
/**
* Adds a specific quantity of an item to the inventory.
*
* @param inventory The inventory to modify.
* @param item The item ID to add.
* @param quantity The quantity to add.
*/
void inventoryAdd(
inventory_t *inventory,
const itemid_t item,
const uint8_t quantity
);
/**
* Removes an item from the inventory.
*
* @param inventory The inventory to modify.
* @param item The item ID to remove.
*/
void inventoryRemove(inventory_t *inventory, const itemid_t item);
/**
* Gets the count of a specific item in the inventory.
*
* @param inventory The inventory to check.
* @param item The item ID to check.
* @return The count of the item in the inventory.
*/
uint8_t inventoryGetCount(const inventory_t *inventory, const itemid_t item);
/**
* Checks if the inventory is full.
*
* @param inventory The inventory to check.
* @return true if full, false otherwise.
*/
bool_t inventoryIsFull(const inventory_t *inventory);
/**
* Checks if a specific item stack is full in the inventory.
*
* @param inventory The inventory to check.
* @param item The item ID to check.
* @return true if the item stack is full, false otherwise.
*/
bool_t inventoryItemFull(const inventory_t *inventory, const itemid_t item);

19
src/item/item.c Normal file
View File

@@ -0,0 +1,19 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "item.h"
const item_t ITEMS[] = {
[ITEM_ID_NULL] = {
.type = ITEM_TYPE_NULL
},
// Potion
[ITEM_ID_POTION] = {
.type = ITEM_TYPE_MEDICINE
},
};

21
src/item/item.h Normal file
View File

@@ -0,0 +1,21 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "itemtype.h"
typedef struct {
itemtype_t type;
} item_t;
typedef uint8_t itemid_t;
#define ITEM_ID_NULL 0
#define ITEM_ID_POTION 1
#define ITEM_ID_POTATO 2
extern const item_t ITEMS[];

19
src/item/itemtype.h Normal file
View File

@@ -0,0 +1,19 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef enum {
ITEM_TYPE_NULL,
ITEM_TYPE_MEDICINE,
ITEM_TYPE_INGREDIENT,
ITEM_TYPE_KEYITEM,
ITEM_TYPE_COUNT
} itemtype_t;