rnd-20040424-1-src
[rocksndiamonds.git] / src / editor.c
index 97904719c9a2df1d74229853f6a667a834835a0e..c4392072282e37d0f8eec97c5b231a9dd7233ccd 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
@@ -1219,6 +1221,7 @@ static struct ValueTextInfo options_walk_to_action[] =
   { EP_DIGGABLE,               "diggable"                      },
   { EP_COLLECTIBLE_ONLY,       "collectible"                   },
   { EP_DROPPABLE,              "collectible & droppable"       },
+  { EP_THROWABLE,              "collectible & throwable"       },
   { EP_PUSHABLE,               "pushable"                      },
 
   { -1,                                NULL                            }
@@ -1242,10 +1245,10 @@ static struct ValueTextInfo options_move_pattern[] =
   { MV_TURNING_LEFT_RIGHT,     "turning left, right"           },
   { MV_TURNING_RIGHT_LEFT,     "turning right, left"           },
   { MV_TURNING_RANDOM,         "turning random"                },
-  { MV_WHEN_PUSHED,            "when pushed"                   },
-  { MV_WHEN_DROPPED,           "when dropped"                  },
   { MV_MAZE_RUNNER,            "maze runner style"             },
   { MV_MAZE_HUNTER,            "maze hunter style"             },
+  { MV_WHEN_PUSHED,            "when pushed"                   },
+  { MV_WHEN_DROPPED,           "when dropped/thrown"           },
 
   { -1,                                NULL                            }
 };
