DungeonCrawl
Loading...
Searching...
No Matches
inventory_mode.c File Reference

Implements functionality for the inventory mode. More...

#include "inventory_mode.h"
#include "../character/character.h"
#include "../common.h"
#include "../game.h"
#include "../io/input/input_handler.h"
#include "../io/output/specific/inventory_output.h"
#include "../item/gear.h"
#include "../local/local_handler.h"
#include "../src/combat/combat_mode.h"
#include "local/inventory_mode_local.h"

Go to the source code of this file.

Functions

bool can_equip_gear (character_t *player, gear_t *gear)
 Checks if the equipment can be equipped in case it occupies a hands slot.
void collect_inventory_gear_options (gear_t *gear_inventory[], int count)
 Checks which options are available in the inventory menu for display.
void collect_inventory_equipment_options (gear_t *equipment[])
 Checks which options are available in the equipment menu for display.
void collect_inv_potion_options (potion_t *potion_inventory[], int count)
 Checks which options are available in the potion menu for display.
int init_inventory_mode ()
 Initialize the inventory mode.
inventory_result_t start_inventory (character_t *player, character_t *monster)
 Starts the inventory mode.
internal_inventory_state_t inventory_menu (character_t *player, character_t *monster)
 Displays the main inventory menu.
internal_inventory_state_t inventory_gear_menu (character_t *player, character_t *monster)
 Displays the gear inventory menu.
internal_inventory_state_t inventory_equipment_menu (character_t *player, character_t *monster)
 Displays the equipment inventory menu.
internal_inventory_state_t inventory_potion_menu (character_t *player, character_t *monster)
 Displays the potion inventory menu.
void shutdown_inventory_mode (void)
 Shuts down the inventory mode and frees allocated resources.

Variables

vector2d_t inventory_view_anchor = {1, 1}
internal_inventory_state_t inventory_state = INVENTORY_MENU
int inventory_gear_count = 0
int inventory_potion_count = 0
char ** inventory_gear_options = NULL
char ** inventory_equipment_options = NULL
char ** inventory_potion_options = NULL

Detailed Description

Implements functionality for the inventory mode.

Definition in file inventory_mode.c.

Function Documentation

◆ can_equip_gear()

bool can_equip_gear ( character_t * player,
gear_t * gear )

Checks if the equipment can be equipped in case it occupies a hands slot.

Checks wether the character can equip certain gear or not.

Parameters
playerThe player character.
gearThe gear to check.
Returns
bool True if the gear can be equipped, false otherwise.
Parameters
playerPointer to the player.
gearPointer to the gear to check.
Returns
true if player can equip the gear false if not.

Definition at line 277 of file inventory_mode.c.

277 {
278 if (gear->slot == SLOT_BOTH_HANDS) {
279 if (player->equipment[SLOT_LEFT_HAND] != NULL || player->equipment[SLOT_RIGHT_HAND] != NULL) {
280 return false;
281 }
282 } else if (gear->slot == SLOT_LEFT_HAND || gear->slot == SLOT_RIGHT_HAND) {
283 if (player->equipment[SLOT_BOTH_HANDS] != NULL) {
284 return false;
285 }
286 }
287 return true;
288}

◆ collect_inv_potion_options()

void collect_inv_potion_options ( potion_t * potion_inventory[],
int count )

Checks which options are available in the potion menu for display.

Collects all the options for inventory potions for displaying.

Parameters
potion_inventoryThe potion inventory to check.
countThe number of items in the potion inventory.
potion_inventoryAn array of potions.
countAmmount of potions in the array.

Definition at line 556 of file inventory_mode.c.

