rnd-20071030-1-src
authorHolger Schemel <info@artsoft.org>
Tue, 30 Oct 2007 00:47:34 +0000 (01:47 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:56:40 +0000 (10:56 +0200)
* added engine functionality that allows custom elements that "can dig"
  other elements not only to do so when moving by themselves, but also
  when being pushed by the player (therefore adding the functionality to
  push one element over another element, replacing it with the new one)

ChangeLog
src/conftime.h
src/game.c

index b3529b1eb392ef596b0e2ce00c2b56c9eaac9c8e..0bbd3b47e6df3e308bf0190e7f67a92184a65f23 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
        * fixed bug with reference elements used as trigger elements on custom
          element change pages not being recognized
        * fixed bug with reference elements not being removed from the playfield
+       * added engine functionality that allows custom elements that "can dig"
+         other elements not only to do so when moving by themselves, but also
+         when being pushed by the player (therefore adding the functionality to
+         push one element over another element, replacing it with the new one)
 
 2007-10-23
        * added command line function to write level sketch images to directory
index 3e308745641f9501608a0b153b17653cb8cc9c8e..9d961e76ba4fb729977d519af3f76837b62b87e6 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "2007-10-29 23:06"
+#define COMPILE_DATE_STRING "2007-10-30 01:13"
index c11fbcdd3a5b606be9a8471abc1d95ae54179c1c..76a9952991770243f7d206eb143d2a11d11adea9 100644 (file)
@@ -1033,7 +1033,10 @@ static boolean MovePlayer(struct PlayerInfo *, int, int);
 static void ScrollPlayer(struct PlayerInfo *, int);
 static void ScrollScreen(struct PlayerInfo *, int);
 
-int DigField(struct PlayerInfo *, int, int, int, int, int, int, int);
+static int DigField(struct PlayerInfo *, int, int, int, int, int, int, int);
+static boolean DigFieldByCE(int, int, int);
+static boolean SnapField(struct PlayerInfo *, int, int);
+static boolean DropElement(struct PlayerInfo *);
 
 static void InitBeltMovement(void);
 static void CloseAllOpenTimegates(void);
@@ -1105,9 +1108,6 @@ void KillPlayer(struct PlayerInfo *);
 void BuryPlayer(struct PlayerInfo *);
 void RemovePlayer(struct PlayerInfo *);
 
-boolean SnapField(struct PlayerInfo *, int, int);
-boolean DropElement(struct PlayerInfo *);
-
 static int getInvisibleActiveFromInvisibleElement(int);
 static int getInvisibleFromInvisibleActiveElement(int);
 
@@ -8377,6 +8377,10 @@ void StartMoving(int x, int y)
     else if (IS_CUSTOM_ELEMENT(element) &&
             CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, newx, newy))
     {
+#if 1
+      if (!DigFieldByCE(newx, newy, element))
+       return;
+#else
       int new_element = Feld[newx][newy];
 
       if (!IS_FREE(newx, newy))
@@ -8415,6 +8419,7 @@ void StartMoving(int x, int y)
       }
 
       Store[newx][newy] = EL_EMPTY;
+
 #if 1
       /* this makes it possible to leave the removed element again */
       if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)))
@@ -8428,6 +8433,8 @@ void StartMoving(int x, int y)
        Store[newx][newy] = (move_leave_element == EL_TRIGGER_ELEMENT ?
                             new_element : move_leave_element);
       }
+#endif
+
 #endif
 
       if (move_pattern & MV_MAZE_RUNNER_STYLE)
