rnd-20040326-1-src
authorHolger Schemel <info@artsoft.org>
Fri, 26 Mar 2004 09:45:37 +0000 (10:45 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:46:39 +0000 (10:46 +0200)
* added option to make growing elements grow into anything diggable
  (for the various amoeba types, biomaze and "game of life")

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

index dcea920b159bdfd31e3e4baa205ed1ea80123f7a..f9d9f79e895c1235cc3b3b3475fee8f1365baf5b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
+2004-03-26
+       * added option to make growing elements grow into anything diggable
+         (for the various amoeba types, biomaze and "game of life")
+
 2004-03-24
        * fixed bug with movable elements not moving after left behind by CEs
+       * changed gravity movement to anything diggable, not only sand/base
+       * optionally allowing passing to walkable element, not only empty space
+       * added option "can pass to walkable element" for players
+       * finally fixed gravity movement (hopefully)
 
 2004-03-23
        * fixed bug with movable elements not moving anymore after falling down
index 999c4b9f15feec49cf4f0c8b9f445a0368ecaa60..e047875251ca735bfbde576d765a41e64fc4f11d 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2004-03-25 03:08]"
+#define COMPILE_DATE_STRING "[2004-03-26 10:44]"
index 97904719c9a2df1d74229853f6a667a834835a0e..98b8375c478d79cce2130c2ea7a5fc7a69934f87 100644 (file)
 #define GADGET_ID_STICK_ELEMENT                (GADGET_ID_CHECKBUTTON_FIRST + 5)
 #define GADGET_ID_EM_SLIPPERY_GEMS     (GADGET_ID_CHECKBUTTON_FIRST + 6)
 #define GADGET_ID_USE_SPRING_BUG       (GADGET_ID_CHECKBUTTON_FIRST + 7)
