rnd-20021123-1-src
[rocksndiamonds.git] / src / game.c
index 81f233b0d2fd2062adf09c6164087d37521528d7..8db4cefb8a6c0183add60ec991e90ae445e7cf7c 100644 (file)
@@ -292,6 +292,8 @@ static void InitField(int x, int y, boolean init_game)
          Feld[x][y] = EL_SP_MURPHY_CLONE;
          break;
        }
+
+       Feld[x][y] = EL_PLAYER1;
       }
       /* no break! */
     case EL_PLAYER1:
@@ -1704,15 +1706,13 @@ void Explode(int ex, int ey, int phase, int mode)
     if (IS_PLAYER(x, y) && !PLAYERINFO(x,y)->present)
       StorePlayer[x][y] = 0;
   }
-  else if (!(phase % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+  else if (phase >= delay && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
   {
-    int graphic = IMG_EXPLOSION;
-    int frame = (phase / delay - 1);
-
-    if (game.emulation == EMU_SUPAPLEX)
-      graphic = (Store[x][y] == EL_SP_INFOTRON ?
-                IMG_SP_EXPLOSION_INFOTRON :
-                IMG_SP_EXPLOSION);
+    int stored = Store[x][y];
+    int graphic = (game.emulation != EMU_SUPAPLEX ? IMG_EXPLOSION :
+                  stored == EL_SP_INFOTRON ? IMG_SP_EXPLOSION_INFOTRON :
+                  IMG_SP_EXPLOSION);
+    int frame = getGraphicAnimationFrame(graphic, phase - delay);
 
     if (phase == delay)
       DrawCrumbledSand(SCREENX(x), SCREENY(y));
@@ -2326,18 +2326,18 @@ void TurnRound(int x, int y)
 
   int element = Feld[x][y];
   int old_move_dir = MovDir[x][y];
-  int left_dir = turn[old_move_dir].left;
+  int left_dir  = turn[old_move_dir].left;
   int right_dir = turn[old_move_dir].right;
-  int back_dir = turn[old_move_dir].back;
+  int back_dir  = turn[old_move_dir].back;
 
-  int left_dx = move_xy[left_dir].x, left_dy = move_xy[left_dir].y;
-  int right_dx = move_xy[right_dir].x, right_dy = move_xy[right_dir].y;
-  int move_dx = move_xy[old_move_dir].x, move_dy = move_xy[old_move_dir].y;
-  int back_dx = move_xy[back_dir].x, back_dy = move_xy[back_dir].y;
+  int left_dx  = move_xy[left_dir].x,     left_dy  = move_xy[left_dir].y;
+  int right_dx = move_xy[right_dir].x,    right_dy = move_xy[right_dir].y;
+  int move_dx  = move_xy[old_move_dir].x, move_dy  = move_xy[old_move_dir].y;
+  int back_dx  = move_xy[back_dir].x,     back_dy  = move_xy[back_dir].y;
 
-  int left_x = x+left_dx, left_y = y+left_dy;
-  int right_x = x+right_dx, right_y = y+right_dy;
-  int move_x = x+move_dx, move_y = y+move_dy;
+  int left_x  = x + left_dx,  left_y  = y + left_dy;
+  int right_x = x + right_dx, right_y = y + right_dy;
+  int move_x  = x + move_dx,  move_y  = y + move_dy;
 
   if (element == EL_BUG || element == EL_BD_BUTTERFLY)
   {
@@ -2581,17 +2581,18 @@ void TurnRound(int x, int y)
     MovDir[x][y] = game.balloon_dir;
     MovDelay[x][y] = 0;
   }
-  else if (element == EL_SPRING_MOVING)
+  else if (element == EL_SPRING)
   {
-    if (!IN_LEV_FIELD(move_x, move_y) || !IS_FREE(move_x, move_y) ||
-       (IN_LEV_FIELD(x, y+1) && IS_FREE(x, y+1)))
-    {
-      Feld[x][y] = EL_SPRING;
+    if ((MovDir[x][y] == MV_LEFT || MovDir[x][y] == MV_RIGHT) &&
+       (!IN_LEV_FIELD(move_x, move_y) || !IS_FREE(move_x, move_y) ||
+        (IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1))))
       MovDir[x][y] = MV_NO_MOVING;
-    }
+
     MovDelay[x][y] = 0;
   }
-  else if (element == EL_ROBOT || element == EL_SATELLITE || element == EL_PENGUIN)
+  else if (element == EL_ROBOT ||
+          element == EL_SATELLITE ||
+          element == EL_PENGUIN)
   {
     int attr_x = -1, attr_y = -1;
 
@@ -2918,24 +2919,38 @@ void StartMoving(int x, int y)
       }
     }
   }
-  else if (CAN_MOVE(element))
+
+  if (CAN_MOVE(element))       /* not "else if" because of EL_SPRING */
   {
     int newx, newy;
 
-    if ((element == EL_SATELLITE || element == EL_BALLOON ||
-        element == EL_SPRING_MOVING)
+    if ((element == EL_SATELLITE ||
+        element == EL_BALLOON ||
+        element == EL_SPRING)
        && JustBeingPushed(x, y))
       return;
 
+    if (element == EL_SPRING && MovDir[x][y] == MV_DOWN)
+      Feld[x][y + 1] = EL_EMPTY;       /* was set to EL_BLOCKED above */
+
     if (!MovDelay[x][y])       /* start new movement phase */
     {
       /* all objects that can change their move direction after each step */
       /* (MAMPFER, MAMPFER2 and PACMAN go straight until they hit a wall  */
 
-      if (element!=EL_YAMYAM && element!=EL_DARK_YAMYAM && element!=EL_PACMAN)
+      if (element != EL_YAMYAM &&
+         element != EL_DARK_YAMYAM &&
+         element != EL_PACMAN)
       {
+#if 0
+  if (element == EL_SPRING)
+    printf("1--> %d\n", MovDir[x][y]);
+#endif
        TurnRound(x, y);
-
+#if 0
+  if (element == EL_SPRING)
+    printf("2--> %d\n", MovDir[x][y]);
+#endif
        if (MovDelay[x][y] && (element == EL_BUG ||
                               element == EL_SPACESHIP ||
                               element == EL_SP_SNIKSNAK ||
@@ -3256,7 +3271,7 @@ void ContinueMoving(int x, int y)
   int direction = MovDir[x][y];
   int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
   int dy = (direction == MV_UP   ? -1 : direction == MV_DOWN  ? +1 : 0);
-  int horiz_move = (dx!=0);
+  int horiz_move = (dx != 0);
   int newx = x + dx, newy = y + dy;
   int step = (horiz_move ? dx : dy) * TILEX / 8;
 
@@ -3273,8 +3288,8 @@ void ContinueMoving(int x, int y)
   else if (CAN_FALL(element) && horiz_move &&
           y < lev_fieldy-1 && IS_BELT_ACTIVE(Feld[x][y+1]))
     step /= 2;
-  else if (element == EL_SPRING_MOVING)
-    step*=2;
+  else if (element == EL_SPRING && horiz_move)
+    step *= 2;
 
 #if OLD_GAME_BEHAVIOUR
   else if (CAN_FALL(element) && horiz_move && !IS_SP_ELEMENT(element))
@@ -3369,8 +3384,13 @@ void ContinueMoving(int x, int y)
     GfxAction[newx][newy] = GfxAction[x][y];   /* keep action one frame */
     GfxAction[x][y] = GFX_ACTION_DEFAULT;
 
+#if 0
     if (!CAN_MOVE(element))
       MovDir[newx][newy] = 0;
+#else
+    if (CAN_FALL(element) && MovDir[newx][newy] == MV_DOWN)
+      MovDir[newx][newy] = 0;
+#endif
 
     DrawLevelField(x, y);
     DrawLevelField(newx, newy);
@@ -3895,14 +3915,15 @@ void RobotWheel(int x, int y)
        DrawGraphic(SCREENX(x), SCREENY(y), IMG_ROBOT_WHEEL_ACTIVE, frame);
       }
 
-      if (!(MovDelay[x][y]%4))
-       PlaySoundLevel(x, y, SND_ROBOT_WHEEL_ACTIVE);
+      PlaySoundLevel(x, y, SND_ROBOT_WHEEL_ACTIVE);
+
       return;
     }
   }
 
   Feld[x][y] = EL_ROBOT_WHEEL;
   DrawLevelField(x, y);
+
   if (ZX == x && ZY == y)
     ZX = ZY = -1;
 }
@@ -3924,23 +3945,20 @@ void TimegateWheel(int x, int y)
        DrawGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_SWITCH_ACTIVE, frame);
       }
 
-      if (!(MovDelay[x][y]%4))
-       PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVE);
+      PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVE);
+
       return;
     }
   }
 
   Feld[x][y] = EL_TIMEGATE_SWITCH;
   DrawLevelField(x, y);