@@ -1336,18 +1339,21 @@ static struct ValueTextInfo options_time_units[] =
 
 static struct ValueTextInfo options_change_direct_action[] =
 {
-  { CE_TOUCHED_BY_PLAYER,      "touched by player ..."         },
-  { CE_PRESSED_BY_PLAYER,      "pressed by player ..."         },
-  { CE_PUSHED_BY_PLAYER,       "pushed by player ..."          },
-  { CE_ENTERED_BY_PLAYER,      "entered by player ..."         },
-  { CE_LEFT_BY_PLAYER,         "left by player ..."            },
-  { CE_DROPPED_BY_PLAYER,      "dropped by player"             },
-  { CE_SWITCHED,               "switched ..."                  },
+  { CE_TOUCHED_BY_PLAYER,      "touched by player"             },
+  { CE_PRESSED_BY_PLAYER,      "pressed by player"             },
+  { CE_PUSHED_BY_PLAYER,       "pushed by player"              },
+  { CE_ENTERED_BY_PLAYER,      "entered by player"             },
+  { CE_LEFT_BY_PLAYER,         "left by player"                },
+  { CE_DROPPED_BY_PLAYER,      "dropped/thrown by player"      },
+  { CE_SWITCHED,               "switched"                      },
 #if 1
-  { CE_HITTING_SOMETHING,      "hitting something ..."         },
-  { CE_HIT_BY_SOMETHING,       "hit by something ..."          },
+  { CE_HITTING_SOMETHING,      "hitting something"             },
+  { CE_HIT_BY_SOMETHING,       "hit by something"              },
 #else
-  { CE_HITTING_SOMETHING,      "collision ..."                 },
+  { CE_HITTING_SOMETHING,      "collision"                     },
+#endif
+#if 1
+  { CE_BLOCKED,                        "blocked"                       },
 #endif
   { CE_IMPACT,                 "impact (on something)"         },
   { CE_SMASHED,                        "smashed (from above)"          },
@@ -1357,20 +1363,20 @@ static struct ValueTextInfo options_change_direct_action[] =
 
 static struct ValueTextInfo options_change_other_action[] =
 {
-  { CE_OTHER_GETS_TOUCHED,     "player touches ..."            },
-  { CE_OTHER_GETS_PRESSED,     "player presses ..."            },
-  { CE_OTHER_GETS_PUSHED,      "player pushes ..."             },
-  { CE_OTHER_GETS_ENTERED,     "player enters ..."             },
-  { CE_OTHER_GETS_LEFT,                "player leaves ..."             },
+  { CE_OTHER_GETS_TOUCHED,     "player touches"                },
+  { CE_OTHER_GETS_PRESSED,     "player presses"                },
+  { CE_OTHER_GETS_PUSHED,      "player pushes"                 },
+  { CE_OTHER_GETS_ENTERED,     "player enters"                 },
+  { CE_OTHER_GETS_LEFT,                "player leaves"                 },
   { CE_OTHER_GETS_DIGGED,      "player digs"                   },
   { CE_OTHER_GETS_COLLECTED,   "player collects"               },
-  { CE_OTHER_GETS_DROPPED,     "player drops"                  },
-  { CE_OTHER_IS_TOUCHING,      "touching ..."                  },
+  { CE_OTHER_GETS_DROPPED,     "player drops/throws"           },
+  { CE_OTHER_IS_TOUCHING,      "touching"                      },
 #if 1
-  { CE_OTHER_IS_HITTING,       "hitting ..."                   },
-  { CE_OTHER_GETS_HIT,         "hit by ..."                    },
+  { CE_OTHER_IS_HITTING,       "hitting"                       },
+  { CE_OTHER_GETS_HIT,         "hit by"                        },
 #endif
-  { CE_OTHER_IS_SWITCHING,     "switch of ..."                 },
+  { CE_OTHER_IS_SWITCHING,     "switch of"                     },
   { CE_OTHER_IS_CHANGING,      "change by page of"             },
   { CE_OTHER_IS_EXPLODING,     "explosion of"                  },
 
@@ -1443,7 +1449,10 @@ static struct ValueTextInfo options_change_trigger_page[] =
 static struct ValueTextInfo options_change_replace_when[] =
 {
   { CP_WHEN_EMPTY,             "empty"                         },
+  { CP_WHEN_WALKABLE,          "walkable"                      },
   { CP_WHEN_DIGGABLE,          "diggable"                      },
+  { CP_WHEN_COLLECTIBLE,       "collectible"                   },
+  { CP_WHEN_REMOVABLE,         "removable"                     },
   { CP_WHEN_DESTRUCTIBLE,      "destructible"                  },
 
   { -1,                                NULL                            }
@@ -1630,7 +1639,7 @@ static struct
     -1,
     options_change_trigger_side,
     &custom_element_change.trigger_side,
-    "... at", "side",                  "element side that causes change"
+    "at", "side",                      "element side that causes change"
   },
   {
     ED_SETTINGS_XPOS(2),               ED_SETTINGS_YPOS(7),
@@ -1961,6 +1970,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 +2235,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 +5335,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;
 
@@ -5798,12 +5813,14 @@ static void CopyCustomElementPropertiesToEditor(int element)
     (IS_DIGGABLE(element) ? EP_DIGGABLE :
      IS_COLLECTIBLE_ONLY(element) ? EP_COLLECTIBLE_ONLY :
      IS_DROPPABLE(element) ? EP_DROPPABLE :
+     IS_THROWABLE(element) ? EP_THROWABLE :
      IS_PUSHABLE(element) ? EP_PUSHABLE :
      custom_element.walk_to_action);
   custom_element_properties[EP_WALK_TO_OBJECT] =
     (IS_DIGGABLE(element) ||
      IS_COLLECTIBLE_ONLY(element) ||
      IS_DROPPABLE(element) ||
+     IS_THROWABLE(element) ||
      IS_PUSHABLE(element));
 
   /* set smash targets selectbox help value */
@@ -5842,12 +5859,18 @@ static void CopyCustomElementPropertiesToEditor(int element)
      CAN_EXPLODE_CROSS(element));
 
   /* special case: sub-settings dependent from main setting */
+#if 0
+  custom_element.can_explode_by_fire = CAN_EXPLODE_BY_FIRE(element);
+  custom_element.can_explode_smashed = CAN_EXPLODE_SMASHED(element);
+  custom_element.can_explode_impact  = CAN_EXPLODE_IMPACT(element);
+#else
   if (CAN_EXPLODE_BY_FIRE(element))
     custom_element.can_explode_by_fire = TRUE;
   if (CAN_EXPLODE_SMASHED(element))
     custom_element.can_explode_smashed = TRUE;
   if (CAN_EXPLODE_IMPACT(element))
     custom_element.can_explode_impact  = TRUE;
+#endif
 
   /* ---------- element settings: advanced (custom elements) --------------- */
 
@@ -5862,6 +5885,7 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_SWITCHED) ? CE_SWITCHED :
      HAS_CHANGE_EVENT(element, CE_HITTING_SOMETHING) ? CE_HITTING_SOMETHING :
      HAS_CHANGE_EVENT(element, CE_HIT_BY_SOMETHING) ? CE_HIT_BY_SOMETHING :
+     HAS_CHANGE_EVENT(element, CE_BLOCKED) ? CE_BLOCKED :
      HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT :
      HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED :
      custom_element_change.direct_action);
