rnd-20030417-3-src
[rocksndiamonds.git] / src / game.c
index d60f158a4404d9f6a443f6d91568cedc835c1e07..bf1000db0c1b794f93bc6a1d3ac744f519bbbddd 100644 (file)
@@ -533,21 +533,15 @@ static void InitGameEngine()
     };
     static int ep_em_slippery_wall_num = SIZEOF_ARRAY_INT(ep_em_slippery_wall);
 
+    /* special EM style gems behaviour */
     for (i=0; i<ep_em_slippery_wall_num; i++)
-    {
-      if (level.em_slippery_gems)      /* special EM style gems behaviour */
-       Properties2[ep_em_slippery_wall[i]] |=
-         EP_BIT_EM_SLIPPERY_WALL;
-      else
-       Properties2[ep_em_slippery_wall[i]] &=
-         ~EP_BIT_EM_SLIPPERY_WALL;
-    }
+      SET_PROPERTY(ep_em_slippery_wall[i], EP_EM_SLIPPERY_WALL,
+                  level.em_slippery_gems);
 
     /* "EL_EXPANDABLE_WALL_GROWING" wasn't slippery for EM gems in 2.0.1 */
-    if (level.em_slippery_gems && game.engine_version > VERSION_IDENT(2,0,1))
-      Properties2[EL_EXPANDABLE_WALL_GROWING] |= EP_BIT_EM_SLIPPERY_WALL;
-    else
-      Properties2[EL_EXPANDABLE_WALL_GROWING] &=~EP_BIT_EM_SLIPPERY_WALL;
+    SET_PROPERTY(EL_EXPANDABLE_WALL_GROWING, EP_EM_SLIPPERY_WALL,
+                (level.em_slippery_gems &&
+                 game.engine_version > VERSION_IDENT(2,0,1)));
   }
 
   /* initialize changing elements information */
@@ -1112,7 +1106,7 @@ void GameWon()
       if (!tape.playing && !setup.sound_loops)
        PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
       if (TimeLeft > 0 && !(TimeLeft % 10))
-       RaiseScore(level.score[SC_ZEITBONUS]);
+       RaiseScore(level.score[SC_TIME_BONUS]);
       if (TimeLeft > 100 && !(TimeLeft % 10))
        TimeLeft -= 10;
       else
@@ -1138,7 +1132,7 @@ void GameWon()
       if (!tape.playing && !setup.sound_loops)
        PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
       if (TimePlayed < 999 && !(TimePlayed % 10))
-       RaiseScore(level.score[SC_ZEITBONUS]);
+       RaiseScore(level.score[SC_TIME_BONUS]);
       if (TimePlayed < 900 && !(TimePlayed % 10))
        TimePlayed += 10;
       else
@@ -1384,7 +1378,7 @@ static int MovingOrBlocked2ElementIfNotLeaving(int x, int y)
 static void RemoveField(int x, int y)
 {
   Feld[x][y] = EL_EMPTY;
-  GfxElement[x][y] = EL_EMPTY;
+  GfxElement[x][y] = EL_UNDEFINED;
   MovPos[x][y] = 0;
   MovDir[x][y] = 0;
   MovDelay[x][y] = 0;
@@ -1531,7 +1525,8 @@ void Explode(int ex, int ey, int phase, int mode)
        RemoveMovingField(x, y);
       }
 
-      if (IS_INDESTRUCTIBLE(element) || element == EL_FLAMES)
+      if ((IS_INDESTRUCTIBLE(element) && !IS_ACCESSIBLE(element)) ||
+         element == EL_FLAMES)
        continue;
 
       if (IS_PLAYER(x, y) && SHIELD_ON(PLAYERINFO(x, y)))
@@ -1549,6 +1544,11 @@ void Explode(int ex, int ey, int phase, int mode)
       if (element == EL_EXPLOSION)
        element = Store2[x][y];
 
+#if 1
+      if (IS_INDESTRUCTIBLE(Store[x][y]))      /* hard element under bomb */
+       element = Store[x][y];
+#endif
+
       if (IS_PLAYER(ex, ey) && !PLAYER_PROTECTED(ex, ey))
       {
        switch(StorePlayer[ex][ey])
@@ -1601,8 +1601,15 @@ void Explode(int ex, int ey, int phase, int mode)
        Store[x][y] = EL_PEARL;
       else if (element == EL_WALL_CRYSTAL)
        Store[x][y] = EL_CRYSTAL;
+#if 1
+      else if (IS_INDESTRUCTIBLE(element))
+       Store[x][y] = element;
+      else
+       Store[x][y] = EL_EMPTY;
+#else
       else if (!IS_PFORTE(Store[x][y]))
        Store[x][y] = EL_EMPTY;
+#endif
 
       if (x != ex || y != ey ||
          center_element == EL_AMOEBA_TO_DIAMOND || mode == EX_BORDER)
@@ -1618,7 +1625,7 @@ void Explode(int ex, int ey, int phase, int mode)
       }
 
       Feld[x][y] = EL_EXPLOSION;