556 {
557 if (inventory_potion_options != NULL) {
558 for (int i = 0; i < inventory_potion_count; i++) {
559 if (inventory_potion_options[i] != NULL) {
560 free(inventory_potion_options[i]);
561 inventory_potion_options[i] = NULL;
562 }
563 }
564 free(inventory_potion_options);
565 inventory_potion_options = NULL;
566 }
567
568 inventory_potion_count = count;
569 inventory_potion_options = (char**) malloc(count * sizeof(char*));
570 RETURN_WHEN_NULL(inventory_potion_options, , "Inventory Mode", "Failed to allocate memory for inventory potion options");
571
572 for (int i = 0; i < count; i++) {
573 inventory_potion_options[i] = (char*) malloc(MAX_STRING_LENGTH * sizeof(char));
574 if (inventory_potion_options[i] == NULL) {
575 for (int j = 0; j < i; j++) {
576 free(inventory_potion_options[j]);
577 inventory_potion_options[j] = NULL;
578 }
579 free(inventory_potion_options);
580 inventory_potion_options = NULL;
581 log_msg(ERROR, "Inventory Mode", "Failed to allocate memory for inventory potion options");
582 return;
583 }
584 }
585
586 for (int i = 0; i < count; i++) {
587 snprintf(inventory_potion_options[i], MAX_STRING_LENGTH,
588 inventory_mode_strings[POTION_FORMAT],
589 potion_inventory[i]->name,
590 potion_type_to_string(potion_inventory[i]->effectType),
591 potion_inventory[i]->value);
592 }
593}
void log_msg(const log_level_t level, const char *module, const char *format,...)
Logs a formatted message with a specified log level and module.
Definition logger.c:246
const char * potion_type_to_string(potion_type_t type)
Converts a potion type to a string representation.
Definition potion.c:40

◆ collect_inventory_equipment_options()

void collect_inventory_equipment_options ( gear_t * equipment[])

Checks which options are available in the equipment menu for display.

Collects equipment inventory options for display.

Parameters
equipmentThe equipment to check.
equipmentAn array of equipment.

Definition at line 513 of file inventory_mode.c.

513 {
514 if (inventory_equipment_options != NULL) {
515 for (int i = 0; i < MAX_SLOT; i++) {
516 if (inventory_equipment_options[i] != NULL) {
517 free(inventory_equipment_options[i]);
518 inventory_equipment_options[i] = NULL;
519 }
520 }
521 for (int i = 0; i < MAX_SLOT; i++) {
522 inventory_equipment_options[i] = (char*) malloc(MAX_STRING_LENGTH * sizeof(char));
523 if (inventory_equipment_options[i] == NULL) {
524 for (int j = 0; j < i; j++) {
525 free(inventory_equipment_options[j]);
526 inventory_equipment_options[j] = NULL;
527 }
528 log_msg(ERROR, "Inventory Mode", "Failed to allocate memory for inventory equipment options");
529 return;
530 }
531 }
532 }
533
534 for (int i = 0; i < MAX_SLOT; i++) {
535 if (equipment[i] != NULL) {
536 snprintf(inventory_equipment_options[i], MAX_STRING_LENGTH,
537 inventory_mode_strings[INVENTORY_GEAR_FORMAT],//TODO: This method of using formats is not safe!
538 equipment[i]->local_key,
539 gear_slot_to_string((gear_slot_t) i),
540 equipment[i]->defenses.armor,
541 equipment[i]->defenses.magic_resist);
542 } else {
543 snprintf(inventory_equipment_options[i], MAX_STRING_LENGTH,
544 inventory_mode_strings[INVENTORY_GEAR_FORMAT_EMPTY],//TODO: This method of using formats is not safe!
545 gear_slot_to_string((gear_slot_t) i));
546 }
547 }
548}
const char * gear_slot_to_string(gear_slot_t slot)
Converts a gear slot enumeration value to its string representation.
Definition gear.c:86

◆ collect_inventory_gear_options()

void collect_inventory_gear_options ( gear_t * gear_inventory[],
int count )

Checks which options are available in the inventory menu for display.

Collects all the options for inventory gear for displaying.

Parameters
gear_inventoryThe gear inventory to check.
countThe number of items in the gear inventory.
gear_inventoryAn array of gear.
countAmmount of items in the array.

Definition at line 468 of file inventory_mode.c.

