Add inventory.
This commit is contained in:
11
src/item/CMakeLists.txt
Normal file
11
src/item/CMakeLists.txt
Normal 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
165
src/item/inventory.c
Normal 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
103
src/item/inventory.h
Normal 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
19
src/item/item.c
Normal 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
21
src/item/item.h
Normal 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
19
src/item/itemtype.h
Normal 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;
|
||||
Reference in New Issue
Block a user