fixed using custom laser color defined in DF style laser for MM engine
[rocksndiamonds.git] / src / game_mm / mm_game.c
index e817b1187613c8cb76445be6ba5b48137bd8267f..45c65634a9985556c75420f04edc463ead080198 100644 (file)
@@ -433,9 +433,9 @@ static void SetLaserColor(int brightness)
 
   pen_ray =
     GetPixelFromRGB(window,
-                   (native_mm_level.laser_red   ? color_max  : color_up),
-                   (native_mm_level.laser_green ? color_down : color_min),
-                   (native_mm_level.laser_blue  ? color_down : color_min));
+                   (game_mm.laser_red   ? color_max  : color_up),
+                   (game_mm.laser_green ? color_down : color_min),
+                   (game_mm.laser_blue  ? color_down : color_min));
 }
 
 static void InitMovDir_MM(int x, int y)
@@ -538,6 +538,19 @@ static void InitField(int x, int y)
        laser.start_edge.x = x;
        laser.start_edge.y = y;
        laser.start_angle = get_element_angle(element);
+
+        if (IS_MCDUFFIN(element))
+        {
+          game_mm.laser_red   = native_mm_level.mm_laser_red;
+          game_mm.laser_green = native_mm_level.mm_laser_green;
+          game_mm.laser_blue  = native_mm_level.mm_laser_blue;
+        }
+        else
+        {
+          game_mm.laser_red   = native_mm_level.df_laser_red;
+          game_mm.laser_green = native_mm_level.df_laser_green;
+          game_mm.laser_blue  = native_mm_level.df_laser_blue;
+        }
       }
 
       break;
@@ -625,6 +638,11 @@ 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.laser_red = FALSE;
+  game_mm.laser_green = FALSE;
+  game_mm.laser_blue = TRUE;
 
   game_mm.level_solved = FALSE;
   game_mm.game_over = FALSE;
@@ -915,29 +933,43 @@ static int ScanPixel(void)
   return hit_mask;
 }
 
-void ScanLaser(void)
+static void DeactivateLaserTargetElement(void)
 {
-  int element;
-  int end = 0, rf = laser.num_edges;
-
-  // do not scan laser again after the game was lost for whatever reason
-  if (game_mm.game_over)
-    return;
-
   if (laser.dest_element_last == EL_BOMB_ACTIVE ||
-      laser.dest_element_last == EL_MINE_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 : EL_MINE);
+      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;
+  int end = 0, rf = laser.num_edges;
+
+  // do not scan laser again after the game was lost for whatever reason
+  if (game_mm.game_over)
+    return;
+
+  // do not scan laser if fuse is off
+  if (laser.fuse_off)
+    return;
+
+  DeactivateLaserTargetElement();
 
   laser.overloaded = FALSE;
   laser.stops_inside_element = FALSE;
@@ -1314,6 +1346,13 @@ static void DrawLaserExt(int start_edge, int num_edges, int mode)
 
 void DrawLaser(int start_edge, int mode)
 {
+  // do not draw laser if fuse is off
+  if (laser.fuse_off && mode == DL_LASER_ENABLED)
+    return;
+
+  if (mode == DL_LASER_DISABLED)
+    DeactivateLaserTargetElement();
+
   if (laser.num_edges - start_edge < 0)
   {
     Warn("DrawLaser: laser.num_edges - start_edge < 0");
@@ -2402,7 +2441,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();
@@ -3333,26 +3373,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