rnd-20040218-1-src
[rocksndiamonds.git] / src / game.c
index 61ea108f18c58ea077b96aa895d373cfec915323..77df179d6664144f52f88ecdaf4de9710dab5d46 100644 (file)
                                        (condition) ||                  \
                                        (DONT_COLLIDE_WITH(e) &&        \
                                         IS_PLAYER(x, y) &&             \
-                                        !PLAYER_PROTECTED(x, y))))
+                                        !PLAYER_ENEMY_PROTECTED(x, y))))
 #else
 #define ELEMENT_CAN_ENTER_FIELD_GENERIC(e, x, y, condition)            \
                (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) ||                \
@@ -216,7 +216,8 @@ static void ScrollScreen(struct PlayerInfo *, int);
 static void InitBeltMovement(void);
 static void CloseAllOpenTimegates(void);
 static void CheckGravityMovement(struct PlayerInfo *);
-static void KillHeroUnlessProtected(int, int);
+static void KillHeroUnlessEnemyProtected(int, int);
+static void KillHeroUnlessExplosionProtected(int, int);
 
 static void TestIfPlayerTouchesCustomElement(int, int);
 static void TestIfElementTouchesCustomElement(int, int);
@@ -496,6 +497,28 @@ collect_count_list[] =
   { EL_UNDEFINED,              0 },
 };
 
+struct
+{
+  int element;
+  int direction;
+}
+tube_access[] =
+{
+  { EL_TUBE_ANY,               MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+  { EL_TUBE_VERTICAL,                               MV_UP | MV_DOWN },
+  { EL_TUBE_HORIZONTAL,                MV_LEFT | MV_RIGHT                   },
+  { EL_TUBE_VERTICAL_LEFT,     MV_LEFT |            MV_UP | MV_DOWN },
+  { EL_TUBE_VERTICAL_RIGHT,              MV_RIGHT | MV_UP | MV_DOWN },
+  { EL_TUBE_HORIZONTAL_UP,     MV_LEFT | MV_RIGHT | MV_UP           },
+  { EL_TUBE_HORIZONTAL_DOWN,   MV_LEFT | MV_RIGHT |         MV_DOWN },
+  { EL_TUBE_LEFT_UP,           MV_LEFT |            MV_UP           },
+  { EL_TUBE_LEFT_DOWN,         MV_LEFT |                    MV_DOWN },
+  { EL_TUBE_RIGHT_UP,                    MV_RIGHT | MV_UP           },
+  { EL_TUBE_RIGHT_DOWN,                          MV_RIGHT |         MV_DOWN },
+
+  { EL_UNDEFINED,              0                                    }
+};
+
 static unsigned long trigger_events[MAX_NUM_ELEMENTS];
 
 #define IS_AUTO_CHANGING(e)    (element_info[e].change_events & \
@@ -1156,6 +1179,18 @@ static void InitGameEngine()
   for (i = 0; collect_count_list[i].element != EL_UNDEFINED; i++)
     element_info[collect_count_list[i].element].collect_count =
       collect_count_list[i].count;
+
+  /* ---------- initialize access direction -------------------------------- */
+
+  /* initialize access direction values to default */
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+    if (!IS_CUSTOM_ELEMENT(i))
+      element_info[i].access_direction = MV_ALL_DIRECTIONS;
+
+  /* set access direction value for certain elements from pre-defined list */
+  for (i = 0; tube_access[i].element != EL_UNDEFINED; i++)
+    element_info[tube_access[i].element].access_direction =
+      tube_access[i].direction;
 }
 
 
@@ -1384,6 +1419,7 @@ void InitGame()
       ChangeEvent[x][y] = CE_BITMASK_DEFAULT;
 
       ExplodePhase[x][y] = 0;
+      ExplodeDelay[x][y] = 0;
       ExplodeField[x][y] = EX_NO_EXPLOSION;
 
       RunnerVisit[x][y] = 0;
@@ -1418,6 +1454,30 @@ void InitGame()
                    emulate_sb ? EMU_SOKOBAN :
                    emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
 
