From 38ba14eddd401551debb805bd506245135e57e75 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sat, 4 Jan 2025 00:31:36 +0100 Subject: [PATCH] added support for playing BD games with multiple lives and global score --- src/files.c | 5 +++++ src/game.c | 42 +++++++++++++++++++++++++++++++++++++-- src/game_bd/bd_gameplay.c | 2 ++ src/game_bd/export_bd.h | 4 ++++ src/game_bd/main_bd.c | 4 ++-- src/libgame/system.h | 1 + src/screens.c | 1 + 7 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/files.c b/src/files.c index af7f9c7a..c6faf9e5 100644 --- a/src/files.c +++ b/src/files.c @@ -11013,6 +11013,10 @@ static struct TokenInfo global_setup_tokens[] = TYPE_INTEGER, &setup.default_game_engine_type, "default_game_engine_type" }, + { + TYPE_SWITCH, + &setup.bd_multiple_lives, "bd_multiple_lives" + }, { TYPE_SWITCH, &setup.bd_skip_uncovering, "bd_skip_uncovering" @@ -11932,6 +11936,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->game_speed_extended = FALSE; si->game_frame_delay = GAME_FRAME_DELAY; si->default_game_engine_type = GAME_ENGINE_TYPE_RND; + si->bd_multiple_lives = FALSE; si->bd_skip_uncovering = FALSE; si->bd_skip_hatching = FALSE; si->bd_scroll_delay = TRUE; diff --git a/src/game.c b/src/game.c index af5b0e2c..3a6662c3 100644 --- a/src/game.c +++ b/src/game.c @@ -2326,7 +2326,7 @@ static void UpdateGameControlValues(void) int score = (game.LevelSolved ? game.LevelSolved_CountingScore : level.game_engine_type == GAME_ENGINE_TYPE_BD ? - game_bd.score : + game_bd.global_score : level.game_engine_type == GAME_ENGINE_TYPE_EM ? game_em.lev->score : level.game_engine_type == GAME_ENGINE_TYPE_SP ? @@ -3708,6 +3708,22 @@ void InitGame(void) if (!game.restart_level) CloseDoor(DOOR_CLOSE_1); + if (level.game_engine_type == GAME_ENGINE_TYPE_BD) + { + if (setup.bd_multiple_lives && game_status == GAME_MODE_MAIN) + { + // new BD game with multiple lives started, so set initial number of lives and global score + game_bd.global_lives = level.native_bd_level->caveset->initial_lives; + game_bd.global_score = 0; + } + else if (!setup.bd_multiple_lives) + { + // new BD game with normal, single life started (resetting global score is important here) + game_bd.global_lives = 0; + game_bd.global_score = 0; + } + } + if (restarting) { // force fading out global animations displayed during game play @@ -5086,6 +5102,9 @@ void GameWon(void) time = time_final; score = score_final; + if (level.game_engine_type == GAME_ENGINE_TYPE_BD && setup.bd_multiple_lives) + score = game_bd.global_score; + LevelSolved_DisplayFinalGameValues(time, score, health); } @@ -5228,7 +5247,21 @@ void GameEnd(void) { boolean restart_game = FALSE; - if (setup.ask_on_game_over) + if (level.game_engine_type == GAME_ENGINE_TYPE_BD && setup.bd_multiple_lives && + game_bd.global_lives > 0) + { + // do not restart intermission after game over (but continue with next level) + if (!level.bd_intermission) + { + // only decrement number of lives for normal levels, not for intermissions + game_bd.global_lives--; + + // do not handle game end if game over and playing with remaining multiple lives + if (game_bd.global_lives > 0) + restart_game = TRUE; + } + } + else if (setup.ask_on_game_over) { // do not handle game end if game over and automatically asking for game restart // (this is a special case: player pressed "return" key or fire button shortly before @@ -16492,6 +16525,11 @@ boolean CheckRestartGame(void) if (!setup.ask_on_game_over) return FALSE; + // do not ask to play again if playing BD game with multiple lifes + if (level.game_engine_type == GAME_ENGINE_TYPE_BD && setup.bd_multiple_lives && + game_bd.global_lives > 0) + return FALSE; + game.RestartGameRequested = TRUE; RequestRestartGame(); diff --git a/src/game_bd/bd_gameplay.c b/src/game_bd/bd_gameplay.c index 514524a9..d907247e 100644 --- a/src/game_bd/bd_gameplay.c +++ b/src/game_bd/bd_gameplay.c @@ -63,6 +63,7 @@ static void add_bonus_life(GdGame *game, boolean inform_user) // only add a life, if lives is > 0. // lives == 0 is a test run or a snapshot, no bonus life then. // also, obey max number of bonus lives. + game_bd.global_lives++; game->player_lives++; } } @@ -74,6 +75,7 @@ static void increment_score(GdGame *game, int increment) int i; i = game->player_score / gd_caveset_data->bonus_life_score; + game_bd.global_score += increment; game->player_score += increment; game->cave_score += increment; diff --git a/src/game_bd/export_bd.h b/src/game_bd/export_bd.h index f3b81d5b..018e84e6 100644 --- a/src/game_bd/export_bd.h +++ b/src/game_bd/export_bd.h @@ -54,6 +54,10 @@ struct GameInfo_BD // needed for saving score time int frames_played; + + // global lives and score over more than one game + int global_lives; + int global_score; }; struct LevelInfo_BD diff --git a/src/game_bd/main_bd.c b/src/game_bd/main_bd.c index a94dfde2..b23cbe98 100644 --- a/src/game_bd/main_bd.c +++ b/src/game_bd/main_bd.c @@ -286,7 +286,7 @@ static void UpdateGameDoorValues_BD(void) game_bd.time_left = time_left; game_bd.gems_still_needed = gems_still_needed; - game_bd.score = game_bd.game->player_score; + game_bd.score = game_bd.game->player_score; // use cave score here if (game.no_level_time_limit) game_bd.time_left = getTimePlayed_BD(); @@ -295,7 +295,7 @@ static void UpdateGameDoorValues_BD(void) { // update time and score in panel while counting bonus time game.LevelSolved_CountingTime = game_bd.time_left; - game.LevelSolved_CountingScore = game_bd.score; + game.LevelSolved_CountingScore = game_bd.global_score; // use global score here } } diff --git a/src/libgame/system.h b/src/libgame/system.h index 2f6d4313..5bae5afb 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -1579,6 +1579,7 @@ struct SetupInfo boolean game_speed_extended; int game_frame_delay; int default_game_engine_type; + boolean bd_multiple_lives; boolean bd_skip_uncovering; boolean bd_skip_hatching; boolean bd_scroll_delay; diff --git a/src/screens.c b/src/screens.c index d6dda4ac..a5cc1b6a 100644 --- a/src/screens.c +++ b/src/screens.c @@ -8576,6 +8576,7 @@ static struct TokenInfo setup_info_engines[] = { TYPE_ECS_AGA, &setup.prefer_aga_graphics, "Game Graphics Style:" }, { TYPE_EMPTY, NULL, "" }, { TYPE_HEADLINE, NULL, "Boulder Dash" }, + { TYPE_SWITCH, &setup.bd_multiple_lives, "Play with multiple lives:" }, { TYPE_SWITCH, &setup.bd_skip_uncovering, "Skip (un)covering screen:" }, { TYPE_SWITCH, &setup.bd_skip_hatching, "Skip hatching player:" }, { TYPE_SWITCH, &setup.bd_scroll_delay, "Scroll Delay:" }, -- 2.34.1