+
+  /* !!! THIS LOOKS WRONG !!! */
   if (ZX == x && ZY == y)
     ZX = ZY = -1;
 }
 
-void Blubber(int x, int y)
-{
-  DrawGraphicAnimation(x, y, IMG_ACID);
-}
-
 void NussKnacken(int x, int y)
 {
   if (!MovDelay[x][y])         /* next animation frame */
@@ -3949,20 +3967,22 @@ void NussKnacken(int x, int y)
   if (MovDelay[x][y])          /* wait some time before next frame */
   {
     MovDelay[x][y]--;
-    if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+    if (MovDelay[x][y])
     {
-      int frame = getGraphicAnimationFrame(IMG_NUT_CRACKING,
-                                          6 - MovDelay[x][y]);
+      if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+      {
+       int frame = getGraphicAnimationFrame(IMG_NUT_CRACKING,
+                                            6 - MovDelay[x][y]);
 
-      DrawGraphic(SCREENX(x), SCREENY(y), IMG_NUT_CRACKING, frame);
-    }
+       DrawGraphic(SCREENX(x), SCREENY(y), IMG_NUT_CRACKING, frame);
+      }
 
-    if (!MovDelay[x][y])
-    {
-      Feld[x][y] = EL_EMERALD;
-      DrawLevelField(x, y);
+      return;
     }
   }
+
+  Feld[x][y] = EL_EMERALD;
+  DrawLevelField(x, y);
 }
 
 void BreakingPearl(int x, int y)
