fixed unneccessarily complex code
[rocksndiamonds.git] / src / game_mm / mm_game.c
index 63e892c5eda19f7ad3f497aec8ee140ede460951..d6ba5374db4d5e50448ab0e7ead370bda84bb6c8 100644 (file)
@@ -825,6 +825,13 @@ void AddLaserEdge(int lx, int ly)
 
 void AddDamagedField(int ex, int ey)
 {
+  // prevent adding the same field position again
+  if (laser.num_damages > 0 &&
+      laser.damage[laser.num_damages - 1].x == ex &&
+      laser.damage[laser.num_damages - 1].y == ey &&
+      laser.damage[laser.num_damages - 1].edge == laser.num_edges)
+    return;
+
   laser.damage[laser.num_damages].is_mirror = FALSE;
   laser.damage[laser.num_damages].angle = laser.current_angle;
   laser.damage[laser.num_damages].edge = laser.num_edges;
@@ -1656,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)
@@ -1686,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);
 
@@ -2460,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);
     }
 
@@ -2475,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;
@@ -2617,15 +2668,14 @@ static void Explode_MM(int x, int y, int phase, int mode)
       Tile[x][y] = center_element;
     }
 
-    if (center_element == EL_BOMB_ACTIVE || IS_MCDUFFIN(center_element))
-      Store[x][y] = center_element;
-    else
-      Store[x][y] = EL_EMPTY;
-
+    Store[x][y] = center_element;
     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;
 
@@ -2655,7 +2705,6 @@ static void Explode_MM(int x, int y, int phase, int mode)
       InitLaser();
 
       Bang_MM(laser.start_edge.x, laser.start_edge.y);
-      Store[x][y] = EL_EMPTY;
 
       GameOver_MM(GAME_OVER_DELAYED);
 
@@ -2663,12 +2712,11 @@ static void Explode_MM(int x, int y, int phase, int mode)
     }
     else if (IS_MCDUFFIN(Store[x][y]))
     {
-      Store[x][y] = EL_EMPTY;
-
       GameOver_MM(GAME_OVER_BOMB);
     }
 
-    Tile[x][y] = Store[x][y];
+    Tile[x][y] = EL_EMPTY;
+
     Store[x][y] = Store2[x][y] = 0;
     MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
 
@@ -2976,6 +3024,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;
@@ -3232,6 +3286,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)
@@ -3434,7 +3490,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;
     }