rnd-20040118-1-src
authorHolger Schemel <info@artsoft.org>
Sun, 18 Jan 2004 10:29:22 +0000 (11:29 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:45:27 +0000 (10:45 +0200)
* custom elements can change (limited) or leave (unlimited) elements
* added new start movement type "previous" for continued CE movement
* added new start movement type "random" for random CE movement start
* added new element "sokoban_field_player" needed for Sokoban levels
  (thanks to Ed Booker for pointing this out!)
* added elements that can be digged or left behind by custom elements
* added group elements for multiple matches and random element creation
* fixed some graphical errors displayed in old levels
* fixed wrong double speed movement after passing closing gates

ChangeLog
src/conftime.h
src/editor.c
src/files.c
src/game.c
src/main.h

index b3e2aeb92e431e4a92054a337cdfe8cd0529f793..942dd6cdd9c565015259b02644455516cb91375e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,28 @@
+2004-01-18
+       * custom elements can change (limited) or leave (unlimited) elements
+
+2004-01-17
+       * added new start movement type "previous" for continued CE movement
+       * added new start movement type "random" for random CE movement start
+
+2004-01-17
+       * added new element "sokoban_field_player" needed for Sokoban levels
+         (thanks to Ed Booker for pointing this out!)
+
+2004-01-15
+       * added elements that can be digged or left behind by custom elements
+
+2004-01-12
+       * added group elements for multiple matches and random element creation
+
+2004-01-11
+       * fixed some graphical errors displayed in old levels
+
+2004-01-10
+       * fixed wrong double speed movement after passing closing gates
 
 2004-01-03
-       * level loader can now load native Emerald Mine levels
+       * added level loader for loading native Emerald Mine levels
 
 2004-01-02
        * changes for "shooting" style CE movement
index 95c1f875058a238e4a965d589057afc006fd626b..49a5b80edfbf9640fafcc1f6ac96f80ddc11da76 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2004-01-17 15:38]"
+#define COMPILE_DATE_STRING "[2004-01-18 11:28]"
index 4877a8bcae69d56bdae6eb0a5c68518bfc001d0f..bdff29f01e88097583051181d39f2334911fcfcb 100644 (file)
 #define GADGET_ID_CUSTOM_MOVE_PATTERN  (GADGET_ID_SELECTBOX_FIRST + 3)
 #define GADGET_ID_CUSTOM_MOVE_DIRECTION        (GADGET_ID_SELECTBOX_FIRST + 4)
 #define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 5)
-#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 6)
-#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 7)
-#define GADGET_ID_CUSTOM_ACCESS_TYPE   (GADGET_ID_SELECTBOX_FIRST + 8)
-#define GADGET_ID_CUSTOM_ACCESS_LAYER  (GADGET_ID_SELECTBOX_FIRST + 9)
-#define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 10)
-#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 11)
-#define GADGET_ID_CHANGE_OTHER_ACTION  (GADGET_ID_SELECTBOX_FIRST + 12)
-#define GADGET_ID_CHANGE_SIDES         (GADGET_ID_SELECTBOX_FIRST + 13)
-#define GADGET_ID_CHANGE_POWER         (GADGET_ID_SELECTBOX_FIRST + 14)
-#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 15)
+#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 6)
+#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 7)
+#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 8)
+#define GADGET_ID_CUSTOM_ACCESS_TYPE   (GADGET_ID_SELECTBOX_FIRST + 9)
+#define GADGET_ID_CUSTOM_ACCESS_LAYER  (GADGET_ID_SELECTBOX_FIRST + 10)
+#define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 11)
+#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 12)
+#define GADGET_ID_CHANGE_OTHER_ACTION  (GADGET_ID_SELECTBOX_FIRST + 13)
+#define GADGET_ID_CHANGE_SIDES         (GADGET_ID_SELECTBOX_FIRST + 14)
+#define GADGET_ID_CHANGE_POWER         (GADGET_ID_SELECTBOX_FIRST + 15)
+#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 16)
 
 /* textbutton identifiers */
-#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 16)
+#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 17)
 
 #define GADGET_ID_PROPERTIES_INFO      (GADGET_ID_TEXTBUTTON_FIRST + 0)
 #define GADGET_ID_PROPERTIES_CONFIG    (GADGET_ID_TEXTBUTTON_FIRST + 1)
 #define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN    3
 #define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION  4
 #define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE   5
-#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS   6
-#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE   7
-#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS      8
-#define ED_SELECTBOX_ID_CUSTOM_CONSISTENCY     9
-#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      10
-#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION   11
-#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    12
-#define ED_SELECTBOX_ID_CHANGE_SIDES           13
-#define ED_SELECTBOX_ID_CHANGE_POWER           14
-#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     15
-
-#define ED_NUM_SELECTBOX                       16
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 6
+#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS   7
+#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE   8
+#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS      9
+#define ED_SELECTBOX_ID_CUSTOM_CONSISTENCY     10
+#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      11
+#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION   12
+#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    13
+#define ED_SELECTBOX_ID_CHANGE_SIDES           14
+#define ED_SELECTBOX_ID_CHANGE_POWER           15
+#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     16
+
+#define ED_NUM_SELECTBOX                       17
 
 #define ED_SELECTBOX_ID_CUSTOM_FIRST   ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE
 #define ED_SELECTBOX_ID_CUSTOM_LAST    ED_SELECTBOX_ID_CUSTOM_CONSISTENCY