@@ -3973,20 +3993,22 @@ void BreakingPearl(int x, int y)
   if (MovDelay[x][y])          /* wait some time before next frame */
   {
     MovDelay[x][y]--;
-    if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+    if (MovDelay[x][y])
     {
-      int frame = getGraphicAnimationFrame(IMG_PEARL_BREAKING,
-                                          8 - MovDelay[x][y]);
+      if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+      {
+       int frame = getGraphicAnimationFrame(IMG_PEARL_BREAKING,
+                                            8 - MovDelay[x][y]);
 
-      DrawGraphic(SCREENX(x), SCREENY(y), IMG_PEARL_BREAKING, frame);
-    }
+       DrawGraphic(SCREENX(x), SCREENY(y), IMG_PEARL_BREAKING, frame);
+      }
 
-    if (!MovDelay[x][y])
-    {
-      Feld[x][y] = EL_EMPTY;
-      DrawLevelField(x, y);
+      return;
     }
   }
+
+  Feld[x][y] = EL_EMPTY;
+  DrawLevelField(x, y);
 }
 
 void SiebAktivieren(int x, int y, int type)
@@ -4038,26 +4060,24 @@ void AusgangstuerOeffnen(int x, int y)
     int tuer;
 
     MovDelay[x][y]--;
-    tuer = MovDelay[x][y]/delay;
-    if (!(MovDelay[x][y]%delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+    tuer = MovDelay[x][y] / delay;
+
+    if (!(MovDelay[x][y] % delay))
     {
-      int frame = getGraphicAnimationFrame(IMG_EXIT_OPENING,
-                                          29 - MovDelay[x][y]);
+      if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+      {
+       int frame = getGraphicAnimationFrame(IMG_EXIT_OPENING,
+                                            29 - MovDelay[x][y]);
 
-      DrawGraphic(SCREENX(x), SCREENY(y), IMG_EXIT_OPENING, frame);
-    }
+       DrawGraphic(SCREENX(x), SCREENY(y), IMG_EXIT_OPENING, frame);
+      }
 
-    if (!MovDelay[x][y])
-    {
-      Feld[x][y] = EL_EXIT_OPEN;
-      DrawLevelField(x, y);
+      return;
     }
   }
-}
 
