DungeonCrawl
Loading...
Searching...
No Matches
combat_mode.h File Reference

Declares combat mode state machine, including menus and combat operations. More...

Go to the source code of this file.

Enumerations

enum  internal_combat_state_t {
  COMBAT_MENU , ABILITY_MENU , POTION_MENU , EVALUATE_COMBAT ,
  COMBAT_EXIT
}
enum  combat_result_t { CONTINUE_COMBAT , PLAYER_WON , PLAYER_LOST , EXIT_GAME }

Functions

int init_combat_mode ()
 Initialize the combat mode.
combat_result_t start_combat (character_t *player, character_t *monster)
 Starts the loop for combat between the player and the monster.
internal_combat_state_t combat_menu (const character_t *player, const character_t *monster)
 Collects the menu options for the ability menu.
internal_combat_state_t ability_menu (character_t *player, character_t *monster)
 Collects the menu options for the ability menu.
internal_combat_state_t potion_menu (character_t *player, character_t *monster)
 Collects the menu options for the potion menu.
void invoke_potion_effect (character_t *character, potion_t *potion)
 Invoke the effect of a potion on a character.
void shutdown_combat_mode (void)
 Shuts down the combat mode and frees allocated memory resources.

Detailed Description

Declares combat mode state machine, including menus and combat operations.

Definition in file combat_mode.h.

Enumeration Type Documentation

◆ combat_result_t

enum combat_result_t

Definition at line 20 of file combat_mode.h.

20 {
21 CONTINUE_COMBAT,
22 PLAYER_WON,
23 PLAYER_LOST,
24 EXIT_GAME
25} combat_result_t;

◆ internal_combat_state_t

enum internal_combat_state_t

Definition at line 12 of file combat_mode.h.

12 {
13 COMBAT_MENU,
14 ABILITY_MENU,
15 POTION_MENU,
16 EVALUATE_COMBAT,// checks if the combat reached an end
17 COMBAT_EXIT // exit combat & game
18} internal_combat_state_t;

Function Documentation

◆ ability_menu()

internal_combat_state_t ability_menu ( character_t * player,
character_t * monster )

Collects the menu options for the ability menu.

Parameters
abilitiesPointer to the player character.
monsterPointer to the monster character.

Definition at line 209 of file combat_mode.c.

209 {
210 clear_screen();
211 // draw combat view
212 const vector2d_t anchor = draw_combat_view(combat_view_anchor, player, monster, GOBLIN_PNG, GOBLIN_HEIGHT, false);
213 int selected_index = 0;
214
215 internal_combat_state_t new_state = ABILITY_MENU;
216 bool ability_used_or_esc = false;
217
218 while (!ability_used_or_esc) {
219 // draw menu options
220 draw_combat_menu(anchor,
221 combat_mode_strings[ABILITY_MENU_TITLE],
222 ability_menu_options,
223 player->ability_count,
224 selected_index,
225 combat_mode_strings[PRESS_C_RETURN]);
226
227 // check for input
228 input_event_t input_event;
229 if (!get_input_blocking(&input_event)) {
230 continue;
231 }
232
233 // Handle input using logical input types
234 switch (input_event.type) {
235 case INPUT_UP:
236 // Move up
237 selected_index = (selected_index - 1 + player->ability_count) % player->ability_count;
238 break;
239 case INPUT_DOWN:
240 // Move down
241 selected_index = (selected_index + 1) % player->ability_count;
242 break;
243 case INPUT_CONFIRM:
244 // Use ability
245 use_ability(player, monster, player->abilities[selected_index]);
246 use_ability(monster, player, get_random_ability(monster));
247
248 new_state = EVALUATE_COMBAT;
249 ability_used_or_esc = true;
250 break;
251 case INPUT_CANCEL:
252 // go back to the combat menu
253 new_state = COMBAT_MENU;
254 ability_used_or_esc = true;
255 break;
256 default:;
257 }
258 }
259 return new_state;
260}
ability_t * get_random_ability(const character_t *character)
Get a random ability from the character's abilities.
void use_ability(character_t *attacker, character_t *target, const ability_t *ability)
Use an ability on a target character.
void draw_combat_menu(const vector2d_t anchor, const char *menu_name, char **menu_options, const int menu_option_count, const int selected_index, const char *tail_msg)
Draws the combat menu.
vector2d_t draw_combat_view(const vector2d_t anchor, const character_t *player, const character_t *enemy, const char *enemy_sprite, const int sprite_height, const bool red_enemy_sprite)
Draws the combat view UI.
bool get_input_blocking(input_event_t *event)
Get the next input event (blocking)
void clear_screen(void)
Clear the screen.
Structure for advanced input events with context data.
Definition input_types.h:43
2-dimensional vector struct
Definition common.h:164