-#define GADGET_ID_BLOCK_LAST_FIELD     (GADGET_ID_CHECKBUTTON_FIRST + 8)
-#define GADGET_ID_SP_BLOCK_LAST_FIELD  (GADGET_ID_CHECKBUTTON_FIRST + 9)
-#define GADGET_ID_INSTANT_RELOCATION   (GADGET_ID_CHECKBUTTON_FIRST + 10)
-#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 11)
-#define GADGET_ID_CAN_FALL_INTO_ACID   (GADGET_ID_CHECKBUTTON_FIRST + 12)
-#define GADGET_ID_CAN_MOVE_INTO_ACID   (GADGET_ID_CHECKBUTTON_FIRST + 13)
-#define GADGET_ID_DONT_COLLIDE_WITH    (GADGET_ID_CHECKBUTTON_FIRST + 14)
-#define GADGET_ID_CUSTOM_EXPLODE_RESULT        (GADGET_ID_CHECKBUTTON_FIRST + 15)
-#define GADGET_ID_CUSTOM_EXPLODE_FIRE  (GADGET_ID_CHECKBUTTON_FIRST + 16)
-#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 17)
-#define GADGET_ID_CUSTOM_EXPLODE_IMPACT        (GADGET_ID_CHECKBUTTON_FIRST + 18)
-#define GADGET_ID_CUSTOM_WALK_TO_OBJECT        (GADGET_ID_CHECKBUTTON_FIRST + 19)
-#define GADGET_ID_CUSTOM_DEADLY                (GADGET_ID_CHECKBUTTON_FIRST + 20)
-#define GADGET_ID_CUSTOM_CAN_MOVE      (GADGET_ID_CHECKBUTTON_FIRST + 21)
-#define GADGET_ID_CUSTOM_CAN_FALL      (GADGET_ID_CHECKBUTTON_FIRST + 22)
-#define GADGET_ID_CUSTOM_CAN_SMASH     (GADGET_ID_CHECKBUTTON_FIRST + 23)
-#define GADGET_ID_CUSTOM_SLIPPERY      (GADGET_ID_CHECKBUTTON_FIRST + 24)
-#define GADGET_ID_CUSTOM_ACCESSIBLE    (GADGET_ID_CHECKBUTTON_FIRST + 25)
-#define GADGET_ID_CUSTOM_USE_GRAPHIC   (GADGET_ID_CHECKBUTTON_FIRST + 26)
-#define GADGET_ID_CUSTOM_USE_TEMPLATE  (GADGET_ID_CHECKBUTTON_FIRST + 27)
-#define GADGET_ID_CUSTOM_CAN_CHANGE    (GADGET_ID_CHECKBUTTON_FIRST + 28)
-#define GADGET_ID_CHANGE_USE_CONTENT   (GADGET_ID_CHECKBUTTON_FIRST + 29)
-#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 30)
-#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 31)
-#define GADGET_ID_CHANGE_USE_RANDOM    (GADGET_ID_CHECKBUTTON_FIRST + 32)
-#define GADGET_ID_CHANGE_DELAY         (GADGET_ID_CHECKBUTTON_FIRST + 33)
-#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 34)
-#define GADGET_ID_CHANGE_BY_OTHER_ACT  (GADGET_ID_CHECKBUTTON_FIRST + 35)
+#define GADGET_ID_GROW_INTO_DIGGABLE   (GADGET_ID_CHECKBUTTON_FIRST + 8)
+#define GADGET_ID_BLOCK_LAST_FIELD     (GADGET_ID_CHECKBUTTON_FIRST + 9)
+#define GADGET_ID_SP_BLOCK_LAST_FIELD  (GADGET_ID_CHECKBUTTON_FIRST + 10)
+#define GADGET_ID_INSTANT_RELOCATION   (GADGET_ID_CHECKBUTTON_FIRST + 11)
+#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 12)
+#define GADGET_ID_CAN_FALL_INTO_ACID   (GADGET_ID_CHECKBUTTON_FIRST + 13)
+#define GADGET_ID_CAN_MOVE_INTO_ACID   (GADGET_ID_CHECKBUTTON_FIRST + 14)
+#define GADGET_ID_DONT_COLLIDE_WITH    (GADGET_ID_CHECKBUTTON_FIRST + 15)
+#define GADGET_ID_CUSTOM_EXPLODE_RESULT        (GADGET_ID_CHECKBUTTON_FIRST + 16)
+#define GADGET_ID_CUSTOM_EXPLODE_FIRE  (GADGET_ID_CHECKBUTTON_FIRST + 17)
+#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 18)
+#define GADGET_ID_CUSTOM_EXPLODE_IMPACT        (GADGET_ID_CHECKBUTTON_FIRST + 19)
+#define GADGET_ID_CUSTOM_WALK_TO_OBJECT        (GADGET_ID_CHECKBUTTON_FIRST + 20)
+#define GADGET_ID_CUSTOM_DEADLY                (GADGET_ID_CHECKBUTTON_FIRST + 21)
+#define GADGET_ID_CUSTOM_CAN_MOVE      (GADGET_ID_CHECKBUTTON_FIRST + 22)
+#define GADGET_ID_CUSTOM_CAN_FALL      (GADGET_ID_CHECKBUTTON_FIRST + 23)
+#define GADGET_ID_CUSTOM_CAN_SMASH     (GADGET_ID_CHECKBUTTON_FIRST + 24)
+#define GADGET_ID_CUSTOM_SLIPPERY      (GADGET_ID_CHECKBUTTON_FIRST + 25)
+#define GADGET_ID_CUSTOM_ACCESSIBLE    (GADGET_ID_CHECKBUTTON_FIRST + 26)
+#define GADGET_ID_CUSTOM_USE_GRAPHIC   (GADGET_ID_CHECKBUTTON_FIRST + 27)
+#define GADGET_ID_CUSTOM_USE_TEMPLATE  (GADGET_ID_CHECKBUTTON_FIRST + 28)
+#define GADGET_ID_CUSTOM_CAN_CHANGE    (GADGET_ID_CHECKBUTTON_FIRST + 29)
+#define GADGET_ID_CHANGE_USE_CONTENT   (GADGET_ID_CHECKBUTTON_FIRST + 30)
+#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 31)
+#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 32)
+#define GADGET_ID_CHANGE_USE_RANDOM    (GADGET_ID_CHECKBUTTON_FIRST + 33)
+#define GADGET_ID_CHANGE_DELAY         (GADGET_ID_CHECKBUTTON_FIRST + 34)
+#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 35)
+#define GADGET_ID_CHANGE_BY_OTHER_ACT  (GADGET_ID_CHECKBUTTON_FIRST + 36)
 
 /* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 36)
+#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 37)
 #define GADGET_ID_ELEMENTLIST_LAST     (GADGET_ID_ELEMENTLIST_FIRST +  \
                                        ED_NUM_ELEMENTLIST_BUTTONS - 1)
 
 #define ED_CHECKBUTTON_ID_STICK_ELEMENT                3
 #define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS     4
 #define ED_CHECKBUTTON_ID_USE_SPRING_BUG       5
-#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD     6
-#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD  7
-#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION   8
-#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 9
-#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID   10
-#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID   11
-#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH    12
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC   13
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE  14
-#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE    15
-#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT        16
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE      17
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL      18
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH     19
-#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      20
-#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY                21
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT        22
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE  23
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 24
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT        25
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE    26
-#define ED_CHECKBUTTON_ID_CHANGE_DELAY         27
-#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 28
-#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT  29
-#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 30
-#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT   31
-#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 32
-#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM    33
-
-#define ED_NUM_CHECKBUTTONS                    34
+#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE   6
+#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD     7
+#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD  8
+#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION   9
+#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 10
+#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID   11
+#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID   12
+#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH    13
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC   14
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE  15
+#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE    16
+#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT        17
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE      18
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL      19
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH     20
+#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      21
+#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY                22
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT        23
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE  24
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 25
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT        26
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE    27
+#define ED_CHECKBUTTON_ID_CHANGE_DELAY         28
+#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 29
+#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT  30
+#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 31
+#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT   32
+#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 33
+#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM    34
+
+#define ED_NUM_CHECKBUTTONS                    35
 
 #define ED_CHECKBUTTON_ID_LEVEL_FIRST  ED_CHECKBUTTON_ID_DOUBLE_SPEED
 #define ED_CHECKBUTTON_ID_LEVEL_LAST   ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
@@ -1961,6 +1963,13 @@ static struct
     NULL,
     "use spring pushing bug",          "use odd spring pushing behaviour"
   },
+  {
+    ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(0),
+    GADGET_ID_GROW_INTO_DIGGABLE,      GADGET_ID_NONE,
+    &level.grow_into_diggable,
+    NULL,
+    "can grow into anything diggable", "grow into more than just sand"
+  },
   {
     ED_SETTINGS_XPOS(0),               ED_SETTINGS_YPOS(1),
     GADGET_ID_BLOCK_LAST_FIELD,                GADGET_ID_NONE,
@@ -2219,7 +2228,7 @@ static struct
   /* ---------- amoeba content --------------------------------------------- */
 
   {
-    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(2),
+    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(3),
     1, 1,
     GADGET_ID_AMOEBA_CONTENT,          GADGET_ID_NONE,
     "content:", NULL,                  NULL
@@ -5319,9 +5328,8 @@ static void MapCheckbuttonGadget(int id)
   int x_right = gi->x + gi->width + xoffset_right;
   int y;       /* set after gadget position was modified */
 
-  /* set position for "stickybutton" and "can move into acid" gadgets */
-  if (id == ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID)
-    ModifyGadget(gi, GDI_Y, SY + checkbutton_info[id].y, GDI_END);
+  /* set position for gadgets with dynamically determined vertical position */
+  ModifyGadget(gi, GDI_Y, SY + checkbutton_info[id].y, GDI_END);
 
   y = gi->y + yoffset;
 
@@ -6945,6 +6953,7 @@ static boolean checkPropertiesConfig(int element)
       IS_ENVELOPE(element) ||
       ELEM_IS_PLAYER(element) ||
       HAS_CONTENT(element) ||
+      CAN_GROW(element) ||
       COULD_MOVE_INTO_ACID(element) ||
       MAYBE_DONT_COLLIDE_WITH(element))
     return TRUE;