-void AusgangstuerBlinken(int x, int y)
-{
-  DrawGraphicAnimation(x, y, IMG_EXIT_OPEN);
+  Feld[x][y] = EL_EXIT_OPEN;
+  DrawLevelField(x, y);
 }
 
 void OpenSwitchgate(int x, int y)
@@ -4071,20 +4091,22 @@ void OpenSwitchgate(int x, int y)
   {
     MovDelay[x][y]--;
 
-    if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+    if (!(MovDelay[x][y] % delay))
     {
-      int frame = getGraphicAnimationFrame(IMG_SWITCHGATE_OPENING,
-                                          29 - MovDelay[x][y]);
+      if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+      {
+       int frame = getGraphicAnimationFrame(IMG_SWITCHGATE_OPENING,
+                                            29 - MovDelay[x][y]);
 
-      DrawGraphic(SCREENX(x), SCREENY(y), IMG_SWITCHGATE_OPENING, frame);
-    }
+       DrawGraphic(SCREENX(x), SCREENY(y), IMG_SWITCHGATE_OPENING, frame);
+      }
 
-    if (!MovDelay[x][y])
-    {
-      Feld[x][y] = EL_SWITCHGATE_OPEN;
-      DrawLevelField(x, y);
+      return;
     }
   }
+
+  Feld[x][y] = EL_SWITCHGATE_OPEN;
+  DrawLevelField(x, y);
 }
 
 void CloseSwitchgate(int x, int y)
@@ -4098,20 +4120,22 @@ void CloseSwitchgate(int x, int y)
   {
     MovDelay[x][y]--;
 
-    if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+    if (!(MovDelay[x][y] % delay))
     {
-      int frame = getGraphicAnimationFrame(IMG_SWITCHGATE_CLOSING,
-                                          29 - MovDelay[x][y]);
+      if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+      {
+       int frame = getGraphicAnimationFrame(IMG_SWITCHGATE_CLOSING,
+                                            29 - MovDelay[x][y]);
 
-      DrawGraphic(SCREENX(x), SCREENY(y), IMG_SWITCHGATE_CLOSING, frame);
-    }
+       DrawGraphic(SCREENX(x), SCREENY(y), IMG_SWITCHGATE_CLOSING, frame);
+      }
 
-    if (!MovDelay[x][y])
-    {
-      Feld[x][y] = EL_SWITCHGATE_CLOSED;
-      DrawLevelField(x, y);
+      return;
     }
   }
+
+  Feld[x][y] = EL_SWITCHGATE_CLOSED;
+  DrawLevelField(x, y);
 }
 
 void OpenTimegate(int x, int y)
@@ -4125,20 +4149,22 @@ void OpenTimegate(int x, int y)
   {
     MovDelay[x][y]--;
 
-    if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+    if (!(MovDelay[x][y] % delay))
     {
-      int frame = getGraphicAnimationFrame(IMG_TIMEGATE_OPENING,
-                                          29 - MovDelay[x][y]);
+      if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+      {
+       int frame = getGraphicAnimationFrame(IMG_TIMEGATE_OPENING,
+                                            29 - MovDelay[x][y]);
 
-      DrawGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_OPENING, frame);
-    }
+       DrawGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_OPENING, frame);
+      }
 
-    if (!MovDelay[x][y])
-    {
-      Feld[x][y] = EL_TIMEGATE_OPEN;
-      DrawLevelField(x, y);
+      return;
     }
   }
+
+  Feld[x][y] = EL_TIMEGATE_OPEN;
+  DrawLevelField(x, y);
 }
 
 void CloseTimegate(int x, int y)
@@ -4152,20 +4178,22 @@ void CloseTimegate(int x, int y)
   {
     MovDelay[x][y]--;
 
-    if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+    if (!(MovDelay[x][y] % delay))
     {
-      int frame = getGraphicAnimationFrame(IMG_TIMEGATE_CLOSING,
-                                          29 - MovDelay[x][y]);
+      if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+      {
+       int frame = getGraphicAnimationFrame(IMG_TIMEGATE_CLOSING,
+                                            29 - MovDelay[x][y]);
 
-      DrawGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_CLOSING, frame);
-    }
+       DrawGraphic(SCREENX(x), SCREENY(y), IMG_TIMEGATE_CLOSING, frame);
+      }
 