◆ combat_menu()

internal_combat_state_t combat_menu ( const character_t * player,
const character_t * monster )

Collects the menu options for the ability menu.

Parameters
playerPointer to the player character.
monsterPointer to the monster character.

Definition at line 156 of file combat_mode.c.

156 {
157 // draw combat view
158 const vector2d_t anchor = draw_combat_view(combat_view_anchor, player, monster, GOBLIN_PNG, GOBLIN_HEIGHT, false);
159 int selected_index = 0;
160
161 internal_combat_state_t new_state = COMBAT_MENU;
162 bool submenu_selected = false;
163
164 while (!submenu_selected) {
165 // draw menu options
166 draw_combat_menu(anchor,
167 combat_mode_strings[MAIN_MENU_TITLE],
168 &combat_mode_strings[MAIN_MENU_OPTION1],
169 2,
170 selected_index,
171 NULL);
172
173 // check for input
174 input_event_t input_event;
175 if (!get_input_blocking(&input_event)) {
176 continue;
177 }
178
179 // Handle input using logical input types
180 switch (input_event.type) {
181 case INPUT_UP:
182 // Move up
183 selected_index = (selected_index - 1 + 2) % 2;
184 break;
185 case INPUT_DOWN:
186 // Move down
187 selected_index = (selected_index + 1) % 2;
188 break;
189 case INPUT_CONFIRM:
190 // Return the selected state
191 if (selected_index == 0) {
192 new_state = ABILITY_MENU;
193 } else if (selected_index == 1) {
194 new_state = POTION_MENU;
195 }
196 submenu_selected = true;
197 break;
198 case INPUT_QUIT:
199 // Exit the game
200 new_state = COMBAT_EXIT;
201 submenu_selected = true;
202 break;
203 default:;
204 }
205 }
206 return new_state;
207}

◆ init_combat_mode()

int init_combat_mode ( )

Initialize the combat mode.

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

Definition at line 67 of file combat_mode.c.

67 {
68 combat_mode_strings = (char**) malloc(MAX_COMBAT_MODE_STRINGS * sizeof(char*));
69 RETURN_WHEN_NULL(combat_mode_strings, -1, "Combat Mode", "Allocated memory for combat mode strings in memory pool is NULL");
70
71 ability_menu_options = (char**) malloc(sizeof(char*) * MAX_ABILITY_LIMIT);
72 if (ability_menu_options == NULL) {
73 free(combat_mode_strings);
74 combat_mode_strings = NULL;
75 log_msg(ERROR, "Combat Mode", "Failed to allocate memory for ability menu options.");
76 return -1;
77 }
78
79 potion_menu_options = (char**) malloc(sizeof(char*) * MAX_POTION_LIMIT);
80 if (potion_menu_options == NULL) {
81 free(combat_mode_strings);
82 combat_mode_strings = NULL;
83 free(ability_menu_options);
84 log_msg(ERROR, "Combat Mode", "Failed to allocate memory for potion menu options.");
85 return -1;
86 }
87
88 for (int i = 0; i < MAX_COMBAT_MODE_STRINGS; i++) {
89 combat_mode_strings[i] = NULL;
90 }
91
92 for (int i = 0; i < MAX_ABILITY_LIMIT; i++) {
93 ability_menu_options[i] = NULL;
94 }
95
96 for (int i = 0; i < MAX_POTION_LIMIT; i++) {
97 potion_menu_options[i] = NULL;
98 }
99
100 //update local once, so the strings are initialized
102 //add update local function to the observer list
104 return 0;
105}
void update_combat_local(void)
Updates the combat mode strings with localized versions.
void observe_local(void(*update_func)(void))
Registers an observer function to be notified of updates from the local handler.
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

