Files
balatro-gba/include/item.h
2026-09-04 18:22:56 +03:00

143 lines
4.4 KiB
C

/**
* @file item.h
*
* @brief The core structure for items in the shop and inventory.
* Provides a common API for the shop and inventory to handle all types of items.
* Uses struct inheritance so all inherited items can implement an is-a relationship with Item.
* This means that pointers to structs that inherit Item using first member struct inheritance
* can and should be cast to Item* so code that expects an Item* can use them.
*/
#ifndef ITEM_H
#define ITEM_H
#include "mgba_logger.h"
#include "random.h"
#include "sprite.h"
enum ItemType
{
ITEM_TYPE_JOKER,
ITEM_TYPE_PLAYING_CARD,
// Future planned item types
// ITEM_TYPE_CONSUMABLE, // Expand to PLANET, TAROT, and SPECTRAL?
// ITEM_TYPE_VOUCHER,
// ITEM_TYPE_PACK
ITEM_NUM_TYPES
};
/**
* @brief A generic interface for all items that can appear in the shop or be in the inventory.
* This uses first member struct inheritance - other structs are meant to inherit it by
* making their first member field Item.
* Then casts from inheriting structs to Item* are allowed and intentional and this allows for
* generic code that uses polymorphism.
* The -fms-extensions compile flag allows for anonymous members making it behave fully
* as inheritance. It makes all member fields be fully inherited so any struct
* that inherits Item for example will have all its fields accessible directly,
* e.g. `JokerObject joker_object; joker_object.type = ITEM_TYPE_JOKER`
*/
typedef struct Item
{
/**
* @brief First member struct inheritance
* all items that can appear in the shop are SpriteObjects.
* Note that this is an anonymous member.
*/
SpriteObject;
/**
* @brief The item type - used to dispatch the function implementations for inheriting types.
*/
enum ItemType type;
} Item;
/**
* @brief The set of functions that each item type implements.
*/
typedef struct ItemFuncs
{
/**
* All items must implement the following since they are called by the shop and all items
* must be capable of appearing in the shop.
*/
Item* (*roll_new)(enum RngSequence key);
int (*get_buy_price)(Item* item);
bool (*can_acquire)(Item* item);
void (*acquire)(Item* item);
void (*dispose)(Item** item);
// TODO: void (*print_description)(Item* item); // or something of the form
// Optional implementation functions will be added here
} ItemFuncs;
/**
* @brief Rolls a random item of type @p item_type and returns a newly created one.
* Manages rollable items set if necessary (i.e. not rolling items already in inventory)
* To be used when rolling new items for the shop or packs.
*
* Matches @ref ItemFuncs.roll_new()
*
* @param item_type The type of the item to roll
* @param key to the RNG sequence used to roll the Item
*
* @return The newly created randomly rolled item
*/
Item* item_roll_new(enum ItemType item_type, enum RngSequence key);
/**
* @brief Returns the buy price of the item.
*
* Matches @ref ItemFuncs.get_buy_price()
*
* @param item The item whose price to return.
*
* @return UNDEFINED in case of error, the item's buy price otherwise.
*/
int item_get_buy_price(Item* item);
/**
* @brief Acquires the item, adding to inventory if applicable.
* Called when it is purchased from the shop, note that it does not
* perform the purchase operation of decrementing the player's money,
* that should be handled by the shop code.
* For packs this can be to just open the pack,
* for vouchers, this will apply their effect.
*
* Matches @ref ItemFuncs.acquire()
*
* @param item The item to acquire
*/
void item_acquire(Item* item);
/**
* @brief Returns true if the item can be acquired, i.e. added to inventory.
* Does not check if the player has enough money to buy the item, that is the shop's job,
* as this will be used both when purchasing and when selecting in a pack.
*
* Matches @ref ItemFuncs.can_acquire()
*
* @param item The item to check
*/
bool item_can_acquire(Item* item);
/**
* @brief Destroys an item, freeing underlying resources, and manages rollable items sets if needed.
* To be used when destroying items from the inventory, shop, or packs.
*
* @param item A pointer to an item for destruction.
*/
void item_dispose(Item** item);
/**
* @brief Prints the buy price under the item
* Relies on the fact item is a SpriteObject
*
* @param item The item to print under
*/
void item_print_buy_price_under(Item* item);
#endif // ITEM_H