-      GfxElement[x][y] = EL_EMPTY;
+      GfxElement[x][y] = EL_UNDEFINED;
       MovDir[x][y] = MovPos[x][y] = 0;
       AmoebaNr[x][y] = 0;
       ExplodePhase[x][y] = 1;
@@ -1692,6 +1699,20 @@ void Explode(int ex, int ey, int phase, int mode)
     if (phase == delay)
       DrawLevelFieldCrumbledSand(x, y);
 
+#if 1
+    if (IS_ACCESSIBLE_OVER(Store[x][y]))
+    {
+      DrawLevelElement(x, y, Store[x][y]);
+      DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic, frame);
+    }
+    else if (IS_ACCESSIBLE_UNDER(Store[x][y]))
+    {
+      DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
+      DrawLevelElementThruMask(x, y, Store[x][y]);
+    }
+    else if (!IS_ACCESSIBLE_INSIDE(Store[x][y]))
+      DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
+#else
     if (IS_PFORTE(Store[x][y]))
     {
       DrawLevelElement(x, y, Store[x][y]);
@@ -1699,6 +1720,7 @@ void Explode(int ex, int ey, int phase, int mode)
     }
     else
       DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
+#endif
   }
 }
 
@@ -2435,11 +2457,11 @@ void TurnRound(int x, int y)
 
     if (IN_LEV_FIELD(left_x, left_y) &&
        (IS_FREE_OR_PLAYER(left_x, left_y) ||
-        IS_MAMPF2(Feld[left_x][left_y])))
+        IS_FOOD_DARK_YAMYAM(Feld[left_x][left_y])))
       can_turn_left = TRUE;
     if (IN_LEV_FIELD(right_x, right_y) &&
        (IS_FREE_OR_PLAYER(right_x, right_y) ||
-        IS_MAMPF2(Feld[right_x][right_y])))
+        IS_FOOD_DARK_YAMYAM(Feld[right_x][right_y])))
       can_turn_right = TRUE;
 
     if (can_turn_left && can_turn_right)
@@ -2726,7 +2748,7 @@ void TurnRound(int x, int y)
             Feld[newx][newy] == EL_ACID ||
             (element == EL_PENGUIN &&
              (Feld[newx][newy] == EL_EXIT_OPEN ||
-              IS_MAMPF3(Feld[newx][newy])))))
+              IS_FOOD_PENGUIN(Feld[newx][newy])))))
          return;
 
        MovDir[x][y] =
@@ -2738,7 +2760,7 @@ void TurnRound(int x, int y)
             Feld[newx][newy] == EL_ACID ||
             (element == EL_PENGUIN &&
              (Feld[newx][newy] == EL_EXIT_OPEN ||
-              IS_MAMPF3(Feld[newx][newy])))))
+              IS_FOOD_PENGUIN(Feld[newx][newy])))))
          return;
 
        MovDir[x][y] = old_move_dir;
@@ -3028,8 +3050,8 @@ void StartMoving(int x, int y)
 
     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  */
+      /* all objects that can change their move direction after each step
+        (YAMYAM, DARK_YAMYAM and PACMAN go straight until they hit a wall */
 
       if (element != EL_YAMYAM &&
          element != EL_DARK_YAMYAM &&
@@ -3156,7 +3178,7 @@ void StartMoving(int x, int y)
 
        return;
       }
-      else if (IS_MAMPF3(Feld[newx][newy]))
+      else if (IS_FOOD_PENGUIN(Feld[newx][newy]))
       {
        if (DigField(local_player, newx, newy, 0, 0, DF_DIG) == MF_MOVING)
          DrawLevelField(newx, newy);
@@ -3251,7 +3273,7 @@ void StartMoving(int x, int y)
       PlaySoundLevel(x, y, SND_YAMYAM_DIGGING);
     }
     else if (element == EL_DARK_YAMYAM && IN_LEV_FIELD(newx, newy) &&
-            IS_MAMPF2(Feld[newx][newy]))
+            IS_FOOD_DARK_YAMYAM(Feld[newx][newy]))
     {
       if (AmoebaNr[newx][newy])
       {
@@ -5036,11 +5058,18 @@ static void CheckGravityMovement(struct PlayerInfo *player)
 
     if (field_under_player_is_free &&
        !player_is_moving_to_valid_field &&
-       !IS_TUBE(Feld[jx][jy]))
+       !IS_WALKABLE_INSIDE(Feld[jx][jy]))
       player->programmed_action = MV_DOWN;
   }
 }
 