@@ -1136,6 +1138,13 @@ static struct ValueTextInfo options_move_stepsize[] =
   { -1,                                NULL                            }
 };
 
+static struct ValueTextInfo options_move_leave_type[] =
+{
+  { LEAVE_TYPE_UNLIMITED,      "leave behind"                  },
+  { LEAVE_TYPE_LIMITED,                "change to"                     },
+  { -1,                                NULL                            }
+};
+
 static struct ValueTextInfo options_smash_targets[] =
 {
   { EP_CAN_SMASH_PLAYER,       "player"                        },
@@ -1308,6 +1317,14 @@ static struct
     &custom_element.move_stepsize,
     "move/fall speed", NULL,           "speed of element movement"
   },
+  {
+    ED_SETTINGS_XPOS(1),               ED_SETTINGS_YPOS(7),
+    GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE,  GADGET_ID_NONE,
+    -1,
+    options_move_leave_type,
+    &custom_element.move_leave_type,
+    "can dig:    can", ":",            "leave behind or change element"
+  },
   {
     -1,                                        ED_SETTINGS_YPOS(10),
     GADGET_ID_CUSTOM_SMASH_TARGETS,    GADGET_ID_CUSTOM_CAN_SMASH,
@@ -1861,12 +1878,11 @@ static struct
     GADGET_ID_CUSTOM_MOVE_ENTER,       GADGET_ID_NONE,
     "can dig:", " ",                   NULL
   },
-
   {
     -1,                                        ED_AREA_ELEM_CONTENT4b_YPOS,
     1, 1,
-    GADGET_ID_CUSTOM_MOVE_LEAVE,       GADGET_ID_CUSTOM_MOVE_ENTER,
-    "can leave behind:", NULL,         NULL
+    GADGET_ID_CUSTOM_MOVE_LEAVE,       GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE,
+    NULL, NULL,                                NULL
   },
 
   /* ---------- custom change target --------------------------------------- */
index c447bba91e40ccc220a9bd1e5506a8a3e66c01b8..2f53a622faf1ad3ced0465ba89559f31ab45d32a 100644 (file)
@@ -214,6 +214,7 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
       element_info[element].move_stepsize = TILEX / 8;
       element_info[element].move_enter_element = EL_EMPTY_SPACE;
       element_info[element].move_leave_element = EL_EMPTY_SPACE;
+      element_info[element].move_leave_type = LEAVE_TYPE_UNLIMITED;
 
       element_info[element].slippery_type = SLIPPERY_ANY_RANDOM;
 
@@ -874,9 +875,10 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
 
   ei->move_enter_element = checkLevelElement(getFile16BitBE(file));
   ei->move_leave_element = checkLevelElement(getFile16BitBE(file));
+  ei->move_leave_type = getFile8Bit(file);
 
   /* some free bytes for future custom property values and padding */
-  ReadUnusedBytesFromFile(file, 8);
+  ReadUnusedBytesFromFile(file, 7);
 
   /* read change property values */
 
@@ -2041,9 +2043,10 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
 
   putFile16BitBE(file, ei->move_enter_element);
   putFile16BitBE(file, ei->move_leave_element);
+  putFile8Bit(file, ei->move_leave_type);
 
   /* some free bytes for future custom property values and padding */
-  WriteUnusedBytesToFile(file, 8);
+  WriteUnusedBytesToFile(file, 7);
 
   /* write change property values */
 
index dfad329ef9c2b2e64d5df8fb4e1a4c6986edd595..c7b803a314e5471b6e244e81a0515934f6ad6e42 100644 (file)
@@ -1085,6 +1085,14 @@ static void InitGameEngine()
     element_info[e].move_stepsize = move_stepsize_list[i].move_stepsize;
   }
 
+  /* ---------- initialize move dig/leave ---------------------------------- */
+
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+  {
+    element_info[i].can_leave_element = FALSE;
+    element_info[i].can_leave_element_last = FALSE;
+  }
+
   /* ---------- initialize gem count --------------------------------------- */
 
   /* initialize gem count values for each element */
@@ -1735,10 +1743,11 @@ void InitMovDir(int x, int y)
          move_direction_initial = MV_AUTOMATIC;
        }
 
-       if (move_direction_initial & MV_ANY_DIRECTION)
+       if (move_direction_initial == MV_RANDOM)
+         MovDir[x][y] = 1 << RND(4);
+       else if (move_direction_initial & MV_ANY_DIRECTION)
          MovDir[x][y] = move_direction_initial;
