fixed explosion graphics for bomb and McDuffin for MM engine
[rocksndiamonds.git] / src / game_mm / mm_game.c
index 641aa4fde5c8fdf0759e408bb686fdf80fddc4d6..c6256e46f6c31db01f5264fb4ccd20c9fc4d5ed6 100644 (file)
@@ -1663,9 +1663,11 @@ boolean HitElement(int element, int hit_mask)
       element == EL_KEY ||
       element == EL_LIGHTBALL ||
       element == EL_PACMAN ||
-      IS_PACMAN(element))
+      IS_PACMAN(element) ||
+      IS_ENVELOPE(element))
   {
-    if (!IS_PACMAN(element))
+    if (!IS_PACMAN(element) &&
+       !IS_ENVELOPE(element))
       Bang_MM(ELX, ELY);
 
     if (element == EL_PACMAN)
@@ -1693,6 +1695,10 @@ boolean HitElement(int element, int hit_mask)
     {
       DeletePacMan(ELX, ELY);
     }
+    else if (IS_ENVELOPE(element))
+    {
+      Tile[ELX][ELY] = EL_ENVELOPE_1_OPENING + ENVELOPE_NR(Tile[ELX][ELY]);
+    }
 
     RaiseScoreElement_MM(element);
 
@@ -2467,6 +2473,8 @@ static void OpenSurpriseBall(int x, int y)
       BlitBitmap(bitmap, drawto, gx + dx, gy + dy, 6, 6,
                 cSX + x * TILEX + dx, cSY + y * TILEY + dy);
 
+      laser.redraw = TRUE;
+
       MarkTileDirty(x, y);
     }
 
@@ -2482,6 +2490,42 @@ static void OpenSurpriseBall(int x, int y)
   }
 }
 
+static void OpenEnvelope(int x, int y)
+{
+  int num_frames = 8;          // seven frames plus final empty space
+
+  if (!MovDelay[x][y])         // next animation frame
+    MovDelay[x][y] = num_frames;
+
+  if (MovDelay[x][y])          // wait some time before next frame
+  {
+    int nr = ENVELOPE_OPENING_NR(Tile[x][y]);
+
+    MovDelay[x][y]--;
+
+    if (MovDelay[x][y] > 0 && IN_SCR_FIELD(x, y))
+    {
+      int graphic = el_act2gfx(EL_ENVELOPE_1 + nr, MM_ACTION_COLLECTING);
+      int frame = num_frames - MovDelay[x][y] - 1;
+
+      DrawGraphicAnimation_MM(x, y, graphic, frame);
+
+      laser.redraw = TRUE;
+    }
+
+    if (MovDelay[x][y] == 0)
+    {
+      Tile[x][y] = EL_EMPTY;
+
+      DrawField_MM(x, y);
+
+      ScanLaser();
+
+      ShowEnvelope_MM(nr);
+    }
+  }
+}
+
 static void MeltIce(int x, int y)
 {
   int frames = 5;
@@ -2632,7 +2676,10 @@ static void Explode_MM(int x, int y, int phase, int mode)
     Store2[x][y] = mode;
 
     Tile[x][y] = EL_EXPLODING_OPAQUE;
-    GfxElement[x][y] = center_element;
+
+    GfxElement[x][y] = (center_element == EL_BOMB_ACTIVE ? EL_BOMB :
+                       IS_MCDUFFIN(center_element) ? EL_MCDUFFIN :
+                       center_element);
 
     MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
 
@@ -2983,6 +3030,12 @@ boolean ClickElement(int x, int y, int button)
 
     element_clicked = TRUE;
   }
+  else if (IS_ENVELOPE(element))
+  {
+    Tile[x][y] = EL_ENVELOPE_1_OPENING + ENVELOPE_NR(element);
+
+    element_clicked = TRUE;
+  }
 
   click_delay.value = (new_button ? CLICK_DELAY_FIRST : CLICK_DELAY);
   new_button = FALSE;
@@ -3239,6 +3292,8 @@ static void GameActions_MM_Ext(void)
       OpenExit(x, y);
     else if (element == EL_GRAY_BALL_OPENING)
       OpenSurpriseBall(x, y);
+    else if (IS_ENVELOPE_OPENING(element))
+      OpenEnvelope(x, y);
     else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_ICE)
       MeltIce(x, y);
     else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_AMOEBA)
@@ -3441,7 +3496,11 @@ static void GameActions_MM_Ext(void)
 
       int new_element = native_mm_level.ball_content[element_pos];
 
-      Store[ELX][ELY] = new_element + RND(get_num_elements(new_element));
+      // randomly rotate newly created game element, if needed
+      if (native_mm_level.rotate_ball_content)
+       new_element = get_rotated_element(new_element, RND(16));
+
+      Store[ELX][ELY] = new_element;
       Store2[ELX][ELY] = TRUE;
     }