rnd-20030527-1-src
authorHolger Schemel <info@artsoft.org>
Tue, 27 May 2003 00:12:37 +0000 (02:12 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:41:56 +0000 (10:41 +0200)
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/init.c
src/libgame/system.h
src/main.h

index 17418548572c14d6c065146487aedad434b13efd..6e9cc4ef74fe0e8b5544c651d2e5b3be960e4cac 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2003-05-25 23:48]"
+#define COMPILE_DATE_STRING "[2003-05-27 01:56]"
index 13a8e8c493f9a652103b9c4f9091e6fe384cc56c..c7b097240c8052389e92afd7dd0637c985ed26f4 100644 (file)
 #define GADGET_ID_SELECTBOX_FIRST      (GADGET_ID_TEXT_INPUT_FIRST + 2)
 
 #define GADGET_ID_CUSTOM_WALK_TO_ACTION        (GADGET_ID_SELECTBOX_FIRST + 0)
-#define GADGET_ID_CUSTOM_MOVE_DIRECTION        (GADGET_ID_SELECTBOX_FIRST + 1)
+#define GADGET_ID_CUSTOM_MOVE_PATTERN  (GADGET_ID_SELECTBOX_FIRST + 1)
 #define GADGET_ID_CUSTOM_WALKABLE_LAYER        (GADGET_ID_SELECTBOX_FIRST + 2)
 #define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 3)
 #define GADGET_ID_CHANGE_CAUSE         (GADGET_ID_SELECTBOX_FIRST + 4)
 
 /* values for selectbox gadgets */
 #define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION  0
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION  1
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN    1
 #define ED_SELECTBOX_ID_CUSTOM_WALKABLE_LAYER  2
 #define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      3
 #define ED_SELECTBOX_ID_CHANGE_CAUSE           4
@@ -802,22 +802,22 @@ static struct ValueTextInfo options_walk_to_action[] =
 };
 static int index_walk_to_action = 0;
 