+  /* initialize explosion and ignition delay */
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+  {
+    if (!IS_CUSTOM_ELEMENT(i))
+    {
+      int num_phase = 9;
+      int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
+      int last_phase = num_phase * delay;
+      int half_phase = (num_phase / 2) * delay;
+
+      element_info[i].explosion_delay = last_phase;
+      element_info[i].ignition_delay = half_phase;
+
+      if (i == EL_BLACK_ORB)
+       element_info[i].ignition_delay = 1;
+    }
+
+    if (element_info[i].explosion_delay < 2)   /* !!! check again !!! */
+      element_info[i].explosion_delay = 2;
+
+    if (element_info[i].ignition_delay < 1)    /* !!! check again !!! */
+      element_info[i].ignition_delay = 1;
+  }
+
   /* correct non-moving belts to start moving left */
   for (i = 0; i < 4; i++)
     if (game.belt_dir[i] == MV_NO_MOVING)
@@ -1793,15 +1853,15 @@ void InitMovDir(int x, int y)
        int move_direction_initial = ei->move_direction_initial;
        int move_pattern = ei->move_pattern;
 
-       if (move_direction_initial == MV_PREVIOUS)
+       if (move_direction_initial == MV_START_PREVIOUS)
        {
          if (MovDir[x][y] != MV_NO_MOVING)
            return;
 
-         move_direction_initial = MV_AUTOMATIC;
+         move_direction_initial = MV_START_AUTOMATIC;
        }
 
-       if (move_direction_initial == MV_RANDOM)
+       if (move_direction_initial == MV_START_RANDOM)
          MovDir[x][y] = 1 << RND(4);
        else if (move_direction_initial & MV_ANY_DIRECTION)
          MovDir[x][y] = move_direction_initial;
@@ -2335,8 +2395,9 @@ void CheckDynamite(int x, int y)
   Bang(x, y);
 }
 