468 {
469 if (inventory_gear_options != NULL) {
470 for (int i = 0; i < inventory_gear_count; i++) {
471 if (inventory_gear_options[i] != NULL) {
472 free(inventory_gear_options[i]);
473 inventory_gear_options[i] = NULL;
474 }
475 }
476 free(inventory_gear_options);
477 inventory_gear_options = NULL;
478 }
479
480 inventory_gear_count = count;
481 inventory_gear_options = (char**) malloc(count * sizeof(char*));
482 RETURN_WHEN_NULL(inventory_gear_options, , "Inventory Mode", "Failed to allocate memory for inventory gear options");
483
484 for (int i = 0; i < count; i++) {
485 inventory_gear_options[i] = (char*) malloc(MAX_STRING_LENGTH * sizeof(char));
486 if (inventory_gear_options[i] == NULL) {
487 for (int j = 0; j < i; j++) {
488 free(inventory_gear_options[j]);
489 inventory_gear_options[j] = NULL;
490 }
491 free(inventory_gear_options);
492 inventory_gear_options = NULL;
493 log_msg(ERROR, "Inventory Mode", "Failed to allocate memory for inventory gear options");
494 return;
495 }
496 }
497
498 for (int i = 0; i < count; i++) {
499 snprintf(inventory_gear_options[i], MAX_STRING_LENGTH,
500 inventory_mode_strings[INVENTORY_GEAR_FORMAT],//TODO: This method of using formats is not safe!
501 gear_inventory[i]->local_key,
502 gear_slot_to_string(gear_inventory[i]->slot),
503 gear_inventory[i]->defenses.armor,
504 gear_inventory[i]->defenses.magic_resist);
505 }
506}

◆ init_inventory_mode()

int init_inventory_mode ( )

Initialize the inventory mode.

Returns
int 0 on success, 1 on failure
Note
This function must be called before using any other functions in this module.

Definition at line 54 of file inventory_mode.c.

54 {
55 inventory_mode_strings = (char**) malloc(sizeof(char*) * MAX_INVENTORY_STRINGS);
56 RETURN_WHEN_NULL(inventory_mode_strings, -1, "Inventory Mode", "Failed to allocate memory for inventory mode strings");
57
58 inventory_equipment_options = (char**) malloc(sizeof(char*) * MAX_SLOT);
59 if (inventory_equipment_options == NULL) {
60 free(inventory_mode_strings);
61 log_msg(ERROR, "Inventory Mode", "Failed to allocate memory for inventory equipment options");
62 return -1;
63 }
64
65 // preset the strings to NULL
66 for (int i = 0; i < MAX_INVENTORY_STRINGS; i++) {
67 inventory_mode_strings[i] = NULL;
68 }
69 // preset the equipped gear options to NULL
70 for (int i = 0; i < MAX_SLOT; i++) {
71 inventory_equipment_options[i] = NULL;
72 }
73
74 //update local once, so the strings are initialized
76 //add update local function to the observer list
78 return 0;
79}
void update_inventory_local(void)
Updates the inventory mode strings with the actual local strings.
void observe_local(void(*update_func)(void))
Registers an observer function to be notified of updates from the local handler.

◆ inventory_equipment_menu()

internal_inventory_state_t inventory_equipment_menu ( character_t * player,
character_t * monster )

Displays the equipment inventory menu.

Parameters
playerThe player character whose inventory is being managed.
monsterThe defeated monster whose inventory will be looted if not NULL.
Returns
internal_inventory_state_t The next state of the inventory mode.

Definition at line 290 of file inventory_mode.c.