◆ invoke_potion_effect()

void invoke_potion_effect ( character_t * character,
potion_t * potion )

Invoke the effect of a potion on a character.

Parameters
characterPointer to the character which uses the potion.
potionPointer to which potion to be used.

Definition at line 387 of file combat_mode.c.

387 {
388 switch (potion->effectType) {
389 case HEALING:
390 if (potion->value > (character->max_resources.health - character->current_resources.health)) {
391 character->current_resources.health = character->max_resources.health;
392 } else {
393 character->current_resources.health += potion->value;
394 }
395 break;
396 case MANA:
397 if (potion->value > (character->max_resources.mana - character->current_resources.mana)) {
398 character->current_resources.mana = character->max_resources.mana;
399 } else {
400 character->current_resources.mana += potion->value;
401 }
402 break;
403
404 case STAMINA:
405 if (potion->value > (character->max_resources.stamina - character->current_resources.stamina)) {
406 character->current_resources.stamina = character->max_resources.stamina;
407 } else {
408 character->current_resources.stamina += potion->value;
409 }
410 break;
411
412 default:
413 log_msg(ERROR, "Character", "Unknown potion effect type: %d", potion->effectType);
414 break;
415 }
416 remove_potion(character, potion);
417}
void remove_potion(character_t *character, potion_t *potion)
Removes a potion from a character's inventory.
Definition character.c:254

◆ potion_menu()

internal_combat_state_t potion_menu ( character_t * player,
character_t * monster )

Collects the menu options for the potion menu.

Parameters
abilitiesPointer to the player character.
monsterPointer to the monster character.

Definition at line 262 of file combat_mode.c.

262 {
263 // draw combat view
264 const vector2d_t anchor = draw_combat_view(combat_view_anchor, player, monster, GOBLIN_PNG, GOBLIN_HEIGHT, false);
265 int selected_index = 0;
266
267 if (player->potion_count == 0) {
268 draw_combat_log(anchor, combat_mode_strings[NO_MORE_POTIONS]);
269 return COMBAT_MENU;
270 }
271
272 internal_combat_state_t new_state = POTION_MENU;
273 bool item_used_or_esc = false;
274
275 while (!item_used_or_esc) {
276 // draw menu options
277 draw_combat_menu(anchor,
278 combat_mode_strings[POTION_MENU_TITLE],
279 potion_menu_options,
280 player->potion_count,
281 selected_index,
282 combat_mode_strings[PRESS_C_RETURN]);
283
284 // check for input
285 input_event_t input_event;
286 if (!get_input_blocking(&input_event)) {
287 continue;
288 }
289
290 // Handle input using logical input types
291 switch (input_event.type) {
292 case INPUT_UP:
293 // Move up
294 selected_index = (selected_index - 1 + player->potion_count) % player->potion_count;
295 break;
296 case INPUT_DOWN:
297 // Move down
298 selected_index = (selected_index + 1) % player->potion_count;
299 break;
300 case INPUT_CONFIRM:
301 // Use the selected potion
302 use_potion(player, monster, player->potion_inventory[selected_index]);
303 use_ability(monster, player, get_random_ability(monster));
304 new_state = EVALUATE_COMBAT;
305
306 collect_potion_menu_options(player->potion_inventory, player->potion_count);
307 item_used_or_esc = true;
308 break;
309 case INPUT_CANCEL:
310 // Go back to the combat menu
311 new_state = COMBAT_MENU;
312 item_used_or_esc = true;
313 break;
314 default:;
315 }
316 }
317 return new_state;
318}
void collect_potion_menu_options(potion_t *potions[], int count)
Collects all the options for potions in the potion menu for displaying.
void use_potion(character_t *player, const character_t *monster, potion_t *potion)
Use a potion on a target character.
void draw_combat_log(vector2d_t anchor, const char *combat_log_message)
Draws the combat log.