@@ -14040,9 +14047,9 @@ static boolean checkDiagonalPushing(struct PlayerInfo *player,
   =============================================================================
 */
 
-int DigField(struct PlayerInfo *player,
-            int oldx, int oldy, int x, int y,
-            int real_dx, int real_dy, int mode)
+static int DigField(struct PlayerInfo *player,
+                   int oldx, int oldy, int x, int y,
+                   int real_dx, int real_dy, int mode)
 {
   boolean is_player = (IS_PLAYER(oldx, oldy) || mode != DF_DIG);
   boolean player_was_pushing = player->is_pushing;
@@ -14521,10 +14528,19 @@ int DigField(struct PlayerInfo *player,
 
     if (!(IN_LEV_FIELD(nextx, nexty) &&
          (IS_FREE(nextx, nexty) ||
-          (Feld[nextx][nexty] == EL_SOKOBAN_FIELD_EMPTY &&
-           IS_SB_ELEMENT(element)))))
+          (IS_SB_ELEMENT(element) &&
+           Feld[nextx][nexty] == EL_SOKOBAN_FIELD_EMPTY) ||
+          (IS_CUSTOM_ELEMENT(element) &&
+           CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, nextx, nexty)))))
       return MP_NO_ACTION;
 
+    if (IS_CUSTOM_ELEMENT(element) &&
+       CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, nextx, nexty))
+    {
+      if (!DigFieldByCE(nextx, nexty, element))
+       return MP_NO_ACTION;
+    }
+
     if (!checkDiagonalPushing(player, x, y, real_dx, real_dy))
       return MP_NO_ACTION;
 
@@ -14784,7 +14800,66 @@ int DigField(struct PlayerInfo *player,
   return MP_MOVING;
 }
 
-boolean SnapField(struct PlayerInfo *player, int dx, int dy)
+static boolean DigFieldByCE(int x, int y, int digging_element)
+{
+  int element = Feld[x][y];
+
+  if (!IS_FREE(x, y))
+  {
+    int action = (IS_DIGGABLE(element) ? ACTION_DIGGING :
+                 IS_COLLECTIBLE(element) ? ACTION_COLLECTING :
+                 ACTION_BREAKING);
+
+    /* no element can dig solid indestructible elements */
+    if (IS_INDESTRUCTIBLE(element) &&
+       !IS_DIGGABLE(element) &&
+       !IS_COLLECTIBLE(element))
+      return FALSE;
+
+    if (AmoebaNr[x][y] &&
+       (element == EL_AMOEBA_FULL ||
+        element == EL_BD_AMOEBA ||
+        element == EL_AMOEBA_GROWING))
+    {
+      AmoebaCnt[AmoebaNr[x][y]]--;
+      AmoebaCnt2[AmoebaNr[x][y]]--;
+    }
+
+    if (IS_MOVING(x, y))
+      RemoveMovingField(x, y);
+    else
+    {
+      RemoveField(x, y);
+      DrawLevelField(x, y);
+    }
+
+    /* if digged element was about to explode, prevent the explosion */
+    ExplodeField[x][y] = EX_TYPE_NONE;
+
+    PlayLevelSoundAction(x, y, action);
+  }
+
+  Store[x][y] = EL_EMPTY;
+
+#if 1
+  /* this makes it possible to leave the removed element again */
+  if (IS_EQUAL_OR_IN_GROUP(element, MOVE_ENTER_EL(digging_element)))
+    Store[x][y] = element;
+#else
+  if (IS_EQUAL_OR_IN_GROUP(element, MOVE_ENTER_EL(digging_element)))
+  {
+    int move_leave_element = element_info[digging_element].move_leave_element;
+
+    /* this makes it possible to leave the removed element again */
+    Store[x][y] = (move_leave_element == EL_TRIGGER_ELEMENT ?
+                  element : move_leave_element);
+  }
+#endif
+
+  return TRUE;
+}
+
+static boolean SnapField(struct PlayerInfo *player, int dx, int dy)
 {
   int jx = player->jx, jy = player->jy;
   int x = jx + dx, y = jy + dy;
@@ -14864,7 +14939,7 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy)
   return TRUE;
 }
 
-boolean DropElement(struct PlayerInfo *player)
+static boolean DropElement(struct PlayerInfo *player)
 {
   int old_element, new_element;
   int dropx = player->jx, dropy = player->jy;