@@ -6976,8 +6985,9 @@ static void DrawPropertiesConfig()
 
       counterbutton_info[counter_id].y =
        ED_SETTINGS_YPOS((HAS_CONTENT(properties_element) ? 1 : 0) +
-                        (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 : 0)+
-                        (COULD_MOVE_INTO_ACID(properties_element) ? 1 : 0));
+                        (CAN_GROW(properties_element) ? 1 : 0) +
+                        (COULD_MOVE_INTO_ACID(properties_element) ? 1 : 0) +
+                        (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 :0));
 
       counterbutton_info[counter_id].value = elements_with_counter[i].value;
       counterbutton_info[counter_id].text_right= elements_with_counter[i].text;
@@ -7017,7 +7027,7 @@ static void DrawPropertiesConfig()
       (!IS_CUSTOM_ELEMENT(properties_element) ||
        edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2))
   {
-    /* set position for special checkbutton for "can move into acid" */
+    /* set position for checkbutton for "can move into acid" */
     checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].y =
       ED_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 6 :
                       HAS_CONTENT(properties_element) ? 1 : 0);
@@ -7031,6 +7041,14 @@ static void DrawPropertiesConfig()
   if (properties_element == EL_SPRING)
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_SPRING_BUG);
 
+  if (CAN_GROW(properties_element))
+  {
+    checkbutton_info[ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE].y =
+      ED_SETTINGS_YPOS(HAS_CONTENT(properties_element) ? 1 : 0);
+
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE);
+  }
+
   if (IS_ENVELOPE(properties_element))
   {
     int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE;
index f44c2ca39afcff12d64029235bc0f65cfabff2d5..c07a04c5ce5873d51f17736e5bc6fec2972ce1db 100644 (file)
@@ -29,7 +29,7 @@
 #define CHUNK_SIZE_NONE                -1      /* do not write chunk size    */
 #define FILE_VERS_CHUNK_SIZE   8       /* size of file version chunk */
 #define LEVEL_HEADER_SIZE      80      /* size of level file header  */
-#define LEVEL_HEADER_UNUSED    2       /* unused level header bytes  */
+#define LEVEL_HEADER_UNUSED    1       /* unused level header bytes  */
 #define LEVEL_CHUNK_CNT2_SIZE  160     /* size of level CNT2 chunk   */
 #define LEVEL_CHUNK_CNT2_UNUSED        11      /* unused CNT2 chunk bytes    */
 #define LEVEL_CHUNK_CNT3_HEADER        16      /* size of level CNT3 header  */
@@ -163,6 +163,7 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
   level->sp_block_last_field = TRUE;
   level->instant_relocation = FALSE;
   level->can_pass_to_walkable = FALSE;
+  level->grow_into_diggable = TRUE;
 
   level->can_move_into_acid_bits = ~0; /* everything can move into acid */
   level->dont_collide_with_bits = ~0;  /* always deadly when colliding  */
@@ -705,6 +706,7 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level)
 
   level->instant_relocation    = (getFile8Bit(file) == 1 ? TRUE : FALSE);
   level->can_pass_to_walkable  = (getFile8Bit(file) == 1 ? TRUE : FALSE);