290 {
291 const character_t* target = (monster != NULL) ? monster : player;
292 vector2d_t anchor = draw_inventory_view(inventory_view_anchor, target);
293 int selected_index = 0;
294
295 internal_inventory_state_t new_state = INVENTORY_EQUIPMENT_MENU;
296 bool item_selected_or_esc = false;
297
298 while (!item_selected_or_esc) {
299 if (monster != NULL) {
300 draw_inventory_menu(anchor,
301 inventory_mode_strings[EQUIPMENT_MENU_TITLE],
302 inventory_mode_strings[LOOT_EQUIPMENT_MENU_HEADER],
303 inventory_equipment_options,// TODO
304 MAX_SLOT,
305 selected_index,
306 NULL,
307 inventory_mode_strings[PRESS_C_RETURN]);
308 } else {
309 draw_inventory_menu(anchor,
310 inventory_mode_strings[EQUIPMENT_MENU_TITLE],
311 inventory_mode_strings[EQUIPMENT_MENU_HEADER],
312 inventory_equipment_options,// TODO
313 MAX_SLOT,
314 selected_index,
315 NULL,
316 inventory_mode_strings[PRESS_C_RETURN]);
317 }
318
319 // check for input
320 input_event_t input_event;
321 if (!get_input_blocking(&input_event)) {
322 continue;
323 }
324
325 // Handle input using logical input types
326 switch (input_event.type) {
327 case INPUT_UP:
328 selected_index = (selected_index - 1 + MAX_SLOT) % MAX_SLOT;
329 break;
330 case INPUT_DOWN:
331 selected_index = (selected_index + 1) % MAX_SLOT;
332 break;
333 case INPUT_CONFIRM:
334 if (monster != NULL) {
335 if (monster->equipment[selected_index] != NULL) {
336 if (player->gear_count < MAX_GEAR_LIMIT) {
337 add_gear(player, monster->equipment[selected_index]);
338 remove_equipped_gear(monster, (gear_slot_t) selected_index);
339 collect_inventory_equipment_options(monster->equipment);
340 } else {
341 anchor = draw_inventory_view(inventory_view_anchor, target);
342 draw_inventory_log(anchor, inventory_mode_strings[INVENTORY_FULL_MSG]);
343 }
344 return INVENTORY_EQUIPMENT_MENU;
345 }
346 } else {
347 if (player->equipment[selected_index] != NULL) {
348 if (player->gear_count < MAX_GEAR_LIMIT) {
349 unequip_gear(player, (gear_slot_t) selected_index);
350 collect_inventory_equipment_options(player->equipment);
351 } else {
352 anchor = draw_inventory_view(inventory_view_anchor, target);
353 draw_inventory_log(anchor, inventory_mode_strings[INVENTORY_FULL_MSG]);
354 }
355 return INVENTORY_EQUIPMENT_MENU;
356 }
357 }
358 break;
359 case INPUT_CANCEL:
360 new_state = INVENTORY_MENU;
361 item_selected_or_esc = true;
362 break;
363 default:
364 break;
365 }
366 }
367 return new_state;
368}
void add_gear(character_t *character, gear_t *gear)
Adds gear to a character's inventory.
Definition character.c:156
void remove_equipped_gear(character_t *character, gear_slot_t slot)
Removes the gear equipped in a specific slot of a character.
Definition character.c:187
void unequip_gear(character_t *character, const gear_slot_t slot)
Unequips a gear item from a character and adds it to the character's inventory.
Definition character.c:292
bool get_input_blocking(input_event_t *event)
Get the next input event (blocking)
void collect_inventory_equipment_options(gear_t *equipment[])
Checks which options are available in the equipment menu for display.
internal_inventory_state_t
Internal states for the inventory mode.
void draw_inventory_menu(const vector2d_t anchor, const char *menu_name, const char *header_msg, char **menu_options, const int menu_option_count, const int selected_index, const char *key_msg, const char *tail_msg)
Draws the inventory menu.
vector2d_t draw_inventory_view(const vector2d_t anchor, const character_t *player)
Draws the inventory view UI.
void draw_inventory_log(vector2d_t anchor, const char *inventory_log_message)
Draws the inventory log.
Structure for advanced input events with context data.
Definition input_types.h:43
2-dimensional vector struct
Definition common.h:164

◆ inventory_gear_menu()

internal_inventory_state_t inventory_gear_menu ( character_t * player,
character_t * monster )

Displays the gear inventory menu.