-    if (!MovDelay[x][y])
-    {
-      Feld[x][y] = EL_TIMEGATE_CLOSED;
-      DrawLevelField(x, y);
+      return;
     }
   }
+
+  Feld[x][y] = EL_TIMEGATE_CLOSED;
+  DrawLevelField(x, y);
 }
 
 static void CloseAllOpenTimegates()
@@ -4884,7 +4912,7 @@ void GameActions()
     else if (element == EL_TIMEGATE_SWITCH_ACTIVE)
       TimegateWheel(x, y);
     else if (element == EL_ACID)
-      Blubber(x, y);
+      DrawGraphicAnimation(x, y, IMG_ACID);
     else if (element == EL_ACID_SPLASH_LEFT ||
             element == EL_ACID_SPLASH_RIGHT)
       Blurb(x, y);
@@ -4899,9 +4927,9 @@ void GameActions()
     else if (element == EL_EXIT_OPENING)
       AusgangstuerOeffnen(x, y);
     else if (element == EL_EXIT_OPEN)
-      AusgangstuerBlinken(x, y);
+      DrawGraphicAnimation(x, y, IMG_EXIT_OPEN);
     else if (element == EL_SP_EXIT_OPEN)
-      ;                /* !!! ADD SOME (OPTIONAL) ANIMATIONS HERE !!! */
+      DrawGraphicAnimation(x, y, IMG_SP_EXIT_OPEN);
     else if (element == EL_WALL_GROWING_ACTIVE)
       MauerWaechst(x, y);
     else if (element == EL_WALL_GROWING ||
@@ -4918,14 +4946,7 @@ void GameActions()
     else if (element == EL_SP_TERMINAL)
       DrawGraphicAnimation(x, y, IMG_SP_TERMINAL);
     else if (element == EL_SP_TERMINAL_ACTIVE)
-    {
       DrawGraphicAnimation(x, y, IMG_SP_TERMINAL_ACTIVE);
-
-#if 0
-      if (!(FrameCounter % 4))
-       PlaySoundLevel(x, y, SND_SP_TERMINAL_ACTIVE);
-#endif
-    }
     else if (IS_BELT_ACTIVE(element))
       DrawBeltAnimation(x, y, element);
     else if (element == EL_SWITCHGATE_OPENING)
@@ -4939,24 +4960,10 @@ void GameActions()
     else if (element == EL_EXTRA_TIME)
       DrawGraphicAnimation(x, y, IMG_EXTRA_TIME);
     else if (element == EL_SHIELD_NORMAL)
-    {
       DrawGraphicAnimation(x, y, IMG_SHIELD_NORMAL);
-
-#if 0
-      if (!(FrameCounter % 4))
-       PlaySoundLevel(x, y, SND_SHIELD_PASSIVE_ACTIVATED);
-#endif
-    }
     else if (element == EL_SHIELD_DEADLY)
-    {
       DrawGraphicAnimation(x, y, IMG_SHIELD_DEADLY);
 
-#if 0
-      if (!(FrameCounter % 4))
-       PlaySoundLevel(x, y, SND_SHIELD_DEADLY_ACTIVE);
-#endif
-    }
-
     if (game.magic_wall_active)
     {
       boolean sieb = FALSE;
@@ -6231,13 +6238,13 @@ int DigField(struct PlayerInfo *player,
       else
       {
        RemoveField(x, y);
-       Feld[x+dx][y+dy] = element;
+       Feld[x + dx][y + dy] = element;
       }
 
       if (element == EL_SPRING)
       {
-       Feld[x+dx][y+dy] = EL_SPRING_MOVING;
-       MovDir[x+dx][y+dy] = move_direction;
+       Feld[x + dx][y + dy] = EL_SPRING;
+       MovDir[x + dx][y + dy] = move_direction;
       }
 
       player->push_delay_value = (element == EL_SPRING ? 0 : 2 + RND(8));