moved code to deactivate target element to separate function in MM engine
[rocksndiamonds.git] / src / game_mm / mm_game.c
index 85a9d4092995b18fcbdd5550ab4b60d1911a7895..c9712c9b2639521de4f612d63795cd249aaefc3a 100644 (file)
@@ -625,6 +625,7 @@ void InitGameEngine_MM(void)
     (native_mm_level.auto_count_kettles ? 0 : native_mm_level.kettles_needed);
   game_mm.lights_still_needed = 0;
   game_mm.num_keys = 0;
+  game_mm.ball_choice_pos = 0;
 
   game_mm.level_solved = FALSE;
   game_mm.game_over = FALSE;
@@ -647,6 +648,9 @@ void InitGameEngine_MM(void)
   laser.fuse_x = laser.fuse_y = -1;
 
   laser.dest_element = EL_EMPTY;
+  laser.dest_element_last = EL_EMPTY;
+  laser.dest_element_last_x = -1;
+  laser.dest_element_last_y = -1;
   laser.wall_mask = 0;
 
   last_LX = 0;
@@ -912,6 +916,29 @@ static int ScanPixel(void)
   return hit_mask;
 }
 
+static void DeactivateLaserTargetElement(void)
+{
+  if (laser.dest_element_last == EL_BOMB_ACTIVE ||
+      laser.dest_element_last == EL_MINE_ACTIVE ||
+      laser.dest_element_last == EL_GRAY_BALL_OPENING)
+  {
+    int x = laser.dest_element_last_x;
+    int y = laser.dest_element_last_y;
+    int element = laser.dest_element_last;
+
+    if (Tile[x][y] == element)
+      Tile[x][y] = (element == EL_BOMB_ACTIVE ? EL_BOMB :
+                   element == EL_MINE_ACTIVE ? EL_MINE : EL_BALL_GRAY);
+
+    if (Tile[x][y] == EL_BALL_GRAY)
+      MovDelay[x][y] = 0;
+
+    laser.dest_element_last = EL_EMPTY;
+    laser.dest_element_last_x = -1;
+    laser.dest_element_last_y = -1;
+  }
+}
+
 void ScanLaser(void)
 {
   int element;
@@ -921,6 +948,8 @@ void ScanLaser(void)
   if (game_mm.game_over)
     return;
 
+  DeactivateLaserTargetElement();
+
   laser.overloaded = FALSE;
   laser.stops_inside_element = FALSE;
 
@@ -1559,6 +1588,12 @@ boolean HitElement(int element, int hit_mask)
   {
     PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
 
+    Tile[ELX][ELY] = (element == EL_BOMB ? EL_BOMB_ACTIVE : EL_MINE_ACTIVE);
+
+    laser.dest_element_last = Tile[ELX][ELY];
+    laser.dest_element_last_x = ELX;
+    laser.dest_element_last_y = ELY;
+
     if (element == EL_MINE)
       laser.overloaded = TRUE;
   }
@@ -2378,7 +2413,8 @@ static void OpenSurpriseBall(int x, int y)
     if (!MovDelay[x][y])
     {
       Tile[x][y] = Store[x][y];
-      Store[x][y] = 0;
+      Store[x][y] = Store2[x][y] = 0;
+
       DrawField_MM(x, y);
 
       ScanLaser();
@@ -2518,7 +2554,7 @@ static void Explode_MM(int x, int y, int phase, int mode)
       Tile[x][y] = center_element;
     }
 
-    if (center_element == EL_BOMB || IS_MCDUFFIN(center_element))
+    if (center_element == EL_BOMB_ACTIVE || IS_MCDUFFIN(center_element))
       Store[x][y] = center_element;
     else
       Store[x][y] = EL_EMPTY;
@@ -2550,7 +2586,7 @@ static void Explode_MM(int x, int y, int phase, int mode)
 
   if (phase == last_phase)
   {
-    if (Store[x][y] == EL_BOMB)
+    if (Store[x][y] == EL_BOMB_ACTIVE)
     {
       DrawLaser(0, DL_LASER_DISABLED);
       InitLaser();
@@ -2597,7 +2633,7 @@ static void Bang_MM(int x, int y)
 
   if (IS_PACMAN(element))
     PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
-  else if (element == EL_BOMB || IS_MCDUFFIN(element))
+  else if (element == EL_BOMB_ACTIVE || IS_MCDUFFIN(element))
     PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
   else if (element == EL_KEY)
     PlayLevelSound_MM(x, y, element, MM_ACTION_EXPLODING);
@@ -3199,7 +3235,9 @@ static void GameActions_MM_Ext(void)
 
   if (!laser.overloaded && laser.overload_value == 0 &&
       element != EL_BOMB &&
+      element != EL_BOMB_ACTIVE &&
       element != EL_MINE &&
+      element != EL_MINE_ACTIVE &&
       element != EL_BALL_GRAY &&
       element != EL_BLOCK_STONE &&
       element != EL_BLOCK_WOOD &&
@@ -3307,26 +3345,38 @@ static void GameActions_MM_Ext(void)
 
   if (element == EL_BALL_GRAY && CT > native_mm_level.time_ball)
   {
-    static int new_elements[] =
+    if (!Store2[ELX][ELY])     // check if content element not yet determined
     {
-      EL_MIRROR_START,
-      EL_MIRROR_FIXED_START,
-      EL_POLAR_START,
-      EL_POLAR_CROSS_START,
-      EL_PACMAN_START,
-      EL_KETTLE,
-      EL_BOMB,
-      EL_PRISM
-    };
-    int num_new_elements = sizeof(new_elements) / sizeof(int);
-    int new_element = new_elements[RND(num_new_elements)];
-
-    Store[ELX][ELY] = new_element + RND(get_num_elements(new_element));
+      int last_anim_random_frame = gfx.anim_random_frame;
+      int element_pos;
+
+      if (native_mm_level.ball_choice_mode == ANIM_RANDOM)
+       gfx.anim_random_frame = RND(native_mm_level.num_ball_contents);
+
+      element_pos = getAnimationFrame(native_mm_level.num_ball_contents, 1,
+                                     native_mm_level.ball_choice_mode, 0,
+                                     game_mm.ball_choice_pos);
+
+      if (native_mm_level.ball_choice_mode == ANIM_RANDOM)
+       gfx.anim_random_frame = last_anim_random_frame;
+
+      game_mm.ball_choice_pos++;
+
+      int new_element = native_mm_level.ball_content[element_pos];
+
+      Store[ELX][ELY] = new_element + RND(get_num_elements(new_element));
+      Store2[ELX][ELY] = TRUE;
+    }
+
     Tile[ELX][ELY] = EL_GRAY_BALL_OPENING;
 
     // !!! CHECK AGAIN: Laser on Polarizer !!!
     ScanLaser();
 
+    laser.dest_element_last = Tile[ELX][ELY];
+    laser.dest_element_last_x = ELX;
+    laser.dest_element_last_y = ELY;
+
     return;
 
 #if 0