-void RelocatePlayer(int x, int y, int element)
+void RelocatePlayer(int x, int y, int element_raw)
 {
+  int element = (element_raw == EL_SP_MURPHY ? EL_PLAYER_1 : element_raw);
   struct PlayerInfo *player = &stored_player[element - EL_PLAYER_1];
   boolean ffwd_delay = (tape.playing && tape.fast_forward);
   boolean no_delay = (tape.index_search);
@@ -2418,11 +2479,21 @@ void RelocatePlayer(int x, int y, int element)
 void Explode(int ex, int ey, int phase, int mode)
 {
   int x, y;
+#if 0
   int num_phase = 9;
+#endif
+
+  /* !!! eliminate this variable !!! */
   int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
+
+#if 1
+  int last_phase;
+#else
   int last_phase = num_phase * delay;
   int half_phase = (num_phase / 2) * delay;
   int first_phase_after_start = EX_PHASE_START + 1;
+#endif
+  int border_element;
 
   if (game.explosions_delayed)
   {
@@ -2457,6 +2528,10 @@ void Explode(int ex, int ey, int phase, int mode)
       Feld[ex][ey] = center_element;
     }
 
+#if 1
+    last_phase = element_info[center_element].explosion_delay;
+#endif
+
     for (y = ey - 1; y <= ey + 1; y++) for (x = ex - 1; x <= ex + 1; x++)
     {
       int xx = x - ex + 1;
@@ -2536,7 +2611,7 @@ void Explode(int ex, int ey, int phase, int mode)
       RemoveField(x, y);
 #endif
 
-      if (IS_PLAYER(ex, ey) && !PLAYER_PROTECTED(ex, ey))
+      if (IS_PLAYER(ex, ey) && !PLAYER_EXPLOSION_PROTECTED(ex, ey))
       {
        switch(StorePlayer[ex][ey])
        {
@@ -2627,6 +2702,9 @@ void Explode(int ex, int ey, int phase, int mode)
 #endif
 
       ExplodePhase[x][y] = 1;
+#if 1
+      ExplodeDelay[x][y] = last_phase;
+#endif
       Stop[x][y] = TRUE;
     }
 
@@ -2643,6 +2721,10 @@ void Explode(int ex, int ey, int phase, int mode)
   x = ex;
   y = ey;
 
+#if 1
+  last_phase = ExplodeDelay[x][y];
+#endif
+
   ExplodePhase[x][y] = (phase < last_phase ? phase + 1 : 0);
 
 #ifdef DEBUG
@@ -2663,6 +2745,69 @@ void Explode(int ex, int ey, int phase, int mode)
   }
 #endif
 
+#if 1
+
+  border_element = Store2[x][y];
+  if (IS_PLAYER(x, y))
+    border_element = StorePlayer[x][y];
+
+  if (phase == element_info[border_element].ignition_delay ||
+      phase == last_phase)
+  {
+    boolean border_explosion = FALSE;
+
+#if 1
+    if (IS_PLAYER(x, y) && PLAYERINFO(x, y)->present)
+#else
+    if (IS_PLAYER(x, y))
+#endif
+    {
+      KillHeroUnlessExplosionProtected(x, y);
+      border_explosion = TRUE;
+
+#if 0
+      if (phase == last_phase)
+       printf("::: IS_PLAYER\n");
+#endif
+    }
+    else if (CAN_EXPLODE_BY_EXPLOSION(border_element))
+    {
+      Feld[x][y] = Store2[x][y];
+      Store2[x][y] = 0;
+      Bang(x, y);
+      border_explosion = TRUE;
+
+#if 0
+      if (phase == last_phase)
+       printf("::: CAN_EXPLODE_BY_EXPLOSION\n");
+#endif
+    }
+    else if (border_element == EL_AMOEBA_TO_DIAMOND)
+    {
+      AmoebeUmwandeln(x, y);
+      Store2[x][y] = 0;
+      border_explosion = TRUE;
+
+#if 0
+      if (phase == last_phase)
+       printf("::: EL_AMOEBA_TO_DIAMOND [%d, %d] [%d]\n",
+              element_info[border_element].explosion_delay,
+              element_info[border_element].ignition_delay,
+              phase);
+#endif
+    }
+
+#if 1
+    /* if an element just explodes due to another explosion (chain-reaction),
+       do not immediately end the new explosion when it was the last frame of
+       the explosion (as it would be done in the following "if"-statement!) */
+    if (border_explosion && phase == last_phase)
+      return;
+#endif
+  }
+
+#else
+
   if (phase == first_phase_after_start)
   {
     int element = Store2[x][y];
@@ -2679,8 +2824,8 @@ void Explode(int ex, int ey, int phase, int mode)
     int element = Store2[x][y];
 
     if (IS_PLAYER(x, y))
-      KillHeroUnlessProtected(x, y);
-    else if (CAN_EXPLODE_BY_FIRE(element))
+      KillHeroUnlessExplosionProtected(x, y);
+    else if (CAN_EXPLODE_BY_EXPLOSION(element))
     {
       Feld[x][y] = Store2[x][y];
       Store2[x][y] = 0;
@@ -2689,6 +2834,7 @@ void Explode(int ex, int ey, int phase, int mode)
     else if (element == EL_AMOEBA_TO_DIAMOND)
       AmoebeUmwandeln(x, y);
   }
+#endif
 
   if (phase == last_phase)
   {
@@ -2731,13 +2877,17 @@ void Explode(int ex, int ey, int phase, int mode)
     if (GFX_CRUMBLED(element))
       DrawLevelFieldCrumbledSandNeighbours(x, y);
 
-    if (IS_PLAYER(x, y) && !PLAYERINFO(x,y)->present)
+    if (IS_PLAYER(x, y) && !PLAYERINFO(x, y)->present)
       StorePlayer[x][y] = 0;
 
     if (ELEM_IS_PLAYER(element))
       RelocatePlayer(x, y, element);
   }
+#if 1
+  else if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+#else
   else if (phase >= delay && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+#endif
   {
 #if 1
     int graphic = el_act2img(GfxElement[x][y], ACTION_EXPLODING);
@@ -2836,7 +2986,7 @@ void Bang(int x, int y)
 #endif
 
 #if 1
-  if (IS_PLAYER(x, y) && !PLAYER_PROTECTED(x, y))
+  if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y))
 #else
   if (IS_PLAYER(x, y))
 #endif
@@ -3250,11 +3400,19 @@ inline static int getElementMoveStepsize(int x, int y)
   /* special values for move stepsize for spring and things on conveyor belt */
   if (horiz_move)
   {
+#if 1
+    if (element == EL_SPRING)
+      step = sign * MOVE_STEPSIZE_NORMAL * 2;
+    else if (CAN_FALL(element) && !CAN_MOVE(element) &&
+            y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
+      step = sign * MOVE_STEPSIZE_NORMAL / 2;
+#else
     if (CAN_FALL(element) &&
        y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
       step = sign * MOVE_STEPSIZE_NORMAL / 2;
     else if (element == EL_SPRING)
       step = sign * MOVE_STEPSIZE_NORMAL * 2;
+#endif
   }
 
   return step;
@@ -3327,7 +3485,7 @@ void Impact(int x, int y)
   if (impact && element == EL_AMOEBA_DROP)
   {
     if (object_hit && IS_PLAYER(x, y + 1))
-      KillHeroUnlessProtected(x, y + 1);
+      KillHeroUnlessEnemyProtected(x, y + 1);
     else if (object_hit && smashed == EL_PENGUIN)
       Bang(x, y + 1);
     else
@@ -3369,7 +3527,7 @@ void Impact(int x, int y)
     {
       if (CAN_SMASH_PLAYER(element))
       {
-       KillHeroUnlessProtected(x, y + 1);
+       KillHeroUnlessEnemyProtected(x, y + 1);
        return;
       }
     }
@@ -4205,8 +4363,8 @@ void StartMoving(int x, int y)
 
   if (CAN_FALL(element) && y < lev_fieldy - 1)
   {
-    if ((x > 0 && IS_PLAYER(x - 1, y)) ||
-       (x < lev_fieldx-1 && IS_PLAYER(x + 1, y)))
+    if ((x > 0              && IS_PLAYER(x - 1, y)) ||
+       (x < lev_fieldx - 1 && IS_PLAYER(x + 1, y)))
       if (JustBeingPushed(x, y))
        return;
 
@@ -4460,7 +4618,11 @@ void StartMoving(int x, int y)
        started_moving = TRUE;
       }
     }
+#if 1
+    else if (IS_BELT_ACTIVE(Feld[x][y + 1]) && !CAN_MOVE(element))
+#else
     else if (IS_BELT_ACTIVE(Feld[x][y + 1]))
+#endif
     {
       boolean left_is_free  = (x > 0 && IS_FREE(x - 1, y));
       boolean right_is_free = (x < lev_fieldx - 1 && IS_FREE(x + 1, y));
@@ -4668,7 +4830,7 @@ void StartMoving(int x, int y)
          {
            int flamed = MovingOrBlocked2Element(xx, yy);
 
-           if (IS_CLASSIC_ENEMY(flamed) || CAN_EXPLODE_BY_FIRE(flamed))
+           if (IS_CLASSIC_ENEMY(flamed) || CAN_EXPLODE_BY_DRAGONFIRE(flamed))
              Bang(xx, yy);
            else
              RemoveMovingField(xx, yy);
@@ -4710,7 +4872,7 @@ void StartMoving(int x, int y)
 
     if (DONT_COLLIDE_WITH(element) &&
        IN_LEV_FIELD(newx, newy) && IS_PLAYER(newx, newy) &&
-       !PLAYER_PROTECTED(newx, newy))
+       !PLAYER_ENEMY_PROTECTED(newx, newy))
     {
 #if 1
       TestIfBadThingRunsIntoHero(x, y, MovDir[x][y]);
@@ -5261,15 +5423,7 @@ void ContinueMoving(int x, int y)
 #if 0
     if (IN_LEV_FIELD(nextx, nexty))
     {
-      static int opposite_directions[] =
-      {
-       MV_RIGHT,
-       MV_LEFT,
-       MV_DOWN,
-       MV_UP
-      };
-      int move_dir_bit = MV_DIR_BIT(direction);
-      int opposite_direction = opposite_directions[move_dir_bit];
+      int opposite_direction = MV_DIR_OPPOSITE(direction);
       int hitting_side = direction;
       int touched_side = opposite_direction;
       int touched_element = MovingOrBlocked2Element(nextx, nexty);
@@ -6232,7 +6386,7 @@ static void ChangeElementNowExt(int x, int y, int target_element)
 
   /* check if element under player changes from accessible to unaccessible
      (needed for special case of dropping element which then changes) */
-  if (IS_PLAYER(x, y) && !PLAYER_PROTECTED(x, y) &&
+  if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) &&
       IS_ACCESSIBLE(Feld[x][y]) && !IS_ACCESSIBLE(target_element))
   {
     Bang(x, y);
@@ -6247,7 +6401,7 @@ static void ChangeElementNowExt(int x, int y, int target_element)
   ResetGfxAnimation(x, y);
   ResetRandomAnimationValue(x, y);
 
-  if (element_info[Feld[x][y]].move_direction_initial == MV_PREVIOUS)
+  if (element_info[Feld[x][y]].move_direction_initial == MV_START_PREVIOUS)
     MovDir[x][y] = previous_move_direction;
 
   InitField(x, y, FALSE);
@@ -6550,11 +6704,41 @@ static boolean CheckElementSideChange(int x, int y, int element, int side,
     element = Feld[x][y];
   }
 
+#if 1
+  if (page < 0)
+  {
+    boolean change_element = FALSE;
+    int i;
+
+    for (i = 0; i < element_info[element].num_change_pages; i++)
+    {
+      struct ElementChangeInfo *change = &element_info[element].change_page[i];
+
+      if (change->can_change &&
+         change->events & CH_EVENT_BIT(trigger_event) &&
+         change->sides & side)
+      {
+       change_element = TRUE;
+       page = i;
+
+       break;
+      }
+    }
+
+    if (!change_element)
+      return FALSE;
+  }
+
+#else
+
+  /* !!! this check misses pages with same event, but different side !!! */
+
   if (page < 0)
     page = element_info[element].event_page_nr[trigger_event];
 
   if (!(element_info[element].change_page[page].sides & side))
     return FALSE;
+#endif
 
   ChangeDelay[x][y] = 1;
   ChangeEvent[x][y] = CH_EVENT_BIT(trigger_event);
@@ -7629,9 +7813,14 @@ static void CheckGravityMovement(struct PlayerInfo *player)
         canEnterSupaplexPort(new_jx, new_jy, dx, dy))));
     /* !!! extend EL_SAND to anything diggable !!! */
 
+    boolean player_is_standing_on_valid_field =
+      (IS_WALKABLE_INSIDE(Feld[jx][jy]) ||
+       (IS_WALKABLE(Feld[jx][jy]) &&
+       !(element_info[Feld[jx][jy]].access_direction & MV_DOWN)));
+
     if (field_under_player_is_free &&
-       !player_is_moving_to_valid_field &&
-       !IS_WALKABLE_INSIDE(Feld[jx][jy]))
+       !player_is_standing_on_valid_field &&
+       !player_is_moving_to_valid_field)
       player->programmed_action = MV_DOWN;
   }
 }
@@ -8337,15 +8526,7 @@ void TestIfElementHitsCustomElement(int x, int y, int direction)
 
   if (IN_LEV_FIELD(hitx, hity))
   {
-    static int opposite_directions[] =
-    {
-      MV_RIGHT,
-      MV_LEFT,
-      MV_DOWN,
-      MV_UP
-    };
-    int move_dir_bit = MV_DIR_BIT(direction);
-    int opposite_direction = opposite_directions[move_dir_bit];
+    int opposite_direction = MV_DIR_OPPOSITE(direction);
     int hitting_side = direction;
     int touched_side = opposite_direction;
     int touched_element = MovingOrBlocked2Element(hitx, hity);
@@ -8474,7 +8655,7 @@ void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir)
 
       if (player->shield_deadly_time_left > 0)
        Bang(kill_x, kill_y);
-      else if (!PLAYER_PROTECTED(good_x, good_y))
+      else if (!PLAYER_ENEMY_PROTECTED(good_x, good_y))
        KillHero(player);
     }
     else
@@ -8566,7 +8747,7 @@ void TestIfBadThingHitsGoodThing(int bad_x, int bad_y, int bad_move_dir)
 
       if (player->shield_deadly_time_left > 0)
        Bang(bad_x, bad_y);
-      else if (!PLAYER_PROTECTED(kill_x, kill_y))
+      else if (!PLAYER_ENEMY_PROTECTED(kill_x, kill_y))
        KillHero(player);
     }
     else
@@ -8656,9 +8837,15 @@ void KillHero(struct PlayerInfo *player)
   BuryHero(player);
 }
 