◆ shutdown_combat_mode()

void shutdown_combat_mode ( void )

Shuts down the combat mode and frees allocated memory resources.

Note
This function deallocates memory associated with combat mode and must be called before exiting the module to prevent memory leaks.

Definition at line 511 of file combat_mode.c.

511 {
512 if (combat_mode_strings != NULL) {
513 for (int i = 0; i < MAX_COMBAT_MODE_STRINGS; i++) {
514 if (combat_mode_strings[i] != NULL) {
515 free(combat_mode_strings[i]);
516 combat_mode_strings[i] = NULL;
517 }
518 }
519 free(combat_mode_strings);
520 combat_mode_strings = NULL;
521 }
522
523 if (ability_menu_options != NULL) {
524 for (int i = 0; i < MAX_ABILITY_LIMIT; i++) {
525 if (ability_menu_options[i] != NULL) {
526 free(ability_menu_options[i]);
527 ability_menu_options[i] = NULL;
528 }
529 }
530 free(ability_menu_options);
531 ability_menu_options = NULL;
532 }
533
534 if (potion_menu_options != NULL) {
535 for (int i = 0; i < MAX_POTION_LIMIT; i++) {
536 if (potion_menu_options[i] != NULL) {
537 free(potion_menu_options[i]);
538 potion_menu_options[i] = NULL;
539 }
540 }
541 free(potion_menu_options);
542 potion_menu_options = NULL;
543 }
544}

◆ start_combat()

combat_result_t start_combat ( character_t * player,
character_t * monster )

Starts the loop for combat between the player and the monster.

Parameters
playerPointer to the player character.
monsterPointer to the monster character.
Returns
combat_result_t The result of the combat.

Definition at line 107 of file combat_mode.c.

107 {
108 // initial combat state
109 const vector2d_t anchor = draw_combat_view(combat_view_anchor, player, monster, GOBLIN_PNG, GOBLIN_HEIGHT, false);
110
111 //collect menu options
112 collect_ability_menu_options(player->abilities, player->ability_count);
113 collect_potion_menu_options(player->potion_inventory, player->potion_count);
114
115 switch (combat_state) {
116 case COMBAT_MENU:
117 combat_state = combat_menu(player, monster);
118 break;
119 case ABILITY_MENU:
120 combat_state = ability_menu(player, monster);
121 break;
122 case POTION_MENU:
123 combat_state = potion_menu(player, monster);
124 break;
125 case EVALUATE_COMBAT:
126 // evaluate the combat result
127 if (player->current_resources.health <= 0) {
128 media_cleanup();
130 return PLAYER_LOST;
131 }
132 if (monster->current_resources.health <= 0) {
133 clear_screen();
134 media_cleanup();
135
136 char message[MAX_STRING_LENGTH];
137 snprintf(message, sizeof(message), "You won the combat! %s is dead.", monster->name);
138 draw_combat_log(anchor, message);
139
140 player->xp += monster->xp_reward;
141 if (player->xp >= calculate_xp_for_next_level(player->level)) {
142 level_up(player);
143 }
144 return PLAYER_WON;
145 }
146 clear_screen();
147 combat_state = COMBAT_MENU;
148 break;
149 case COMBAT_EXIT:
150 media_cleanup();
151 return EXIT_GAME;
152 }
153 return CONTINUE_COMBAT;
154}
internal_combat_state_t combat_menu(const character_t *player, const character_t *monster)
Collects the menu options for the ability menu.
void collect_ability_menu_options(ability_t *abilities[], int count)
Collects all the options for abilities in the abilities menu for displaying.
internal_combat_state_t ability_menu(character_t *player, character_t *monster)
Collects the menu options for the ability menu.
internal_combat_state_t potion_menu(character_t *player, character_t *monster)
Collects the menu options for the potion menu.
void draw_game_over(void)
Draws the game over screen.
void level_up(character_t *player)
Handles the level-up process for a character.
Definition level.c:27
int calculate_xp_for_next_level(int level)
Calculates the XP required for the next level.
Definition level.c:11