Parameters
playerThe player character whose inventory is being managed.
monsterThe defeated monster whose inventory will be looted if not NULL.
Returns
internal_inventory_state_t The next state of the inventory mode.

Definition at line 177 of file inventory_mode.c.

177 {
178 const character_t* target = (monster != NULL) ? monster : player;
179 vector2d_t anchor = draw_inventory_view(inventory_view_anchor, target);
180 int selected_index = 0;
181
182 if (target->gear_count == 0) {
183 draw_inventory_log(anchor, inventory_mode_strings[INVENTORY_EMPTY_MSG]);
184 return INVENTORY_MENU;
185 }
186
187 internal_inventory_state_t new_state = INVENTORY_GEAR_MENU;
188 bool item_selected_or_esc = false;
189
190 while (!item_selected_or_esc) {
191 if (monster != NULL) {
192 draw_inventory_menu(anchor,
193 inventory_mode_strings[INVENTORY_MENU_TITLE],
194 inventory_mode_strings[LOOT_GEAR_MENU_HEADER],
195 inventory_gear_options,// TODO
196 monster->gear_count,
197 selected_index,
198 NULL,
199 inventory_mode_strings[PRESS_C_RETURN]);
200 } else {
201 draw_inventory_menu(anchor,
202 inventory_mode_strings[INVENTORY_MENU_TITLE],
203 inventory_mode_strings[INVENTORY_MENU_HEADER],
204 inventory_gear_options,// TODO
205 player->gear_count,
206 selected_index,
207 inventory_mode_strings[INVENTORY_DROP_GEAR_MSG],
208 inventory_mode_strings[PRESS_C_RETURN]);
209 }
210
211 // check for input
212 input_event_t input_event;
213 if (!get_input_blocking(&input_event)) {
214 continue;
215 }
216
217 // For character keys like 'd'/'D', we need to check the raw input value
218 uint32_t key_id = input_event.raw_input.id;
219
220 // Handle input using logical input types
221 switch (input_event.type) {
222 case INPUT_UP:
223 selected_index = (selected_index - 1 + target->gear_count) % target->gear_count;
224 break;
225 case INPUT_DOWN:
226 selected_index = (selected_index + 1) % target->gear_count;
227 break;
228 case INPUT_CONFIRM:
229 if (monster != NULL) {
230 if (player->gear_count < MAX_GEAR_LIMIT) {
231 add_gear(player, monster->gear_inventory[selected_index]);
232 remove_gear(monster, monster->gear_inventory[selected_index]);
233 collect_inventory_gear_options(monster->gear_inventory, monster->gear_count);
234 } else {
235 anchor = draw_inventory_view(inventory_view_anchor, target);
236 draw_inventory_log(anchor, inventory_mode_strings[INVENTORY_FULL_MSG]);
237 }
238 } else {
239 if (player->equipment[player->gear_inventory[selected_index]->slot] == NULL) {
240 if (can_equip_gear(player, player->gear_inventory[selected_index])) {
241 equip_gear(player, player->gear_inventory[selected_index]);
242 collect_inventory_gear_options(player->gear_inventory, player->gear_count);
243 } else {
244 anchor = draw_inventory_view(inventory_view_anchor, target);
245 draw_inventory_log(anchor, inventory_mode_strings[EQUIPMENT_HANDS_SLOT_FULL]);
246 }
247 } else {
248 anchor = draw_inventory_view(inventory_view_anchor, target);
249 draw_inventory_log(anchor, inventory_mode_strings[EQUIPMENT_SLOT_FULL]);
250 }
251 }
252 return INVENTORY_GEAR_MENU;
253 case INPUT_CANCEL:
254 new_state = INVENTORY_MENU;
255 item_selected_or_esc = true;
256 break;
257 default:
258 // Handle special character keys
259 if ((key_id == 'd' || key_id == 'D') && monster == NULL) {
260 remove_gear(player, player->gear_inventory[selected_index]);
261 collect_inventory_gear_options(player->gear_inventory, player->gear_count);
262 return INVENTORY_GEAR_MENU;
263 }
264 break;
265 }
266 }
267 return new_state;
268}
void equip_gear(character_t *character, gear_t *gear)
Equips a gear item to a character.
Definition character.c:272
void remove_gear(character_t *character, gear_t *gear)
Removes a gear item from a character's inventory.
Definition character.c:169
bool can_equip_gear(character_t *player, gear_t *gear)
Checks if the equipment can be equipped in case it occupies a hands slot.
void collect_inventory_gear_options(gear_t *gear_inventory[], int count)
Checks which options are available in the inventory menu for display.