-static struct ValueTextInfo options_move_direction[] =
-{
-  { MV_BIT_LEFT,               "left"                  },
-  { MV_BIT_RIGHT,              "right"                 },
-  { MV_BIT_UP,                 "up"                    },
-  { MV_BIT_DOWN,               "down"                  },
-  { MV_BIT_HORIZONTAL,         "horizontal"            },
-  { MV_BIT_VERTICAL,           "vertical"              },
-  { MV_BIT_ALL_DIRECTIONS,     "all directions"        },
-  { MV_BIT_TOWARDS_PLAYER,     "towards player"        },
-  { MV_BIT_AWAY_FROM_PLAYER,   "away from player"      },
-  { MV_BIT_ALONG_LEFT_SIDE,    "along left side"       },
-  { MV_BIT_ALONG_RIGHT_SIDE,   "along right side"      },
+static struct ValueTextInfo options_move_pattern[] =
+{
+  { MV_LEFT,                   "left"                  },
+  { MV_RIGHT,                  "right"                 },
+  { MV_UP,                     "up"                    },
+  { MV_DOWN,                   "down"                  },
+  { MV_HORIZONTAL,             "horizontal"            },
+  { MV_VERTICAL,               "vertical"              },
+  { MV_ALL_DIRECTIONS,         "all directions"        },
+  { MV_TOWARDS_PLAYER,         "towards player"        },
+  { MV_AWAY_FROM_PLAYER,       "away from player"      },
+  { MV_ALONG_LEFT_SIDE,                "along left side"       },
+  { MV_ALONG_RIGHT_SIDE,       "along right side"      },
   { -1,                                NULL                    }
 };
-static int index_move_direction = 0;
+static int index_move_pattern = 0;
 
 static struct ValueTextInfo options_walkable_layer[] =
 {
@@ -867,10 +867,10 @@ static struct
   },
   {
     ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(6),
-    GADGET_ID_CUSTOM_MOVE_DIRECTION,
+    GADGET_ID_CUSTOM_MOVE_PATTERN,
     -1,
-    options_move_direction, &index_move_direction,
-    &custom_element.move_direction,
+    options_move_pattern, &index_move_pattern,
+    &custom_element.move_pattern,
     "can move", "element move direction"
   },
   {
index dcb4aa54696e5af6a7922759560d3d9b3cb8d1a4..c835a73464436b25413e488f65f2226819d0a8af 100644 (file)
@@ -101,7 +101,7 @@ static void setLevelInfoToDefaults()
 
     element_info[element].use_gfx_element = FALSE;
     element_info[element].gfx_element = EL_EMPTY_SPACE;
-    element_info[element].move_direction = 0;
+    element_info[element].move_pattern = MV_NO_MOVING;
 
     for(x=0; x<3; x++)
       for(y=0; y<3; y++)
index 6a771c300a535dfcf90c638b1d79970a64e4ae89..b034735bd66b4cf6e5f65aae793a42c118c3e91e 100644 (file)
@@ -377,7 +377,9 @@ static int getBeltDirFromBeltSwitchElement(int element)
 
 static void InitField(int x, int y, boolean init_game)
 {
-  switch (Feld[x][y])
+  int element = Feld[x][y];
+
+  switch (element)
   {
     case EL_SP_MURPHY:
       if (init_game)
@@ -574,6 +576,8 @@ static void InitField(int x, int y, boolean init_game)
       break;
 
     default:
+      if (IS_CUSTOM_ELEMENT(element) && CAN_MOVE(element))
+       InitMovDir(x, y);
       break;
   }
 }
@@ -635,32 +639,6 @@ static void InitGameEngine()
   game.initial_move_delay_value =
     (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
 
-#if 0
-  /* dynamically adjust element properties according to game engine version */
-  {
-    static int ep_em_slippery_wall[] =
-    {
-      EL_STEELWALL,
-      EL_WALL,
-      EL_EXPANDABLE_WALL,
-      EL_EXPANDABLE_WALL_HORIZONTAL,
-      EL_EXPANDABLE_WALL_VERTICAL,
-      EL_EXPANDABLE_WALL_ANY
-    };
-    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++)
-      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 */
-    SET_PROPERTY(EL_EXPANDABLE_WALL_GROWING, EP_EM_SLIPPERY_WALL,
-                (level.em_slippery_gems &&
-                 game.engine_version > VERSION_IDENT(2,0,1)));
-  }
-#endif
-
   /* initialize changing elements information */
   for (i=0; i<MAX_NUM_ELEMENTS; i++)
   {
@@ -1161,30 +1139,64 @@ void InitMovDir(int x, int y)
       break;
 
     default:
-      MovDir[x][y] = 1 << RND(4);
-      if (element != EL_BUG &&
-         element != EL_SPACESHIP &&
-         element != EL_BD_BUTTERFLY &&
-         element != EL_BD_FIREFLY)
-       break;
-
-      for (i=0; i<4; i++)
+      if (IS_CUSTOM_ELEMENT(element))
       {
-       int x1 = x + xy[i][0];
-       int y1 = y + xy[i][1];
-
-       if (!IN_LEV_FIELD(x1, y1) || !IS_FREE(x1, y1))
+       if (element_info[element].move_pattern == MV_ALL_DIRECTIONS)
+         MovDir[x][y] = 1 << RND(4);
+       else if (element_info[element].move_pattern == MV_HORIZONTAL)
+         MovDir[x][y] = (RND(2) ? MV_LEFT : MV_RIGHT);
+       else if (element_info[element].move_pattern == MV_VERTICAL)
+         MovDir[x][y] = (RND(2) ? MV_UP : MV_DOWN);
+       else if (element_info[element].move_pattern & MV_ANY_DIRECTION)
+         MovDir[x][y] = element_info[element].move_pattern;
+       else if (element_info[element].move_pattern == MV_ALONG_LEFT_SIDE ||
+                element_info[element].move_pattern == MV_ALONG_RIGHT_SIDE)
        {
-         if (element == EL_BUG || element == EL_BD_BUTTERFLY)
+         for (i=0; i<4; i++)
          {
-           MovDir[x][y] = direction[0][i];
-           break;
+           int x1 = x + xy[i][0];
+           int y1 = y + xy[i][1];
+
+           if (!IN_LEV_FIELD(x1, y1) || !IS_FREE(x1, y1))
+           {
+             if (element_info[element].move_pattern == MV_ALONG_RIGHT_SIDE)
+               MovDir[x][y] = direction[0][i];
+             else
+               MovDir[x][y] = direction[1][i];
+
+             break;
+           }
          }
-         else if (element == EL_SPACESHIP || element == EL_BD_FIREFLY ||
-                  element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
+       }                
+      }
+      else
+      {
+       MovDir[x][y] = 1 << RND(4);
+
+       if (element != EL_BUG &&
+           element != EL_SPACESHIP &&
+           element != EL_BD_BUTTERFLY &&
+           element != EL_BD_FIREFLY)
+         break;
+
+       for (i=0; i<4; i++)
+       {
+         int x1 = x + xy[i][0];
+         int y1 = y + xy[i][1];
+
+         if (!IN_LEV_FIELD(x1, y1) || !IS_FREE(x1, y1))
          {
-           MovDir[x][y] = direction[1][i];
-           break;
+           if (element == EL_BUG || element == EL_BD_BUTTERFLY)
+           {
+             MovDir[x][y] = direction[0][i];
+             break;
+           }
+           else if (element == EL_SPACESHIP || element == EL_BD_FIREFLY ||
+                    element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
+           {
+             MovDir[x][y] = direction[1][i];
+             break;
+           }
          }
        }
       }
@@ -2836,8 +2848,8 @@ void TurnRound(int x, int y)
 
       for (i=0; i<4; i++)
       {
-       int ex = x + xy[i%4][0];
-       int ey = y + xy[i%4][1];
+       int ex = x + xy[i % 4][0];
+       int ey = y + xy[i % 4][1];
 
        if (IN_LEV_FIELD(ex, ey) && Feld[ex][ey] == EL_EXIT_OPEN)
        {
@@ -2849,21 +2861,21 @@ void TurnRound(int x, int y)
     }
 
     MovDir[x][y] = MV_NO_MOVING;
-    if (attr_x<x)
+    if (attr_x < x)
       MovDir[x][y] |= (AllPlayersGone ? MV_RIGHT : MV_LEFT);
-    else if (attr_x>x)
+    else if (attr_x > x)
       MovDir[x][y] |= (AllPlayersGone ? MV_LEFT : MV_RIGHT);
-    if (attr_y<y)
+    if (attr_y < y)
       MovDir[x][y] |= (AllPlayersGone ? MV_DOWN : MV_UP);
-    else if (attr_y>y)
+    else if (attr_y > y)
       MovDir[x][y] |= (AllPlayersGone ? MV_UP : MV_DOWN);
 
     if (element == EL_ROBOT)
     {
       int newx, newy;
 
-      if ((MovDir[x][y]&(MV_LEFT|MV_RIGHT)) && (MovDir[x][y]&(MV_UP|MV_DOWN)))
-       MovDir[x][y] &= (RND(2) ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
+      if (MovDir[x][y] & MV_HORIZONTAL && MovDir[x][y] & MV_VERTICAL)
+       MovDir[x][y] &= (RND(2) ? MV_HORIZONTAL : MV_VERTICAL);
       Moving2Blocked(x, y, &newx, &newy);
 
       if (IN_LEV_FIELD(newx, newy) && IS_FREE_OR_PLAYER(newx, newy))
@@ -2877,13 +2889,13 @@ void TurnRound(int x, int y)
 
       MovDelay[x][y] = 1;
 
-      if ((MovDir[x][y]&(MV_LEFT|MV_RIGHT)) && (MovDir[x][y]&(MV_UP|MV_DOWN)))
+      if (MovDir[x][y] & MV_HORIZONTAL && MovDir[x][y] & MV_VERTICAL)
       {
        boolean first_horiz = RND(2);
        int new_move_dir = MovDir[x][y];
 
        MovDir[x][y] =
-         new_move_dir & (first_horiz ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
+         new_move_dir & (first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
        Moving2Blocked(x, y, &newx, &newy);
 
        if (IN_LEV_FIELD(newx, newy) &&
@@ -2895,7 +2907,7 @@ void TurnRound(int x, int y)
          return;
 
        MovDir[x][y] =
-         new_move_dir & (!first_horiz ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
+         new_move_dir & (!first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
        Moving2Blocked(x, y, &newx, &newy);
 
        if (IN_LEV_FIELD(newx, newy) &&
@@ -2911,6 +2923,124 @@ void TurnRound(int x, int y)
       }
     }
   }
+  else if (element_info[element].move_pattern == MV_ALL_DIRECTIONS)
+  {
+    boolean can_turn_left = FALSE, can_turn_right = FALSE;
+
+    if (IN_LEV_FIELD(left_x, left_y) && IS_FREE(left_x, left_y))
+      can_turn_left = TRUE;
+    if (IN_LEV_FIELD(right_x, right_y) && IS_FREE(right_x, right_y))
+      can_turn_right = TRUE;
+
+    if (can_turn_left && can_turn_right)
+      MovDir[x][y] = (RND(3) ? (RND(2) ? left_dir : right_dir) : back_dir);
+    else if (can_turn_left)
+      MovDir[x][y] = (RND(2) ? left_dir : back_dir);
+    else if (can_turn_right)
+      MovDir[x][y] = (RND(2) ? right_dir : back_dir);
+    else
+      MovDir[x][y] = back_dir;
+
+    MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+  }
+  else if (element_info[element].move_pattern == MV_HORIZONTAL ||
+          element_info[element].move_pattern == MV_VERTICAL)
+  {
+    MovDir[x][y] = back_dir;
+    MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+  }
+  else if (element_info[element].move_pattern & MV_ANY_DIRECTION)
+  {
+    MovDir[x][y] = element_info[element].move_pattern;
+    MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+  }
+  else if (element_info[element].move_pattern == MV_ALONG_LEFT_SIDE)
+  {
+    if (IN_LEV_FIELD(left_x, left_y) && IS_FREE(left_x, left_y))
+      MovDir[x][y] = left_dir;
+    else if (!IN_LEV_FIELD(move_x, move_y) || !IS_FREE(move_x, move_y))
+      MovDir[x][y] = right_dir;
+
+    MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+  }
+  else if (element_info[element].move_pattern == MV_ALONG_RIGHT_SIDE)
+  {
+    if (IN_LEV_FIELD(right_x, right_y) && IS_FREE(right_x, right_y))
+      MovDir[x][y] = right_dir;
+    else if (!IN_LEV_FIELD(move_x, move_y) || !IS_FREE(move_x, move_y))
+      MovDir[x][y] = left_dir;
+
+    MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+  }
+  else if (element_info[element].move_pattern == MV_TOWARDS_PLAYER ||
+          element_info[element].move_pattern == MV_AWAY_FROM_PLAYER)
+  {
+    int attr_x = -1, attr_y = -1;
+    int newx, newy;
+    boolean move_away =
+      (element_info[element].move_pattern == MV_AWAY_FROM_PLAYER);
+
+    if (AllPlayersGone)
+    {
+      attr_x = ExitX;
+      attr_y = ExitY;
+    }
+    else
+    {
+      int i;
+
+      for (i=0; i<MAX_PLAYERS; i++)
+      {
+       struct PlayerInfo *player = &stored_player[i];
+       int jx = player->jx, jy = player->jy;
+
+       if (!player->active)
+         continue;
+
+       if (attr_x == -1 || ABS(jx-x)+ABS(jy-y) < ABS(attr_x-x)+ABS(attr_y-y))
+       {
+         attr_x = jx;
+         attr_y = jy;
+       }
+      }
+    }
+
+    MovDir[x][y] = MV_NO_MOVING;
+    if (attr_x < x)
+      MovDir[x][y] |= (move_away ? MV_RIGHT : MV_LEFT);
+    else if (attr_x > x)
+      MovDir[x][y] |= (move_away ? MV_LEFT : MV_RIGHT);
+    if (attr_y < y)
+      MovDir[x][y] |= (move_away ? MV_DOWN : MV_UP);
+    else if (attr_y > y)
+      MovDir[x][y] |= (move_away ? MV_UP : MV_DOWN);
+
+    MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+
+    if (MovDir[x][y] & MV_HORIZONTAL && MovDir[x][y] & MV_VERTICAL)
+    {
+      boolean first_horiz = RND(2);
+      int new_move_dir = MovDir[x][y];
+
+      MovDir[x][y] =
+       new_move_dir & (first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
+      Moving2Blocked(x, y, &newx, &newy);
+
+      if (IN_LEV_FIELD(newx, newy) && (IS_FREE(newx, newy) ||
+                                      Feld[newx][newy] == EL_ACID))
+       return;
+
+      MovDir[x][y] =
+       new_move_dir & (!first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
+      Moving2Blocked(x, y, &newx, &newy);
+
+      if (IN_LEV_FIELD(newx, newy) && (IS_FREE(newx, newy) ||
+                                      Feld[newx][newy] == EL_ACID))
+       return;
+
+      MovDir[x][y] = old_move_dir;
+    }
+  }
 }
 
 static boolean JustBeingPushed(int x, int y)
@@ -3198,7 +3328,8 @@ void StartMoving(int x, int y)
 
       if (element != EL_YAMYAM &&
          element != EL_DARK_YAMYAM &&
-         element != EL_PACMAN)
+         element != EL_PACMAN &&
+         !(element_info[element].move_pattern & MV_ANY_DIRECTION))
       {
        TurnRound(x, y);
 
index 5bc49cf75e9ad8dd98131cd38fa7c528cb9db450..2ab42de2c8ddb1131f11f387118a12633f542d3c 100644 (file)
@@ -2474,6 +2474,18 @@ void InitElementPropertiesEngine(int engine_version)
                 (level.em_slippery_gems &&
                  engine_version > VERSION_IDENT(2,0,1)));
   }
+
+  /* dynamically adjust element properties according to game engine version */
+  if (engine_version < RELEASE_IDENT(2,2,0,7))
+  {
+    for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+    {
+      int element = EL_CUSTOM_START + i;
+
+      element_info[element].push_delay_fixed = 2;
+      element_info[element].push_delay_random = 8;
+    }
+  }
 }
 
 static void InitGlobal()
index dbaa3ddf1c25df11a7946e73b6b48567e4915504..bc0256361c86adf56dc712ed007f7a62147f32ab 100644 (file)
 
 #define NUM_DIRECTIONS         4
 
-/* values for special move patterns (stored in level files) */
-#define MV_BIT_HORIZONTAL      4
-#define MV_BIT_VERTICAL                5
-#define MV_BIT_ALL_DIRECTIONS  6
-#define MV_BIT_TOWARDS_PLAYER  7
-#define MV_BIT_AWAY_FROM_PLAYER        8
-#define MV_BIT_ALONG_LEFT_SIDE 9
-#define MV_BIT_ALONG_RIGHT_SIDE        10
+/* values for special "button" bitmasks (effective at runtime) */
+#define BUTTON_1               4
+#define BUTTON_2               5
 
-#define NUM_MOVE_PATTERNS      11
+/* values for special move patterns (stored in level files) */
+#define MV_BIT_TOWARDS_PLAYER  6
+#define MV_BIT_AWAY_FROM_PLAYER        7
+#define MV_BIT_ALONG_LEFT_SIDE 8
+#define MV_BIT_ALONG_RIGHT_SIDE        9
 
-/* values for move direction and special "button" key bitmasks */
+/* values for move direction/pattern and special "button" key bitmasks */
 #define MV_NO_MOVING           0
 #define MV_LEFT                        (1 << MV_BIT_LEFT)
 #define MV_RIGHT               (1 << MV_BIT_RIGHT)
 #define MV_UP                  (1 << MV_BIT_UP)
 #define MV_DOWN                        (1 << MV_BIT_DOWN)
-#define KEY_BUTTON_1           (1 << 4)
-#define KEY_BUTTON_2           (1 << 5)
+
+#define KEY_BUTTON_1           (1 << BUTTON_1)
+#define KEY_BUTTON_2           (1 << BUTTON_2)
 #define KEY_MOTION             (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)
 #define KEY_BUTTON             (KEY_BUTTON_1 | KEY_BUTTON_2)
 #define KEY_ACTION             (KEY_MOTION | KEY_BUTTON)
                                 (x) == MV_RIGHT ? MV_BIT_RIGHT :       \
                                 (x) == MV_UP    ? MV_BIT_UP    : MV_BIT_DOWN)
 
+#define MV_HORIZONTAL          (MV_LEFT | MV_RIGHT)
+#define MV_VERTICAL            (MV_UP | MV_DOWN)
+#define MV_ALL_DIRECTIONS      (MV_HORIZONTAL | MV_VERTICAL)
+#define MV_ANY_DIRECTION       (MV_ALL_DIRECTIONS)
+#define MV_TOWARDS_PLAYER      (1 << MV_BIT_TOWARDS_PLAYER)
+#define MV_AWAY_FROM_PLAYER    (1 << MV_BIT_AWAY_FROM_PLAYER)
+#define MV_ALONG_LEFT_SIDE     (1 << MV_BIT_ALONG_LEFT_SIDE)
+#define MV_ALONG_RIGHT_SIDE    (1 << MV_BIT_ALONG_RIGHT_SIDE)
 
 /* values for button status */
 #define MB_NOT_PRESSED         FALSE
index 3b8863640ed4cf5dbc5bb663909761c895db3ddf..23b431efaa7be3ea837584b7aa4ad2eeca821c25 100644 (file)
@@ -1172,7 +1172,7 @@ struct ElementInfo
   int move_delay_fixed;                /* constant frame delay for moving */
   int move_delay_random;       /* additional random frame delay for moving */
 
-  int move_direction;          /* direction movable element moves to */
+  int move_pattern;            /* direction movable element moves to */
 
   int walk_to_action;          /* only for level editor; not stored */
   int walkable_layer;          /* only for level editor; not stored */