+  level->grow_into_diggable    = (getFile8Bit(file) == 1 ? TRUE : FALSE);
 
   ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED);
 
@@ -2444,6 +2446,7 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level)
 
   putFile8Bit(file, (level->instant_relocation ? 1 : 0));
   putFile8Bit(file, (level->can_pass_to_walkable ? 1 : 0));
+  putFile8Bit(file, (level->grow_into_diggable ? 1 : 0));
 
   WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED);
 }
index 05460294a81d05a35f0e58af40cb809d06c09333..b1254556955778c3d660d44bc45a19d023a1c171 100644 (file)
        ((e) == EL_TRIGGER_ELEMENT ? (ch)->actual_trigger_element :     \
         (e) == EL_TRIGGER_PLAYER  ? (ch)->actual_trigger_player : (e))
 
+#define CAN_GROW_INTO(e)                                               \
+       (e == EL_SAND || (IS_DIGGABLE(e) && level.grow_into_diggable))
+
 #define ELEMENT_CAN_ENTER_FIELD_BASE_X(x, y, condition)                        \
                (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) ||                \
                                        (condition)))
@@ -996,9 +999,10 @@ static inline void InitField_WithBug2(int x, int y, boolean init_game)
   /* this case is in fact a combination of not less than three bugs:
      first, it calls InitMovDir() for elements that can move, although this is
      already done by InitField(); then, it checks the element that was at this
-     field _before_ the call to InitField() (which can change it)
-
- */
+     field _before_ the call to InitField() (which can change it); lastly, it
+     was not called for "mole with direction" elements, which were treated as
+     "cannot move" due to (fixed) wrong element initialization in "src/init.c"
+  */
 }
 
 inline void DrawGameValue_Emeralds(int value)