@@ -5928,6 +5952,7 @@ static void CopyCustomElementPropertiesToGame(int element)
 {
   int i;
   int access_type_and_layer;
+  boolean can_explode;
 
   /* mark that this custom element has been modified */
   custom_element.modified_settings = TRUE;
@@ -5973,6 +5998,7 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_properties[EP_DIGGABLE] = FALSE;
   custom_element_properties[EP_COLLECTIBLE_ONLY] = FALSE;
   custom_element_properties[EP_DROPPABLE] = FALSE;
+  custom_element_properties[EP_THROWABLE] = FALSE;
   custom_element_properties[EP_PUSHABLE] = FALSE;
   custom_element_properties[custom_element.walk_to_action] =
     custom_element_properties[EP_WALK_TO_OBJECT];
@@ -6003,6 +6029,17 @@ static void CopyCustomElementPropertiesToGame(int element)
     custom_element_properties[EP_EXPLODE_RESULT];
 
   /* special case: sub-settings dependent from main setting */
+#if 0
+  can_explode = (custom_element_properties[EP_CAN_EXPLODE_1X1] ||
+                custom_element_properties[EP_CAN_EXPLODE_3X3] ||
+                custom_element_properties[EP_CAN_EXPLODE_CROSS]);
+  custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] =
+    (can_explode && custom_element.can_explode_by_fire);
+  custom_element_properties[EP_CAN_EXPLODE_SMASHED] =
+    (can_explode && custom_element.can_explode_smashed);
+  custom_element_properties[EP_CAN_EXPLODE_IMPACT] =
+    (can_explode && custom_element.can_explode_impact);
+#else
   if (custom_element_properties[EP_CAN_EXPLODE_1X1] ||
       custom_element_properties[EP_CAN_EXPLODE_3X3] ||
       custom_element_properties[EP_CAN_EXPLODE_CROSS])
@@ -6014,6 +6051,7 @@ static void CopyCustomElementPropertiesToGame(int element)
     custom_element_properties[EP_CAN_EXPLODE_IMPACT] =
       custom_element.can_explode_impact;
   }
+#endif
 
   /* ---------- element settings: advanced (custom elements) --------------- */
 
@@ -6027,6 +6065,7 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_SWITCHED] = FALSE;
   custom_element_change_events[CE_HITTING_SOMETHING] = FALSE;
   custom_element_change_events[CE_HIT_BY_SOMETHING] = FALSE;
+  custom_element_change_events[CE_BLOCKED] = FALSE;
   custom_element_change_events[CE_IMPACT] = FALSE;
   custom_element_change_events[CE_SMASHED] = FALSE;
   custom_element_change_events[custom_element_change.direct_action] =
@@ -6148,7 +6187,7 @@ void DrawLevelEd()
 
   redraw_mask |= REDRAW_ALL;
 
-  ReinitializeElementListButtons();    /* only needed after setup changes */
+  ReinitializeElementListButtons();    /* custom element may look different */
 #if 0
   ModifyEditorElementList();           /* may be needed for custom elements */
 #endif
@@ -6740,14 +6779,16 @@ static void DrawPropertiesInfo()
     { EP_PASSABLE_OVER,                "- player can pass over it"             },
     { EP_PASSABLE_INSIDE,      "- player can pass through it"          },
     { EP_PASSABLE_UNDER,       "- player can pass under it"            },
+    { EP_PROTECTED,            "- player is protected by it"           },
 
     { EP_DIGGABLE,             "- can be digged away"                  },
     { EP_COLLECTIBLE,          "- can be collected"                    },
     { EP_DROPPABLE,            "- can be dropped after collecting"     },
+    { EP_THROWABLE,            "- can be thrown after collecting"      },
     { EP_PUSHABLE,             "- can be pushed"                       },
 
-    { EP_CAN_MOVE,             "- can move"                            },
     { EP_CAN_FALL,             "- can fall"                            },
+    { EP_CAN_MOVE,             "- can move"                            },
 
     { EP_CAN_SMASH_PLAYER,     "- can smash player"                    },
 #if 0
@@ -6755,7 +6796,7 @@ static void DrawPropertiesInfo()
 #endif
     { EP_CAN_SMASH_EVERYTHING, "- can smash everything smashable"      },
 
-    { EP_SLIPPERY,             "- slippery for falling objects"        },
+    { EP_SLIPPERY,             "- slippery for falling elements"       },
     { EP_EM_SLIPPERY_WALL,     "- slippery for some gems (EM style)"   },
 
     { EP_DONT_RUN_INTO,                "- deadly when running into"            },
@@ -6772,6 +6813,7 @@ static void DrawPropertiesInfo()
 
     /* pre-defined properties */
     { EP_CAN_PASS_MAGIC_WALL,  "- can pass magic walls"                },
+    { EP_SWITCHABLE,           "- can be switched"                     },
     { EP_HAS_CONTENT,          "- can contain other elements"          },
 
     { -1,                      NULL                                    }
@@ -6945,6 +6987,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 +7019,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 +7061,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 +7075,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;