-       else if (move_direction_initial == MV_RANDOM ||
-                move_pattern == MV_ALL_DIRECTIONS ||
+       else if (move_pattern == MV_ALL_DIRECTIONS ||
                 move_pattern == MV_TURNING_LEFT ||
                 move_pattern == MV_TURNING_RIGHT ||
                 move_pattern == MV_TURNING_LEFT_RIGHT ||
@@ -4731,6 +4740,8 @@ void StartMoving(int x, int y)
 
 )
     {
+      int new_element = Feld[newx][newy];
+
 #if 0
       printf("::: '%s' digs '%s' [%d]\n",
             element_info[element].token_name,
@@ -4740,8 +4751,9 @@ void StartMoving(int x, int y)
 
       if (!IS_FREE(newx, newy))
       {
-       int new_element = Feld[newx][newy];
-       int sound;
+       int action = (IS_DIGGABLE(new_element) ? ACTION_DIGGING :
+                     IS_COLLECTIBLE(new_element) ? ACTION_COLLECTING :
+                     ACTION_BREAKING);
 
        /* no element can dig solid indestructible elements */
        if (IS_INDESTRUCTIBLE(new_element) &&
@@ -4766,13 +4778,12 @@ void StartMoving(int x, int y)
          DrawLevelField(newx, newy);
        }
 
-       sound = (IS_DIGGABLE(new_element) ? ACTION_DIGGING :
-                IS_COLLECTIBLE(new_element) ? ACTION_COLLECTING :
-                ACTION_BREAKING);
-
-       PlayLevelSoundAction(x, y, sound);
+       PlayLevelSoundAction(x, y, action);
       }
 
+      if (new_element == element_info[element].move_enter_element)
+       element_info[element].can_leave_element = TRUE;
+
       if (move_pattern & MV_MAZE_RUNNER_STYLE)
       {
        RunnerVisit[x][y] = FrameCounter;
@@ -4953,6 +4964,7 @@ void StartMoving(int x, int y)
 void ContinueMoving(int x, int y)
 {
   int element = Feld[x][y];
+  struct ElementInfo *ei = &element_info[element];
   int direction = MovDir[x][y];
   int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
   int dy = (direction == MV_UP   ? -1 : direction == MV_DOWN  ? +1 : 0);
@@ -5070,22 +5082,20 @@ void ContinueMoving(int x, int y)
   ResetGfxAnimation(x, y);     /* reset animation values for old field */
 
 #if 1
-  if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y))
+  if (IS_CUSTOM_ELEMENT(element) && !IS_PLAYER(x, y) &&
+      ei->move_leave_element != EL_EMPTY &&
+      (ei->move_leave_type == LEAVE_TYPE_UNLIMITED ||
+       ei->can_leave_element_last))
   {
-    int new_element = element_info[element].move_leave_element;
-
-    Feld[x][y] = new_element;
-
-    if (new_element != EL_EMPTY)
-    {
-      InitField(x, y, FALSE);
-
-      TestIfElementTouchesCustomElement(x, y);
+    Feld[x][y] = ei->move_leave_element;
+    InitField(x, y, FALSE);
 
-      if (GFX_CRUMBLED(new_element))
-       DrawLevelFieldCrumbledSandNeighbours(x, y);
-    }
+    if (GFX_CRUMBLED(Feld[x][y]))
+      DrawLevelFieldCrumbledSandNeighbours(x, y);
   }
+
+  ei->can_leave_element_last = ei->can_leave_element;
+  ei->can_leave_element = FALSE;
 #endif
 
 #if 0
@@ -5147,7 +5157,7 @@ void ContinueMoving(int x, int y)
     Impact(x, newy);
 
 #if 1
-  TestIfElementTouchesCustomElement(x, y);             /* for empty space */
+  TestIfElementTouchesCustomElement(x, y);     /* empty or new element */
 #endif
 
 #if 0
index 64cd7bdcf44b7210aca3f4fa88d57ae36a1b6fa5..f449795aac7722dd4d1ed5999ff376df10a72d55 100644 (file)
 #define MV_TURNING_RANDOM      (1 << MV_BIT_TURNING_RANDOM)
 #define MV_PREVIOUS            (1 << MV_BIT_PREVIOUS)
 
+/* values for elements left behind by custom elements */
+#define LEAVE_TYPE_UNLIMITED   0
+#define LEAVE_TYPE_LIMITED     1
+
 /* values for slippery property for custom elements */
 #define SLIPPERY_ANY_RANDOM    0
 #define SLIPPERY_ANY_LEFT_RIGHT        1
@@ -1524,6 +1528,7 @@ struct ElementInfo
   int move_stepsize;           /* step size element moves with */
   int move_enter_element;      /* element that can be entered (and removed) */
   int move_leave_element;      /* element that can be left behind */
+  int move_leave_type;         /* change (limited) or leave (unlimited) */
 
   int slippery_type;           /* how/where other elements slip away */
 
@@ -1546,6 +1551,9 @@ struct ElementInfo
 
   boolean in_group[NUM_GROUP_ELEMENTS];
 
+  boolean can_leave_element;   /* element can leave other element behind */
+  boolean can_leave_element_last;
+
   /* ---------- internal values used in level editor ---------- */
 
   int access_type;             /* walkable or passable */