◆ inventory_menu()

internal_inventory_state_t inventory_menu ( character_t * player,
character_t * monster )

Displays the main inventory menu.

Parameters
playerThe player character whose inventory is being managed.
monsterThe defeated monster whose inventory will be looted if not NULL.
Returns
internal_inventory_state_t The next state of the inventory mode.

Definition at line 112 of file inventory_mode.c.

112 {
113 const character_t* target = (monster != NULL) ? monster : player;
114 const vector2d_t anchor = draw_inventory_view(inventory_view_anchor, target);
115 int selected_index = 0;
116
117 internal_inventory_state_t new_state = INVENTORY_MENU;
118 bool submenu_selected = false;
119
120 while (!submenu_selected) {
121 if (monster != NULL) {
122 draw_inventory_menu(anchor,
123 inventory_mode_strings[LOOT_MAIN_MENU_TITLE],
124 NULL,
125 &inventory_mode_strings[LOOT_OPTION_SHOW_GEAR],
126 3,
127 selected_index,
128 NULL,
129 inventory_mode_strings[FINISH_LOOTING_MSG]);
130 } else {
131 draw_inventory_menu(anchor,
132 inventory_mode_strings[MAIN_MENU_TITLE],
133 NULL,
134 &inventory_mode_strings[SHOW_GEAR],
135 3,
136 selected_index,
137 NULL,
138 inventory_mode_strings[PRESS_C_RETURN]);
139 }
140
141 // check for input
142 input_event_t input_event;
143 if (!get_input_blocking(&input_event)) {
144 continue;
145 }
146
147 // Handle input using logical input types
148 switch (input_event.type) {
149 case INPUT_UP:
150 selected_index = (selected_index - 1 + 3) % 3;
151 break;
152 case INPUT_DOWN:
153 selected_index = (selected_index + 1) % 3;
154 break;
155 case INPUT_CONFIRM:
156 if (selected_index == 0) {
157 new_state = INVENTORY_GEAR_MENU;
158 } else if (selected_index == 1) {
159 new_state = INVENTORY_EQUIPMENT_MENU;
160 } else if (selected_index == 2) {
161 new_state = INVENTORY_POTION_MENU;
162 }
163 submenu_selected = true;
164 break;
165 case INPUT_CANCEL:
166 case INPUT_INVENTORY:
167 new_state = INVENTORY_EXIT;
168 submenu_selected = true;
169 break;
170 default:
171 break;
172 }
173 }
174 return new_state;
175}

◆ inventory_potion_menu()

internal_inventory_state_t inventory_potion_menu ( character_t * player,
character_t * monster )

Displays the potion inventory menu.

Parameters
playerThe player character whose inventory is being managed.
monsterThe defeated monster whose inventory will be looted if not NULL.
Returns
internal_inventory_state_t The next state of the inventory mode.

Definition at line 370 of file inventory_mode.c.