@@ -3416,12 +3420,16 @@ void DynaExplode(int ex, int ey)
 
       Explode(x, y, EX_PHASE_START, EX_TYPE_BORDER);
 
+#if 1
+      if (element != EL_EMPTY && element != EL_EXPLOSION &&
+         !CAN_GROW_INTO(element) && !dynabomb_xl)
+       break;
+#else
       /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
-      if (element != EL_EMPTY &&
-         element != EL_SAND &&
-         element != EL_EXPLOSION &&
-         !dynabomb_xl)
+      if (element != EL_EMPTY && element != EL_EXPLOSION &&
+         element != EL_SAND && !dynabomb_xl)
        break;
+#endif
     }
   }
 }
@@ -6449,6 +6457,15 @@ void AmoebeAbleger(int ax, int ay)
     if (!IN_LEV_FIELD(x, y))
       return;
 
+#if 1
+    if (IS_FREE(x, y) ||
+       CAN_GROW_INTO(Feld[x][y]) ||
+       Feld[x][y] == EL_QUICKSAND_EMPTY)
+    {
+      newax = x;
+      neway = y;
+    }
+#else
     /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
     if (IS_FREE(x, y) ||
        Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY)
@@ -6456,6 +6473,7 @@ void AmoebeAbleger(int ax, int ay)
       newax = x;
       neway = y;
     }
+#endif
 
     if (newax == ax && neway == ay)
       return;
@@ -6474,6 +6492,16 @@ void AmoebeAbleger(int ax, int ay)
       if (!IN_LEV_FIELD(x, y))
        continue;
 
+#if 1
+      if (IS_FREE(x, y) ||
+         CAN_GROW_INTO(Feld[x][y]) ||
+         Feld[x][y] == EL_QUICKSAND_EMPTY)
+      {
+       newax = x;
+       neway = y;
+       break;
+      }
+#else
       /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
       if (IS_FREE(x, y) ||
          Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY)
@@ -6482,6 +6510,7 @@ void AmoebeAbleger(int ax, int ay)
        neway = y;
        break;
       }
+#endif
       else if (IS_PLAYER(x, y))
        waiting_for_player = TRUE;
     }
@@ -6619,6 +6648,20 @@ void Life(int ax, int ay)
        changed = TRUE;
       }
     }
+#if 1
+    else if (IS_FREE(xx, yy) || CAN_GROW_INTO(Feld[xx][yy]))
+    {                                  /* free border field */
+      if (nachbarn >= life[2] && nachbarn <= life[3])
+      {
+       Feld[xx][yy] = element;
+       MovDelay[xx][yy] = (element == EL_GAME_OF_LIFE ? 0 : life_time-1);
+       if (!Stop[xx][yy])
+         DrawLevelField(xx, yy);
+       Stop[xx][yy] = TRUE;
+       changed = TRUE;
+      }
+    }
+#else
     /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
     else if (IS_FREE(xx, yy) || Feld[xx][yy] == EL_SAND)
     {                                  /* free border field */
@@ -6632,6 +6675,7 @@ void Life(int ax, int ay)
        changed = TRUE;
       }
     }
+#endif
   }
 
   if (changed)
@@ -8315,6 +8359,21 @@ void GameActions()
 #endif
       element = Feld[x][y];
 
