added support for playing BD games with multiple lives and global score
authorHolger Schemel <holger.schemel@virtion.de>
Fri, 3 Jan 2025 23:31:36 +0000 (00:31 +0100)
committerHolger Schemel <holger.schemel@virtion.de>
Sat, 4 Jan 2025 01:00:35 +0000 (02:00 +0100)
src/files.c
src/game.c
src/game_bd/bd_gameplay.c
src/game_bd/export_bd.h
src/game_bd/main_bd.c
src/libgame/system.h
src/screens.c

index af7f9c7a3a37fe6b63c84971396885b58397f513..c6faf9e589784302c5f82b0a5a1171b5d50342a3 100644 (file)
@@ -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;
index af5b0e2cdb620caf0ca053620d090e71274d39f1..3a6662c3faa12b067591a900ef4aac29fba68d51 100644 (file)
@@ -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();
index 514524a956cc161f4643db55e38525952868980e..d907247e775e921606d2ed35485812696278c2c1 100644 (file)
@@ -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;
 
index f3b81d5b8c08b2579c5856eba302981bc1fe1dd2..018e84e65d9d1aa1ad4952c00546deda6b34d331 100644 (file)
@@ -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
index a94dfde209ca727a0f2e6ff938dda4baf79fc7da..b23cbe987d50cf5810050fe85ce3052b90290570 100644 (file)
@@ -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
   }
 }
 
index 2f6d431314de6f5c936ab191564eeefa17c7dc90..5bae5afbdaac76c1a52600d603d67703933ac755 100644 (file)
@@ -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;
index d6dda4acf44e03703f180eb4ff146f23052995b6..a5cc1b6afc315275523a76903b111fba05482a55 100644 (file)
@@ -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:"                 },