From 1d5688526fb2f93574d11000b65eb2fdc5e7a7bb Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Wed, 8 Apr 2026 10:26:30 +0300 Subject: [PATCH] stats: track all gameplay statistics during player actions Signed-off-by: NotAShelf Change-Id: Ie94380572d2256dda45ce7bfcf347c7f6a6a6964 --- src/main.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index 073b84f..5b4f122 100644 --- a/src/main.c +++ b/src/main.c @@ -115,6 +115,7 @@ static void init_floor(GameState *gs, int floor_num) { // Initialize player position if first floor if (floor_num == 1) { player_init(&gs->player, start_x, start_y); + gs->floors_reached = 1; } else { // Move player to new floor position gs->player.x = start_x; @@ -190,7 +191,8 @@ static void post_action(GameState *gs, Enemy *attacked_enemy) { audio_play_dodge(gs); } else { if (combat_get_last_damage() > 0) - spawn_floating_text(gs, ex, ey, combat_get_last_damage(), combat_was_critical()); + gs->damage_dealt += combat_get_last_damage(); + spawn_floating_text(gs, ex, ey, combat_get_last_damage(), combat_was_critical()); audio_play_attack(gs); if (combat_was_blocked()) { spawn_floating_label(gs, ex, ey - 10, "BLOCK", EFFECT_NONE); @@ -199,6 +201,7 @@ static void post_action(GameState *gs, Enemy *attacked_enemy) { if (combat_was_critical()) { spawn_floating_label(gs, ex + 8, ey - 10, "CRIT!", EFFECT_NONE); audio_play_crit(gs); + gs->crits_landed++; } StatusEffectType applied = combat_get_applied_effect(); if (applied != EFFECT_NONE) { @@ -208,6 +211,7 @@ static void post_action(GameState *gs, Enemy *attacked_enemy) { if (!attacked_enemy->alive) { spawn_floating_label(gs, ex, ey - 20, "SLAIN", EFFECT_NONE); audio_play_enemy_death(gs); + gs->total_kills++; } } } @@ -219,6 +223,8 @@ static void post_action(GameState *gs, Enemy *attacked_enemy) { if (combat_was_player_damage() && combat_get_last_damage() > 0) { audio_play_player_damage(gs); gs->screen_shake = 8; + gs->damage_taken += combat_get_last_damage(); + gs->times_hit++; spawn_floating_text(gs, gs->player.x * TILE_SIZE + 8, gs->player.y * TILE_SIZE, combat_get_last_damage(), combat_was_critical()); } @@ -309,6 +315,7 @@ static int handle_inventory_input(GameState *gs) { if (item != NULL) { if (item->type == ITEM_POTION) { player_use_item(&gs->player, item); + gs->potions_used++; player_remove_inventory_item(&gs->player, gs->inv_selected); gs->last_message = "Used potion!"; gs->message_timer = 60; @@ -350,6 +357,8 @@ static int handle_descend_input(GameState *gs) { if (IsKeyPressed(KEY_Y)) { if (gs->player.floor < NUM_FLOORS) { audio_play_stairs(gs); + if (gs->player.floor + 1 > gs->floors_reached) + gs->floors_reached = gs->player.floor + 1; init_floor(gs, gs->player.floor + 1); gs->last_message = "Descended to next floor!"; gs->message_timer = 60; @@ -383,6 +392,7 @@ static int handle_movement_input(GameState *gs) { Item *item = get_item_at_floor(gs->items, gs->item_count, gs->player.x, gs->player.y); if (item != NULL) { if (player_pickup(&gs->player, item)) { + gs->items_collected++; char pickup_msg[64]; snprintf(pickup_msg, sizeof(pickup_msg), "Picked up %s", item_get_name(item)); add_log(gs, pickup_msg); @@ -400,6 +410,7 @@ static int handle_movement_input(GameState *gs) { // Check for item usage (U key - use first potion) if (IsKeyPressed(KEY_U)) { if (gs->player.inventory_count > 0 && player_use_first_item(&gs->player)) { + gs->potions_used++; gs->last_message = "Used potion!"; gs->message_timer = 60; audio_play_item_pickup(gs); @@ -509,6 +520,7 @@ static void game_loop(void) { memset(&gs, 0, sizeof(GameState)); gs.game_over = 0; gs.game_won = 0; + load_audio_assets(&gs); init_floor(&gs, 1); } } @@ -554,13 +566,15 @@ static void game_loop(void) { // Draw game over screen if (gs.game_over) { - render_game_over(); + // Compute final score + gs.final_score = gs.total_kills * 100 + gs.items_collected * 30 + gs.floors_reached * 200 + gs.crits_landed * 25 + + gs.damage_dealt * 2 - gs.damage_taken * 2 - gs.times_hit * 15; if (gs.game_won) { - // Draw win message - const char *win_msg = "YOU WIN! ESCAPED THE DUNGEON!"; - int msg_w = MeasureText(win_msg, 30); - DrawText(win_msg, (SCREEN_WIDTH - msg_w) / 2, SCREEN_HEIGHT / 2 - 80, 30, GOLD); + gs.final_score = (gs.final_score * 3) / 2; } + render_end_screen(gs.game_won, gs.total_kills, gs.items_collected, gs.damage_dealt, gs.damage_taken, + gs.crits_landed, gs.times_hit, gs.potions_used, gs.floors_reached, gs.turn_count, + gs.final_score); } EndDrawing();