Openworld: Itemspec_t Design Doc - uchicago-cs/chiventure GitHub Wiki
Currently, roomspec_t has an item_hash_t *items field for storing items for that specific room type, but items spawn in same quantities for every instance of the room generated. We would like to allow game authors to –– per room –– customize item occurrence probability and possible quantity ranges for the item. This allows openworld to generate a much more diverse (and possibly exciting) map. The original item_hash_t functionality can be preserved with an occurrence probability of 1 (guaranteed spawn) and a quantity range of 1-1 (only 1 item).
e.g. Iron ingots have a random chance of spawning in minecraft village chests. When they do, their quantity falls in the range of 1-3.
Related issue (#1035) and PR.
Changes
itemspec_t
struct
Introduce an ...which contains the info for generating an item:
typedef struct itemspec {
UT_hash_handle hh;
char *item_name; // key
double spawn_chance; // 0 ≤ p ≤ 1
unsigned int min_num; // quantity lowerbound
unsigned int max_num; // quantity upperbound
} itemspec_t;
typedef struct itemspec itemspec_hash_t; // to differentiate between pointers and hash tables
Along with new, init, and free helpers and tests.
roomspec_t
struct:
Add a itemspec hash table field to the typedef struct roomspec {
char *room_name;
char *short_desc;
char *long_desc;
int num_built;
item_hash_t *items;
itemspec_hash_t *itemspecs; // <-- new addition
UT_hash_handle hh;
} roomspec_t;
random_items()
with a new helper generate_items()
Replace ...for generating based off of itemspec info:
Type:
item_hash_t *generate_items(roomspec_t *roomspec);
Algorithm:
Declare and initialize int item_count = 0
–– the total number of items (all types) that have been added to the room so far.
Iterate over roomspec item hash–– for each item, query itemspec hash to look for a corresponding itemspec:
- If itemspec not found, spawn item with default settings: chance 100%, quantity 1
- Else (found), use spawn_chance to decide whether to spawn the items(s)
--->2a. if decide not, set spawn quantity to 0
--->2b. if decide to spawn, set spawn quantity as a random value within the specified lowerbound–upperbound (inclusive) range. Compare (MAX_RAND_ITEMS - item_count) and selected quantity.
------>2bi. If the first is smaller (insufficient space to add all items), add that many duplicates of the item to the rv hash. Then break out of the loop and return rv hash.
------>2bii. Else (enough space), add quantity
number of item duplicates to the rv hash. Then continue to the next item.
Notes:
- Each quantity within the range has an equal chance of being picked. e.g. if range is [7, 9]–– three values–– then each has a 1/3 chance of occurring
- MAX_RAND_ITEMS is currently set to a small value; it should be amended to be very large.
- Item duplicates must be deep copies–– a function served by copy_item_to_hash() in default_rooms.c. However it must be slightly refactored to make use of add_item_to_hash() instead of HASH_ADD_STR in order to enable item stacking (details).