370 {
371 const character_t* target = (monster != NULL) ? monster : player;
372 vector2d_t anchor = draw_inventory_view(inventory_view_anchor, target);
373 int selected_index = 0;
374
375 if (target->potion_count == 0) {
376 draw_inventory_log(anchor, inventory_mode_strings[POTION_EMPTY_MSG]);
377 return INVENTORY_MENU;
378 }
379
380 internal_inventory_state_t new_state = INVENTORY_MENU;
381 bool item_selected_or_esc = false;
382
383 while (!item_selected_or_esc) {
384 if (monster != NULL) {
385 draw_inventory_menu(anchor,
386 inventory_mode_strings[POTION_MENU_TITLE],
387 inventory_mode_strings[LOOT_POTION_MENU_HEADER],
388 inventory_potion_options,// TODO
389 monster->potion_count,
390 selected_index,
391 NULL,
392 inventory_mode_strings[PRESS_C_RETURN]);
393 } else {
394 draw_inventory_menu(anchor,
395 inventory_mode_strings[POTION_MENU_TITLE],
396 inventory_mode_strings[POTION_MENU_HEADER],
397 inventory_potion_options,// TODO
398 player->potion_count,
399 selected_index,
400 inventory_mode_strings[POTION_DROP_POTION_MSG],
401 inventory_mode_strings[PRESS_C_RETURN]);
402 }
403
404 // check for input
405 input_event_t input_event;
406 if (!get_input_blocking(&input_event)) {
407 continue;
408 }
409
410 // For character keys like 'd'/'D', we need to check the raw input value
411 uint32_t key_id = input_event.raw_input.id;
412
413 // Handle input using logical input types
414 switch (input_event.type) {
415 case INPUT_UP:
416 selected_index = (selected_index - 1 + target->potion_count) % target->potion_count;
417 break;
418 case INPUT_DOWN:
419 selected_index = (selected_index + 1) % target->potion_count;
420 break;
421 case INPUT_CONFIRM:
422 if (monster != NULL) {
423 if (player->potion_count < MAX_POTION_LIMIT) {
424 add_potion(player, monster->potion_inventory[selected_index]);
425 remove_potion(monster, monster->potion_inventory[selected_index]);
426 collect_inv_potion_options(monster->potion_inventory, monster->potion_count);
427 } else {
428 anchor = draw_inventory_view(inventory_view_anchor, target);
429 draw_inventory_log(anchor, inventory_mode_strings[POTION_FULL_MSG]);
430 }
431 } else {
432 char message[MAX_STRING_LENGTH];
433 snprintf(message, sizeof(message), inventory_mode_strings[POTION_USE],//TODO: This method of using formats is not safe!
434 player->name,
435 player->potion_inventory[selected_index]->name,
436 player->potion_inventory[selected_index]->value,
437 potion_type_to_string(player->potion_inventory[selected_index]->effectType));
438
439 invoke_potion_effect(player, player->potion_inventory[selected_index]);
440 anchor = draw_inventory_view(inventory_view_anchor, target);
441 draw_inventory_log(anchor, message);
442 collect_inv_potion_options(player->potion_inventory, player->potion_count);
443 }
444 return INVENTORY_POTION_MENU;
445 case INPUT_CANCEL:
446 new_state = INVENTORY_MENU;
447 item_selected_or_esc = true;
448 break;
449 default:
450 // Handle special character keys
451 if ((key_id == 'd' || key_id == 'D') && monster == NULL) {
452 remove_potion(player, player->potion_inventory[selected_index]);
453 collect_inv_potion_options(player->potion_inventory, player->potion_count);
454 return INVENTORY_POTION_MENU;
455 }
456 break;
457 }
458 }
459 return new_state;
460}
void add_potion(character_t *character, potion_t *potion)
Adds a potion to a character's inventory.
Definition character.c:242
void remove_potion(character_t *character, potion_t *potion)
Removes a potion from a character's inventory.
Definition character.c:254
void invoke_potion_effect(character_t *character, potion_t *potion)
Invoke the effect of a potion on a character.
void collect_inv_potion_options(potion_t *potion_inventory[], int count)
Checks which options are available in the potion menu for display.

◆ shutdown_inventory_mode()

void shutdown_inventory_mode ( void )

Shuts down the inventory mode and frees allocated resources.

Note
This function must be called to clean up resources used by the inventory mode.

Definition at line 595 of file inventory_mode.c.