+#if 1
+      if (!IS_PLAYER(x,y) &&
+         (element == EL_EMPTY ||
+          CAN_GROW_INTO(element) ||
+          element == EL_QUICKSAND_EMPTY ||
+          element == EL_ACID_SPLASH_LEFT ||
+          element == EL_ACID_SPLASH_RIGHT))
+      {
+       if ((IN_LEV_FIELD(x, y-1) && Feld[x][y-1] == EL_AMOEBA_WET) ||
+           (IN_LEV_FIELD(x-1, y) && Feld[x-1][y] == EL_AMOEBA_WET) ||
+           (IN_LEV_FIELD(x+1, y) && Feld[x+1][y] == EL_AMOEBA_WET) ||
+           (IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET))
+         Feld[x][y] = EL_AMOEBA_DROP;
+      }
+#else
       /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
       if (!IS_PLAYER(x,y) &&
          (element == EL_EMPTY ||
@@ -8329,6 +8388,7 @@ void GameActions()
            (IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET))
          Feld[x][y] = EL_AMOEBA_DROP;
       }
+#endif
 
       random = random * 129 + 1;
     }
@@ -8702,6 +8762,7 @@ static void CheckGravityMovement(struct PlayerInfo *player)
     int move_dir_horizontal = player->action & MV_HORIZONTAL;
     int move_dir_vertical   = player->action & MV_VERTICAL;
 #endif
+
 #if 1
     boolean player_is_snapping = player->effective_action & JOY_BUTTON_1;
 #else
@@ -8746,6 +8807,7 @@ static void CheckGravityMovement(struct PlayerInfo *player)
       (IN_LEV_FIELD(jx, jy + 1) &&
        (IS_FREE(jx, jy + 1)));
 #endif
+
 #if 0
     boolean player_is_moving_to_valid_field =
       (
@@ -10380,12 +10442,12 @@ int DigField(struct PlayerInfo *player,
          return MF_NO_ACTION;  /* player cannot walk here due to gravity */
 #endif
 
-       if (element >= EL_GATE_1 && element <= EL_GATE_4)
+       if (IS_GATE(element))
        {
          if (!player->key[element - EL_GATE_1])
            return MF_NO_ACTION;
        }
-       else if (element >= EL_GATE_1_GRAY && element <= EL_GATE_4_GRAY)
+       else if (IS_GATE_GRAY(element))
        {
          if (!player->key[element - EL_GATE_1_GRAY])
            return MF_NO_ACTION;
@@ -11050,11 +11112,20 @@ boolean DropElement(struct PlayerInfo *player)
     Changed[jx][jy] = 0;               /* allow another change */
 #endif
 
+#if 1
+    /* !!! TEST ONLY !!! */
+    CheckElementChangePlayer(jx, jy, new_element, CE_DROPPED_BY_PLAYER,
+                            player->index_bit, drop_side);
+    CheckTriggeredElementChangePlayer(jx, jy, new_element,
+                                     CE_OTHER_GETS_DROPPED,
+                                     player->index_bit, drop_side);
+#else
     CheckTriggeredElementChangePlayer(jx, jy, new_element,
                                      CE_OTHER_GETS_DROPPED,
                                      player->index_bit, drop_side);
     CheckElementChangePlayer(jx, jy, new_element, CE_DROPPED_BY_PLAYER,
                             player->index_bit, drop_side);
+#endif
 
     TestIfElementTouchesCustomElement(jx, jy);
   }
index 3b04676d95dca1b85e0e939385a4c10a9108ee26..715a57fde04e3dfaf450288dce2bb90f048b5973 100644 (file)
@@ -1585,6 +1585,7 @@ static int get_special_property_bit(int element, int property_bit_nr)
     { EL_PLAYER_3,             0       },
     { EL_PLAYER_4,             0       },
     { EL_SP_MURPHY,            0       },
+    { EL_SOKOBAN_FIELD_PLAYER, 0       },
 
     /* all element that can move may be able to also move into acid */
     { EL_BUG,                  1       },
@@ -1733,6 +1734,7 @@ void InitElementPropertiesStatic()
     EL_INVISIBLE_SAND_ACTIVE,
 
     /* !!! currently not diggable, but handled by 'ep_dont_run_into' !!! */
+    /* (if amoeba can grow into anything diggable, maybe keep these out) */
 #if 0
     EL_LANDMINE,
     EL_TRAP_ACTIVE,
@@ -2261,6 +2263,7 @@ void InitElementPropertiesStatic()
     EL_PLAYER_3,
     EL_PLAYER_4,
     EL_SP_MURPHY,
+    EL_SOKOBAN_FIELD_PLAYER,
     -1
   };
 
@@ -2322,6 +2325,9 @@ void InitElementPropertiesStatic()
     EL_EXIT_OPEN,
     EL_STEELWALL,
     EL_PLAYER_1,
+    EL_PLAYER_2,
+    EL_PLAYER_3,
+    EL_PLAYER_4,
     EL_BD_FIREFLY,
     EL_BD_FIREFLY_1,
     EL_BD_FIREFLY_2,
@@ -2405,7 +2411,11 @@ void InitElementPropertiesStatic()
     EL_SOKOBAN_OBJECT,
     EL_SOKOBAN_FIELD_EMPTY,
     EL_SOKOBAN_FIELD_FULL,
+    EL_SOKOBAN_FIELD_PLAYER,
     EL_PLAYER_1,
+    EL_PLAYER_2,
+    EL_PLAYER_3,
+    EL_PLAYER_4,
     EL_INVISIBLE_STEELWALL,
     -1
   };
