added delayed game over if BD player can be re-created from effect
authorHolger Schemel <holger.schemel@virtion.de>
Wed, 4 Dec 2024 19:41:20 +0000 (20:41 +0100)
committerHolger Schemel <holger.schemel@virtion.de>
Wed, 4 Dec 2024 15:42:21 +0000 (16:42 +0100)
src/game_bd/bd_cave.h
src/game_bd/bd_caveengine.c
src/game_bd/bd_caveobject.c

index 2bd4b0d3ef0ab62c0df23c0e422d868b688f54a6..a1de37923145b46b9bce3041c095e20d9fef7465 100644 (file)
@@ -336,6 +336,9 @@ typedef struct _gd_c64_random_generator
 #define GD_HIGHSCORE_NUM               20
 #define GD_PLAYER_MEM_SIZE             16
 
+#define GD_PLAYER_GONE_LIMIT_STANDARD  1
+#define GD_PLAYER_GONE_LIMIT_EXTENDED  15
+
 typedef struct _gd_cave
 {
   // Defined by the editor. public data :)
@@ -626,6 +629,7 @@ typedef struct _gd_cave
   GdMagicWallState magic_wall_state;    // State of magic wall
   GdPlayerState player_state;           // Player state. not yet living, living, exited...
   int player_seen_ago;                  // player was seen this number of scans ago
+  int player_seen_ago_limit;            // number of scans player has to be gone for game over
   boolean voodoo_touched;               // as its name says
   boolean kill_player;                  // Voodoo died, or used pressed escape to restart level.
   boolean sweet_eaten;                  // player ate sweet, he's strong. prob_sweet applies,
index e64699dedc86b831de2b10f57971c8d2ee697ed1..11bdbe81e2a251e87840a171ffafed82d61e6503 100644 (file)
@@ -4104,8 +4104,10 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire,
 
   // PLAYER
 
-  // check if player is alive. (delay reduced from 15 to 1 to faster detect game over)
-  if ((cave->player_state == GD_PL_LIVING && cave->player_seen_ago > 1) || cave->kill_player)
+  // check if player is alive. (delay reduced from 15 to 1 to faster detect game over,
+  // but may be set back to 15 if a dead player can be re-created from effects element)
+  if (cave->kill_player ||
+      (cave->player_state == GD_PL_LIVING && cave->player_seen_ago > cave->player_seen_ago_limit))
     cave->player_state = GD_PL_DIED;
 
   // check if any voodoo exploded, and kill players the next scan if that happended.
index 9b68d9a7fc918808dc197f464f20aa4cdbe4e56b..ab9551b0ee41ae5d3a7f6f6fbd54138d9b06a5d7 100644 (file)
@@ -1430,7 +1430,7 @@ GdCave *gd_cave_new_rendered(const GdCave *data, const int level, const unsigned
 {
   GdCave *cave;
   GdElement element;
-  int x, y;
+  int i, x, y;
   List *iter;
 
   // make a copy
@@ -1587,6 +1587,60 @@ GdCave *gd_cave_new_rendered(const GdCave *data, const int level, const unsigned
   cave->last_direction = GD_MV_STILL;
   cave->last_horizontal_direction = GD_MV_STILL;
 
+  // list of cave variables for effects that can create other game elements
+  GdElement *effects_list[] =
+  {
+    &cave->amoeba_enclosed_effect,
+    &cave->amoeba_too_big_effect,
+    &cave->amoeba_2_enclosed_effect,
+    &cave->amoeba_2_too_big_effect,
+    &cave->amoeba_2_explosion_effect,
+    &cave->acid_turns_to,
+    &cave->nut_turns_to_when_crushed,
+    &cave->slime_converts_1,
+    &cave->slime_converts_2,
+    &cave->slime_converts_3,
+    &cave->explosion_effect,
+    &cave->explosion_3_effect,
+    &cave->diamond_birth_effect,
+    &cave->bomb_explosion_effect,
+    &cave->nitro_explosion_effect,
+    &cave->firefly_explode_to,
+    &cave->alt_firefly_explode_to,
+    &cave->butterfly_explode_to,
+    &cave->alt_butterfly_explode_to,
+    &cave->stonefly_explode_to,
+    &cave->dragonfly_explode_to,
+    &cave->stone_falling_effect,
+    &cave->diamond_falling_effect,
+    &cave->stone_bouncing_effect,
+    &cave->diamond_bouncing_effect,
+    &cave->magic_stone_to,
+    &cave->magic_diamond_to,
+    &cave->magic_mega_stone_to,
+    &cave->magic_light_stone_to,
+    &cave->magic_nitro_pack_to,
+    &cave->magic_nut_to,
+    &cave->magic_flying_stone_to,
+    &cave->magic_flying_diamond_to,
+  };
+
+  // default: immediate game over if player not seen on playfield anymore
+  cave->player_seen_ago_limit = GD_PLAYER_GONE_LIMIT_STANDARD;
+
+  // check if player can be created from effects element in this cave
+  for (i = 0; i < ARRAY_SIZE(effects_list); i++)
+  {
+    int element = *effects_list[i];
+
+    if ((element >= O_PRE_PL_1 && element <= O_PRE_PL_3) ||
+        (gd_element_properties[element].properties & P_PLAYER) != 0)
+    {
+      // wait some extra time if player can be re-created from effects element
+      cave->player_seen_ago_limit = GD_PLAYER_GONE_LIMIT_EXTENDED;
+    }
+  }
+
   return cave;
 }