rnd-20050807-1-src
[rocksndiamonds.git] / src / game.c
index dd8af0d3679aa16450f8a65fac907bd7aadab7ee..b0d7ec6bfd1a670820bce99d0111fd67b8c7db58 100644 (file)
 #define USE_HITTING_SOMETHING_BUGFIX   (TRUE   * USE_NEW_STUFF         * 1)
 #define USE_HIT_BY_SOMETHING_BUGFIX    (TRUE   * USE_NEW_STUFF         * 1)
 
+#define USE_DROP_BUGFIX                        (TRUE   * USE_NEW_STUFF         * 1)
+
+#define USE_CHANGE_TO_TRIGGERED                (TRUE   * USE_NEW_STUFF         * 1)
+
 
 /* for DigField() */
 #define DF_NO_PUSH             0
@@ -1775,6 +1779,11 @@ void InitGame()
     player->switch_x = -1;
     player->switch_y = -1;
 
+#if USE_DROP_BUGFIX
+    player->drop_x = -1;
+    player->drop_y = -1;
+#endif
+
     player->show_envelope = 0;
 
     player->move_delay       = game.initial_move_delay;
@@ -4395,9 +4404,9 @@ static void ActivateTimegateSwitch(int x, int y)
 
 void Impact(int x, int y)
 {
-  boolean lastline = (y == lev_fieldy-1);
+  boolean last_line = (y == lev_fieldy - 1);
   boolean object_hit = FALSE;
-  boolean impact = (lastline || object_hit);
+  boolean impact = (last_line || object_hit);
   int element = Feld[x][y];
   int smashed = EL_STEELWALL;
 
@@ -4405,7 +4414,7 @@ void Impact(int x, int y)
   printf("IMPACT!\n");
 #endif
 
-  if (!lastline)       /* check if element below was hit */
+  if (!last_line)      /* check if element below was hit */
   {
     if (Feld[x][y + 1] == EL_PLAYER_IS_LEAVING)
       return;
@@ -4426,10 +4435,10 @@ void Impact(int x, int y)
     if (object_hit)
       smashed = MovingOrBlocked2Element(x, y + 1);
 
-    impact = (lastline || object_hit);
+    impact = (last_line || object_hit);
   }
 
-  if (!lastline && smashed == EL_ACID) /* element falls into acid */
+  if (!last_line && smashed == EL_ACID)        /* element falls into acid */
   {
     SplashAcid(x, y + 1);
     return;
@@ -4628,7 +4637,7 @@ void Impact(int x, int y)
   }
 
   /* play sound of magic wall / mill */
-  if (!lastline &&
+  if (!last_line &&
       (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE ||
        Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE))
   {
@@ -4641,7 +4650,7 @@ void Impact(int x, int y)
   }
 
   /* play sound of object that hits the ground */
-  if (lastline || object_hit)
+  if (last_line || object_hit)
     PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT);
 }
 
@@ -6212,7 +6221,16 @@ void StartMoving(int x, int y)
 #if 1
       Store[newx][newy] = EL_EMPTY;
       if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)))
+      {
+#if USE_CHANGE_TO_TRIGGERED
+       int move_leave_element = element_info[element].move_leave_element;
+
+       Store[newx][newy] = (move_leave_element == EL_TRIGGER_ELEMENT ?
+                            new_element : move_leave_element);
+#else
        Store[newx][newy] = element_info[element].move_leave_element;
+#endif
+      }
 #else
       Store[newx][newy] = EL_EMPTY;
       if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)) ||
@@ -6443,6 +6461,10 @@ void StartMoving(int x, int y)
     ContinueMoving(x, y);
 }
 
+void dummy()
+{
+}
+
 void ContinueMoving(int x, int y)
 {
   int element = Feld[x][y];
@@ -6461,6 +6483,7 @@ void ContinueMoving(int x, int y)
 #else
   boolean pushed_by_player = Pushed[x][y];
 #endif
+  boolean last_line = (newy == lev_fieldy - 1);
 
   MovPos[x][y] += getElementMoveStepsize(x, y);
 
@@ -6622,6 +6645,12 @@ void ContinueMoving(int x, int y)
   {
     int move_leave_element = ei->move_leave_element;
 
+#if USE_CHANGE_TO_TRIGGERED
+    if (ei->move_leave_type == LEAVE_TYPE_LIMITED &&
+        ei->move_leave_element == EL_TRIGGER_ELEMENT)
+      move_leave_element = stored;
+#endif
+
     Feld[x][y] = move_leave_element;
 
 #if USE_PREVIOUS_MOVE_DIR
@@ -6750,20 +6779,19 @@ void ContinueMoving(int x, int y)
 #if USE_NEW_MOVE_STYLE
 #if 0
   if (CAN_FALL(element) && direction == MV_DOWN &&
-      (newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1)) &&
-      IS_PLAYER(x, newy + 1))
+      !last_line && IS_PLAYER(x, newy + 1))
     printf("::: we would now kill the player [%d]\n", FrameCounter);
 #endif
 
   /* give the player one last chance (one more frame) to move away */
   if (CAN_FALL(element) && direction == MV_DOWN &&
-      (newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1)) &&
-      ((newy < lev_fieldy - 1 && !IS_PLAYER(x, newy + 1)) ||
-       game.engine_version < VERSION_IDENT(3,1,1,0)))
+      (last_line || (!IS_FREE(x, newy + 1) &&
+                    (!IS_PLAYER(x, newy + 1) ||
+                     game.engine_version < VERSION_IDENT(3,1,1,0)))))
     Impact(x, newy);
 #else
   if (CAN_FALL(element) && direction == MV_DOWN &&
-      (newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1)))
+      (last_line || !IS_FREE(x, newy + 1)))
     Impact(x, newy);
 #endif
 
@@ -12361,6 +12389,15 @@ boolean DropElement(struct PlayerInfo *player)
                      EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr :
                      EL_UNDEFINED);
 
+#if USE_DROP_BUGFIX
+  /* do not drop an element on top of another element; when holding drop key
+     pressed without moving, dropped element must move away before the next
+     element can be dropped (this is especially important if the next element
+     is dynamite, which can be placed on background for historical reasons) */
+  if (PLAYER_DROPPING(player, dropx, dropy) && Feld[dropx][dropy] != EL_EMPTY)
+    return MF_ACTION;
+#endif
+
   if (IS_THROWABLE(drop_element))
   {
     dropx += GET_DX_FROM_DIR(drop_direction);
@@ -12557,6 +12594,10 @@ boolean DropElement(struct PlayerInfo *player)
 
   player->is_dropping = TRUE;
 
+#if USE_DROP_BUGFIX
+  player->drop_x = dropx;
+  player->drop_y = dropy;
+#endif
 
   return TRUE;
 }