@@ -2836,6 +2846,18 @@ void InitElementPropertiesStatic()
     -1
   };
 
+  static int ep_can_grow[] =
+  {
+    EL_BD_AMOEBA,
+    EL_AMOEBA_DROP,
+    EL_AMOEBA_WET,
+    EL_AMOEBA_DRY,
+    EL_AMOEBA_FULL,
+    EL_GAME_OF_LIFE,
+    EL_BIOMAZE,
+    -1
+  };
+
   static int ep_active_bomb[] =
   {
     EL_DYNAMITE_ACTIVE,
@@ -3057,6 +3079,7 @@ void InitElementPropertiesStatic()
     { ep_amoebalive,           EP_AMOEBALIVE           },
     { ep_has_content,          EP_HAS_CONTENT          },
     { ep_can_turn_each_move,   EP_CAN_TURN_EACH_MOVE   },
+    { ep_can_grow,             EP_CAN_GROW             },
     { ep_active_bomb,          EP_ACTIVE_BOMB          },
     { ep_inactive,             EP_INACTIVE             },
 
index c58dbfbe8ecc81897578a1f1ff66035bd4c78818..b125603a7b995fbe711752c20ea1bd29046c532c 100644 (file)
 #define EP_AMOEBALIVE          51
 #define EP_HAS_CONTENT         52
 #define EP_CAN_TURN_EACH_MOVE  53
-#define EP_ACTIVE_BOMB         54
-#define EP_INACTIVE            55
+#define EP_CAN_GROW            54
+#define EP_ACTIVE_BOMB         55
+#define EP_INACTIVE            56
 
 /* values for special configurable properties (depending on level settings) */
-#define EP_EM_SLIPPERY_WALL    56
+#define EP_EM_SLIPPERY_WALL    57
 
 /* values for special graphics properties (no effect on game engine) */
-#define EP_GFX_CRUMBLED                57
+#define EP_GFX_CRUMBLED                58
 
 /* values for derived properties (determined from properties above) */
-#define EP_ACCESSIBLE_OVER     58
-#define EP_ACCESSIBLE_INSIDE   59
-#define EP_ACCESSIBLE_UNDER    60
-#define EP_WALKABLE            61
-#define EP_PASSABLE            62
-#define EP_ACCESSIBLE          63
-#define EP_COLLECTIBLE         64
-#define EP_SNAPPABLE           65
-#define EP_WALL                        66
-#define EP_SOLID_FOR_PUSHING   67
-#define EP_DRAGONFIRE_PROOF    68
-#define EP_EXPLOSION_PROOF     69
-#define EP_CAN_SMASH           70
-#define EP_CAN_EXPLODE         71
-#define EP_CAN_EXPLODE_3X3     72
-#define EP_SP_PORT             73
-#define EP_CAN_EXPLODE_BY_DRAGONFIRE   74
-#define EP_CAN_EXPLODE_BY_EXPLOSION    75
-#define EP_COULD_MOVE_INTO_ACID                76
-#define EP_MAYBE_DONT_COLLIDE_WITH     77
+#define EP_ACCESSIBLE_OVER     59
+#define EP_ACCESSIBLE_INSIDE   60
+#define EP_ACCESSIBLE_UNDER    61
+#define EP_WALKABLE            62
+#define EP_PASSABLE            63
+#define EP_ACCESSIBLE          64
+#define EP_COLLECTIBLE         65
+#define EP_SNAPPABLE           66
+#define EP_WALL                        67
+#define EP_SOLID_FOR_PUSHING   68
+#define EP_DRAGONFIRE_PROOF    69
+#define EP_EXPLOSION_PROOF     70
+#define EP_CAN_SMASH           71
+#define EP_CAN_EXPLODE         72
+#define EP_CAN_EXPLODE_3X3     73
+#define EP_SP_PORT             74
+#define EP_CAN_EXPLODE_BY_DRAGONFIRE   75
+#define EP_CAN_EXPLODE_BY_EXPLOSION    76
+#define EP_COULD_MOVE_INTO_ACID                77
+#define EP_MAYBE_DONT_COLLIDE_WITH     78
 
 /* values for internal purpose only (level editor) */
-#define EP_EXPLODE_RESULT      78
-#define EP_WALK_TO_OBJECT      79
-#define EP_DEADLY              80
+#define EP_EXPLODE_RESULT      79
+#define EP_WALK_TO_OBJECT      80
+#define EP_DEADLY              81
 
-#define NUM_ELEMENT_PROPERTIES 81
+#define NUM_ELEMENT_PROPERTIES 82
 
 #define NUM_EP_BITFIELDS       ((NUM_ELEMENT_PROPERTIES + 31) / 32)
 #define EP_BITFIELD_BASE       0
 #define IS_AMOEBALIVE(e)       HAS_PROPERTY(e, EP_AMOEBALIVE)
 #define HAS_CONTENT(e)         HAS_PROPERTY(e, EP_HAS_CONTENT)
 #define CAN_TURN_EACH_MOVE(e)  HAS_PROPERTY(e, EP_CAN_TURN_EACH_MOVE)
+#define CAN_GROW(e)            HAS_PROPERTY(e, EP_CAN_GROW)
 #define IS_ACTIVE_BOMB(e)      HAS_PROPERTY(e, EP_ACTIVE_BOMB)
 #define IS_INACTIVE(e)         HAS_PROPERTY(e, EP_INACTIVE)
 
 #define IS_ENVELOPE(e)         ((e) >= EL_ENVELOPE_1 &&                \
                                 (e) <= EL_ENVELOPE_4)
 
+#define IS_GATE(e)             ((e) >= EL_GATE_1 &&                    \
+                                (e) <= EL_GATE_4)
+
+#define IS_GATE_GRAY(e)                ((e) >= EL_GATE_1_GRAY &&               \
+                                (e) <= EL_GATE_4_GRAY)
+
 #define IS_EM_GATE(e)          ((e) >= EL_EM_GATE_1 &&                 \
                                 (e) <= EL_EM_GATE_4)
 
@@ -1461,6 +1469,7 @@ struct LevelInfo
   boolean use_spring_bug;      /* for compatibility with old levels */
   boolean instant_relocation;  /* no visual delay when relocating player */
   boolean can_pass_to_walkable;        /* player can pass to empty or walkable tile */
+  boolean grow_into_diggable;  /* amoeba can grow into anything diggable */
 
   /* ('int' instead of 'boolean' because used as selectbox value in editor) */
   int use_step_counter;                /* count steps instead of seconds for level */