-static void KillHeroUnlessProtected(int x, int y)
+static void KillHeroUnlessEnemyProtected(int x, int y)
 {
-  if (!PLAYER_PROTECTED(x, y))
+  if (!PLAYER_ENEMY_PROTECTED(x, y))
+    KillHero(PLAYERINFO(x, y));
+}
+
+static void KillHeroUnlessExplosionProtected(int x, int y)
+{
+  if (!PLAYER_EXPLOSION_PROTECTED(x, y))
     KillHero(PLAYERINFO(x, y));
 }
 
@@ -8757,7 +8944,9 @@ int DigField(struct PlayerInfo *player,
                        dx == +1 ? MV_RIGHT :
                        dy == -1 ? MV_UP :
                        dy == +1 ? MV_DOWN : MV_NO_MOVING);
+  int opposite_direction = MV_DIR_OPPOSITE(move_direction);
   int dig_side = change_sides[MV_DIR_BIT(move_direction)];
+  int old_element = Feld[jx][jy];
   int element;
 
   if (player->MovPos == 0)
@@ -8780,6 +8969,8 @@ int DigField(struct PlayerInfo *player,
   if (IS_MOVING(x, y) || IS_PLAYER(x, y))
     return MF_NO_ACTION;
 
+#if 0
+
 #if 0
   if (IS_TUBE(Feld[jx][jy]) || IS_TUBE(Back[jx][jy]))
 #else
@@ -8816,6 +9007,17 @@ int DigField(struct PlayerInfo *player,
       return MF_NO_ACTION;     /* tube has no opening in this direction */
   }
 
+#else
+
+  if (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0,0))
+    old_element = Back[jx][jy];
+
+#endif
+
+  if (IS_WALKABLE(old_element) &&
+      !(element_info[old_element].access_direction & move_direction))
+    return MF_NO_ACTION;       /* field has no opening in this direction */
+
   element = Feld[x][y];
 
   if (mode == DF_SNAP && !IS_SNAPPABLE(element) &&
@@ -8888,6 +9090,7 @@ int DigField(struct PlayerInfo *player,
       PlayLevelSound(x, y, SND_CLASS_SP_PORT_PASSING);
       break;
 
+#if 0
     case EL_TUBE_ANY:
     case EL_TUBE_VERTICAL:
     case EL_TUBE_HORIZONTAL:
@@ -8930,6 +9133,7 @@ int DigField(struct PlayerInfo *player,
        PlayLevelSound(x, y, SND_CLASS_TUBE_WALKING);
       }
       break;
+#endif
 
     default:
 
@@ -8937,6 +9141,9 @@ int DigField(struct PlayerInfo *player,
       {
        int sound_action = ACTION_WALKING;
 
+       if (!(element_info[element].access_direction & opposite_direction))
+         return MF_NO_ACTION;  /* field not accessible from this direction */
+
        if (element >= EL_GATE_1 && element <= EL_GATE_4)
        {
          if (!player->key[element - EL_GATE_1])
@@ -8971,6 +9178,10 @@ int DigField(struct PlayerInfo *player,
        if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty))
          return MF_NO_ACTION;
 
+       if (IS_CUSTOM_ELEMENT(element) &&
+           !(element_info[element].access_direction & opposite_direction))
+         return MF_NO_ACTION;  /* field not accessible from this direction */
+
 #if 1
        if (CAN_MOVE(element))  /* only fixed elements can be passed! */
          return MF_NO_ACTION;
@@ -9569,7 +9780,7 @@ boolean DropElement(struct PlayerInfo *player)
     int move_stepsize = element_info[new_element].move_stepsize;
     int direction, dx, dy, nextx, nexty;
 
-    if (element_info[new_element].move_direction_initial == MV_AUTOMATIC)
+    if (element_info[new_element].move_direction_initial == MV_START_AUTOMATIC)
       MovDir[jx][jy] = player->MovDir;
 
     direction = MovDir[jx][jy];