+/*
+  MoveFigureOneStep()
+  -----------------------------------------------------------------------------
+  dx, dy:              direction (non-diagonal) to try to move the player to
+  real_dx, real_dy:    direction as read from input device (can be diagonal)
+*/
+
 boolean MoveFigureOneStep(struct PlayerInfo *player,
                          int dx, int dy, int real_dx, int real_dy)
 {
@@ -5315,7 +5344,7 @@ void ScrollFigure(struct PlayerInfo *player, int mode)
 
   if (player->MovPos == 0)
   {
-    if (IS_QUICK_GATE(Feld[last_jx][last_jy]))
+    if (IS_PASSABLE(Feld[last_jx][last_jy]))
     {
       /* continue with normal speed after quickly moving through gate */
       HALVE_PLAYER_SPEED(player);
@@ -5603,8 +5632,11 @@ void KillHero(struct PlayerInfo *player)
   if (!player->active)
     return;
 
+#if 1
+#else
   if (IS_PFORTE(Feld[jx][jy]))
     Feld[jx][jy] = EL_EMPTY;
+#endif
 
   /* deactivate shield (else Bang()/Explode() would not work right) */
   player->shield_normal_time_left = 0;
@@ -5656,6 +5688,25 @@ void RemoveHero(struct PlayerInfo *player)
   ExitY = ZY = jy;
 }
 
+#if 0
+/*
+  checkDiagonalPushing()
+  -----------------------------------------------------------------------------
+  check if diagonal input device direction results in pushing of object
+*/
+
+static boolean checkDiagonalPushing(int x, int y, int real_dx, int real_dy)
+{
+}
+#endif
+
+/*
+  DigField()
+  -----------------------------------------------------------------------------
+  x, y:                        field next to player (non-diagonal) to try to dig to
+  real_dx, real_dy:    direction as read from input device (can be diagonal)
+*/
+
 int DigField(struct PlayerInfo *player,
             int x, int y, int real_dx, int real_dy, int mode)
 {
@@ -6104,16 +6155,16 @@ int DigField(struct PlayerInfo *player,
       break;
 
     case EL_SP_PORT_LEFT:
-    case EL_SP_GRAVITY_PORT_LEFT:
     case EL_SP_PORT_RIGHT:
-    case EL_SP_GRAVITY_PORT_RIGHT:
     case EL_SP_PORT_UP:
-    case EL_SP_GRAVITY_PORT_UP:
     case EL_SP_PORT_DOWN:
-    case EL_SP_GRAVITY_PORT_DOWN:
     case EL_SP_PORT_HORIZONTAL:
     case EL_SP_PORT_VERTICAL:
     case EL_SP_PORT_ANY:
+    case EL_SP_GRAVITY_PORT_LEFT:
+    case EL_SP_GRAVITY_PORT_RIGHT:
+    case EL_SP_GRAVITY_PORT_UP:
+    case EL_SP_GRAVITY_PORT_DOWN:
       if ((dx == -1 &&
           element != EL_SP_PORT_LEFT &&
           element != EL_SP_GRAVITY_PORT_LEFT &&
@@ -6617,22 +6668,22 @@ void RaiseScoreElement(int element)
     case EL_EMERALD_YELLOW:
     case EL_EMERALD_RED:
     case EL_EMERALD_PURPLE:
-      RaiseScore(level.score[SC_EDELSTEIN]);
+      RaiseScore(level.score[SC_EMERALD]);
       break;
     case EL_DIAMOND:
-      RaiseScore(level.score[SC_DIAMANT]);
+      RaiseScore(level.score[SC_DIAMOND]);
       break;
     case EL_BUG:
     case EL_BD_BUTTERFLY:
-      RaiseScore(level.score[SC_KAEFER]);
+      RaiseScore(level.score[SC_BUG]);
       break;
     case EL_SPACESHIP:
     case EL_BD_FIREFLY:
-      RaiseScore(level.score[SC_FLIEGER]);
+      RaiseScore(level.score[SC_SPACESHIP]);
       break;
     case EL_YAMYAM:
     case EL_DARK_YAMYAM:
-      RaiseScore(level.score[SC_MAMPFER]);
+      RaiseScore(level.score[SC_YAMYAM]);
       break;
     case EL_ROBOT:
       RaiseScore(level.score[SC_ROBOT]);
@@ -6641,16 +6692,16 @@ void RaiseScoreElement(int element)
       RaiseScore(level.score[SC_PACMAN]);
       break;
     case EL_NUT:
-      RaiseScore(level.score[SC_KOKOSNUSS]);
+      RaiseScore(level.score[SC_NUT]);
       break;
     case EL_DYNAMITE:
-      RaiseScore(level.score[SC_DYNAMIT]);
+      RaiseScore(level.score[SC_DYNAMITE]);
       break;
     case EL_KEY_1:
     case EL_KEY_2:
     case EL_KEY_3:
     case EL_KEY_4:
-      RaiseScore(level.score[SC_SCHLUESSEL]);
+      RaiseScore(level.score[SC_KEY]);
       break;
     default:
       break;