595 {
596 // free the local strings
597 if (inventory_mode_strings != NULL) {
598 for (int i = 0; i < MAX_INVENTORY_STRINGS; i++) {
599 if (inventory_mode_strings[i] != NULL) {
600 free(inventory_mode_strings[i]);
601 }
602 }
603 free(inventory_mode_strings);
604 }
605 // free the inventory gear options
606 if (inventory_gear_options != NULL) {
607 for (int i = 0; i < inventory_gear_count; i++) {
608 if (inventory_gear_options[i] != NULL) {
609 free(inventory_gear_options[i]);
610 }
611 }
612 free(inventory_gear_options);
613 }
614 // free the inventory equipped gear options
615 if (inventory_equipment_options != NULL) {
616 for (int i = 0; i < MAX_SLOT; i++) {
617 if (inventory_equipment_options[i] != NULL) {
618 free(inventory_equipment_options[i]);
619 }
620 }
621 free(inventory_equipment_options);
622 }
623 // free the inventory potion options
624 if (inventory_potion_options != NULL) {
625 for (int i = 0; i < inventory_potion_count; i++) {
626 if (inventory_potion_options[i] != NULL) {
627 free(inventory_potion_options[i]);
628 }
629 }
630 free(inventory_potion_options);
631 }
632}

◆ start_inventory()

inventory_result_t start_inventory ( character_t * player,
character_t * monster )

Starts the inventory mode.

Parameters
playerThe player character whose inventory will be managed.
monsterThe defeated monster whose inventory will be looted if not NULL.
Returns
inventory_result_t The result of the inventory mode.

Definition at line 81 of file inventory_mode.c.

81 {
82 if (monster != NULL) {
83 collect_inventory_gear_options(monster->gear_inventory, monster->gear_count);
84 collect_inventory_equipment_options(monster->equipment);
85 collect_inv_potion_options(monster->potion_inventory, monster->potion_count);
86 } else {
87 collect_inventory_gear_options(player->gear_inventory, player->gear_count);
88 collect_inventory_equipment_options(player->equipment);
89 collect_inv_potion_options(player->potion_inventory, player->potion_count);
90 }
91
92 switch (inventory_state) {
93 case INVENTORY_MENU:
94 inventory_state = inventory_menu(player, monster);
95 break;
96 case INVENTORY_GEAR_MENU:
97 inventory_state = inventory_gear_menu(player, monster);
98 break;
99 case INVENTORY_EQUIPMENT_MENU:
100 inventory_state = inventory_equipment_menu(player, monster);
101 break;
102 case INVENTORY_POTION_MENU:
103 inventory_state = inventory_potion_menu(player, monster);
104 break;
105 case INVENTORY_EXIT:
106 inventory_state = INVENTORY_MENU;
107 return EXIT_TO_MAP;
108 }
109 return CONTINUE_INVENTORY;
110}
internal_inventory_state_t inventory_menu(character_t *player, character_t *monster)
Displays the main inventory menu.
internal_inventory_state_t inventory_equipment_menu(character_t *player, character_t *monster)
Displays the equipment inventory menu.
internal_inventory_state_t inventory_potion_menu(character_t *player, character_t *monster)
Displays the potion inventory menu.
internal_inventory_state_t inventory_gear_menu(character_t *player, character_t *monster)
Displays the gear inventory menu.

Variable Documentation

◆ inventory_equipment_options

char** inventory_equipment_options = NULL

Definition at line 51 of file inventory_mode.c.

◆ inventory_gear_count

int inventory_gear_count = 0

Definition at line 47 of file inventory_mode.c.

◆ inventory_gear_options

char** inventory_gear_options = NULL

Definition at line 50 of file inventory_mode.c.

◆ inventory_potion_count

int inventory_potion_count = 0

Definition at line 48 of file inventory_mode.c.

◆ inventory_potion_options

char** inventory_potion_options = NULL

Definition at line 52 of file inventory_mode.c.

◆ inventory_state

internal_inventory_state_t inventory_state = INVENTORY_MENU

Definition at line 45 of file inventory_mode.c.

◆ inventory_view_anchor

vector2d_t inventory_view_anchor = {1, 1}

Definition at line 44 of file inventory_mode.c.

44{1, 1};