rnd-20030429-1-src
[rocksndiamonds.git] / src / editor.c
index 4707b4ff1264b4137867189dd452310e047212a1..3f1f49098d7d62bdb91d4409d2597ad543005932 100644 (file)
@@ -75,7 +75,7 @@
 
 /* values for counter gadgets */
 #define ED_COUNT_ELEM_SCORE_XPOS       ED_SETTINGS_XPOS
-#define ED_COUNT_ELEM_SCORE_YPOS       (14 * MINI_TILEY)
+#define ED_COUNT_ELEM_SCORE_YPOS       (11 * MINI_TILEY)
 #define ED_COUNT_ELEM_CONTENT_XPOS     ED_SETTINGS_XPOS
 #define ED_COUNT_ELEM_CONTENT_YPOS     (19 * MINI_TILEY)
 
 #define GADGET_ID_STICK_ELEMENT                (GADGET_ID_CHECKBUTTON_FIRST + 5)
 #define GADGET_ID_EM_SLIPPERY_GEMS     (GADGET_ID_CHECKBUTTON_FIRST + 6)
 #define GADGET_ID_CUSTOM_INDESTRUCTIBLE        (GADGET_ID_CHECKBUTTON_FIRST + 7)
-#define GADGET_ID_CUSTOM_CAN_FALL      (GADGET_ID_CHECKBUTTON_FIRST + 8)
-#define GADGET_ID_CUSTOM_CAN_SMASH     (GADGET_ID_CHECKBUTTON_FIRST + 9)
+#define GADGET_ID_CUSTOM_DIGGABLE      (GADGET_ID_CHECKBUTTON_FIRST + 8)
+#define GADGET_ID_CUSTOM_COLLECTIBLE   (GADGET_ID_CHECKBUTTON_FIRST + 9)
 #define GADGET_ID_CUSTOM_PUSHABLE      (GADGET_ID_CHECKBUTTON_FIRST + 10)
-#define GADGET_ID_CUSTOM_SLIPPERY      (GADGET_ID_CHECKBUTTON_FIRST + 11)
+#define GADGET_ID_CUSTOM_CAN_FALL      (GADGET_ID_CHECKBUTTON_FIRST + 11)
+#define GADGET_ID_CUSTOM_CAN_SMASH     (GADGET_ID_CHECKBUTTON_FIRST + 12)
+#define GADGET_ID_CUSTOM_CAN_MOVE      (GADGET_ID_CHECKBUTTON_FIRST + 13)
+#define GADGET_ID_CUSTOM_SLIPPERY      (GADGET_ID_CHECKBUTTON_FIRST + 14)
+#define GADGET_ID_CUSTOM_WALKABLE_OVER (GADGET_ID_CHECKBUTTON_FIRST + 15)
+#define GADGET_ID_CUSTOM_WALKABLE_INSIDE (GADGET_ID_CHECKBUTTON_FIRST+ 16)
+#define GADGET_ID_CUSTOM_WALKABLE_UNDER        (GADGET_ID_CHECKBUTTON_FIRST + 17)
 
 /* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 12)
+#define GADGET_ID_ELEMENTLIST_FIRST    (GADGET_ID_CHECKBUTTON_FIRST + 18)
 #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_CUSTOM_INDESTRUCTIBLE        5
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL      6
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH     7
+#define ED_CHECKBUTTON_ID_CUSTOM_DIGGABLE      6
+#define ED_CHECKBUTTON_ID_CUSTOM_COLLECTIBLE   7
 #define ED_CHECKBUTTON_ID_CUSTOM_PUSHABLE      8
-#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      9
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL      9
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH     10
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE      11
+#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY      12
+#define ED_CHECKBUTTON_ID_CUSTOM_WALKABLE_OVER 13
+#define ED_CHECKBUTTON_ID_CUSTOM_WALKABLE_INSIDE 14
+#define ED_CHECKBUTTON_ID_CUSTOM_WALKABLE_UNDER        15
 
-#define ED_NUM_CHECKBUTTONS                    10
+#define ED_NUM_CHECKBUTTONS                    16
 
 #define ED_CHECKBUTTON_ID_LEVEL_FIRST  ED_CHECKBUTTON_ID_DOUBLE_SPEED
 #define ED_CHECKBUTTON_ID_LEVEL_LAST   ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
 
 #define ED_CHECKBUTTON_ID_CUSTOM_FIRST ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE
-#define ED_CHECKBUTTON_ID_CUSTOM_LAST  ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY
+#define ED_CHECKBUTTON_ID_CUSTOM_LAST  ED_CHECKBUTTON_ID_CUSTOM_WALKABLE_UNDER
 
 /* values for radiobutton gadgets */
 #define ED_RADIOBUTTON_ID_PERCENTAGE   0
@@ -530,15 +542,7 @@ static int random_placement_method = RANDOM_USE_QUANTITY;
 static int random_placement_background_element = EL_SAND;
 static boolean random_placement_background_restricted = FALSE;
 static boolean stick_element_properties_window = FALSE;
-
-static struct
-{
-  boolean indestructible;
-  boolean can_fall;
-  boolean can_smash;
-  boolean pushable;
-  boolean slippery;
-} custom_element_properties[NUM_CUSTOM_ELEMENTS];
+static boolean custom_element_properties[NUM_ELEMENT_PROPERTIES];
 
 static struct
 {
@@ -603,7 +607,7 @@ static struct
     0,                                 255,
     GADGET_ID_LEVEL_TIMESCORE_DOWN,    GADGET_ID_LEVEL_TIMESCORE_UP,
     GADGET_ID_LEVEL_TIMESCORE_TEXT,
-    &level.score[SC_ZEITBONUS],
+    &level.score[SC_TIME_BONUS],
     "score for each 10 seconds left",  NULL
   },
   {
@@ -855,34 +859,70 @@ static struct
     "slip down from certain flat walls","use EM style slipping behaviour"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(10),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(5),
     GADGET_ID_CUSTOM_INDESTRUCTIBLE,
-    &custom_element_properties[0].indestructible,
+    &custom_element_properties[EP_INDESTRUCTIBLE],
     "indestructible",                  "element cannot be destroyed"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(11),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(6),
+    GADGET_ID_CUSTOM_DIGGABLE,
+    &custom_element_properties[EP_DIGGABLE],
+    "diggable",                                "element can be digged away"
+  },
+  {
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(7),
+    GADGET_ID_CUSTOM_COLLECTIBLE,
+    &custom_element_properties[EP_COLLECTIBLE],
+    "collectible",                     "element can be collected"
+  },
+  {
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(8),
+    GADGET_ID_CUSTOM_PUSHABLE,
+    &custom_element_properties[EP_PUSHABLE],
+    "pushable",                                "element can be pushed"
+  },
+  {
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(9),
     GADGET_ID_CUSTOM_CAN_FALL,
-    &custom_element_properties[0].can_fall,
+    &custom_element_properties[EP_CAN_FALL],
     "can fall",                                "element can fall down"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(12),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(10),
     GADGET_ID_CUSTOM_CAN_SMASH,
-    &custom_element_properties[0].can_smash,
+    &custom_element_properties[EP_CAN_SMASH],
     "can smash",                       "element can smash other elements"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(13),
-    GADGET_ID_CUSTOM_PUSHABLE,
-    &custom_element_properties[0].pushable,
-    "pushable",                                "element can be pushed"
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(11),
+    GADGET_ID_CUSTOM_CAN_MOVE,
+    &custom_element_properties[EP_CAN_MOVE],
+    "can move",                                "element can move in some direction"
   },
   {
-    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(14),
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(12),
     GADGET_ID_CUSTOM_SLIPPERY,
-    &custom_element_properties[0].slippery,
+    &custom_element_properties[EP_SLIPPERY],
     "slippery",                                "other elements can fall down from it"
+  },
+  {
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(13),
+    GADGET_ID_CUSTOM_WALKABLE_OVER,
+    &custom_element_properties[EP_WALKABLE_OVER],
+    "player can walk over",            "player can walk over this element"
+  },
+  {
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(14),
+    GADGET_ID_CUSTOM_WALKABLE_INSIDE,
+    &custom_element_properties[EP_WALKABLE_INSIDE],
+    "player can walk inside",          "player can walk inside this element"
+  },
+  {
+    ED_SETTINGS_XPOS,                  ED_COUNTER_YPOS2(15),
+    GADGET_ID_CUSTOM_WALKABLE_UNDER,
+    &custom_element_properties[EP_WALKABLE_UNDER],
+    "player can walk under",           "player can walk under this element"
   }
 };
 
@@ -2615,7 +2655,7 @@ void CreateLevelEditorGadgets()
   int old_game_status = game_status;
 
   /* setting 'game_status' is needed to get the right fonts for the editor */
-  game_status = LEVELED;
+  game_status = GAME_MODE_EDITOR;
 
   ReinitializeElementList();
 
@@ -2808,67 +2848,20 @@ static void CopyPlayfield(short src[MAX_LEV_FIELDX][MAX_LEV_FIELDY],
       dst[x][y] = src[x][y];
 }
 
-static void CopyCustomElementPropertiesToEditor()
+static void CopyCustomElementPropertiesToEditor(int element)
 {
   int i;
 
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
-  {
-    int element = EL_CUSTOM_START + i;
-    int properties = Properties1[element];
-
-    custom_element_properties[i].indestructible =
-      ((properties & EP_BIT_INDESTRUCTIBLE) != 0 ? TRUE : FALSE);
-
-    custom_element_properties[i].can_fall =
-      ((properties & EP_BIT_CAN_FALL) != 0 ? TRUE : FALSE);
-
-    custom_element_properties[i].can_smash =
-      ((properties & EP_BIT_CAN_SMASH) != 0 ? TRUE : FALSE);
-
-    custom_element_properties[i].pushable =
-      ((properties & EP_BIT_PUSHABLE) != 0 ? TRUE : FALSE);
-
-    custom_element_properties[i].slippery =
-      ((properties & EP_BIT_SLIPPERY) != 0 ? TRUE : FALSE);
-  }
+  for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+    custom_element_properties[i] = HAS_PROPERTY(element, i);
 }
 
-static void CopyCustomElementPropertiesToGame()
+static void CopyCustomElementPropertiesToGame(int element)
 {
   int i;
 
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
-  {
-    int element = EL_CUSTOM_START + i;
-
-    Properties1[element] = EP_BITMASK_DEFAULT;
-
-    if (custom_element_properties[i].indestructible)
-      Properties1[element] |= EP_BIT_INDESTRUCTIBLE;
-    else
-      Properties1[element] &= ~EP_BIT_INDESTRUCTIBLE;
-
-    if (custom_element_properties[i].can_fall)
-      Properties1[element] |= EP_BIT_CAN_FALL;
-    else
-      Properties1[element] &= ~EP_BIT_CAN_FALL;
-
-    if (custom_element_properties[i].can_smash)
-      Properties1[element] |= EP_BIT_CAN_SMASH;
-    else
-      Properties1[element] &= ~EP_BIT_CAN_SMASH;
-
-    if (custom_element_properties[i].pushable)
-      Properties1[element] |= EP_BIT_PUSHABLE;
-    else
-      Properties1[element] &= ~EP_BIT_PUSHABLE;
-
-    if (custom_element_properties[i].slippery)
-      Properties1[element] |= EP_BIT_SLIPPERY;
-    else
-      Properties1[element] &= ~EP_BIT_SLIPPERY;
-  }
+  for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+    SET_PROPERTY(element, i, custom_element_properties[i]);
 }
 
 void DrawLevelEd()
@@ -3351,45 +3344,45 @@ static struct
   char *text;
 } elements_with_counter[] =
 {
-  { EL_EMERALD,                &level.score[SC_EDELSTEIN],     TEXT_COLLECTING },
-  { EL_BD_DIAMOND,     &level.score[SC_EDELSTEIN],     TEXT_COLLECTING },
-  { EL_EMERALD_YELLOW, &level.score[SC_EDELSTEIN],     TEXT_COLLECTING },
-  { EL_EMERALD_RED,    &level.score[SC_EDELSTEIN],     TEXT_COLLECTING },
-  { EL_EMERALD_PURPLE, &level.score[SC_EDELSTEIN],     TEXT_COLLECTING },
-  { EL_DIAMOND,                &level.score[SC_DIAMANT],       TEXT_COLLECTING },
-  { EL_BUG_RIGHT,      &level.score[SC_KAEFER],        TEXT_SMASHING   },
-  { EL_BUG_UP,         &level.score[SC_KAEFER],        TEXT_SMASHING   },
-  { EL_BUG_LEFT,       &level.score[SC_KAEFER],        TEXT_SMASHING   },
-  { EL_BUG_DOWN,       &level.score[SC_KAEFER],        TEXT_SMASHING   },
-  { EL_BD_BUTTERFLY_RIGHT,&level.score[SC_KAEFER],     TEXT_SMASHING   },
-  { EL_BD_BUTTERFLY_UP,   &level.score[SC_KAEFER],     TEXT_SMASHING   },
-  { EL_BD_BUTTERFLY_LEFT, &level.score[SC_KAEFER],     TEXT_SMASHING   },
-  { EL_BD_BUTTERFLY_DOWN, &level.score[SC_KAEFER],     TEXT_SMASHING   },
-  { EL_SPACESHIP_RIGHT,        &level.score[SC_FLIEGER],       TEXT_SMASHING   },
-  { EL_SPACESHIP_UP,   &level.score[SC_FLIEGER],       TEXT_SMASHING   },
-  { EL_SPACESHIP_LEFT, &level.score[SC_FLIEGER],       TEXT_SMASHING   },
-  { EL_SPACESHIP_DOWN, &level.score[SC_FLIEGER],       TEXT_SMASHING   },
-  { EL_BD_FIREFLY_RIGHT,&level.score[SC_FLIEGER],      TEXT_SMASHING   },
-  { EL_BD_FIREFLY_UP,  &level.score[SC_FLIEGER],       TEXT_SMASHING   },
-  { EL_BD_FIREFLY_LEFT, &level.score[SC_FLIEGER],      TEXT_SMASHING   },
-  { EL_BD_FIREFLY_DOWN, &level.score[SC_FLIEGER],      TEXT_SMASHING   },
-  { EL_YAMYAM,         &level.score[SC_MAMPFER],       TEXT_SMASHING   },
-  { EL_DARK_YAMYAM,    &level.score[SC_MAMPFER],       TEXT_SMASHING   },
+  { EL_EMERALD,                &level.score[SC_EMERALD],       TEXT_COLLECTING },
+  { EL_BD_DIAMOND,     &level.score[SC_EMERALD],       TEXT_COLLECTING },
+  { EL_EMERALD_YELLOW, &level.score[SC_EMERALD],       TEXT_COLLECTING },
+  { EL_EMERALD_RED,    &level.score[SC_EMERALD],       TEXT_COLLECTING },
+  { EL_EMERALD_PURPLE, &level.score[SC_EMERALD],       TEXT_COLLECTING },
+  { EL_DIAMOND,                &level.score[SC_DIAMOND],       TEXT_COLLECTING },
+  { EL_BUG_RIGHT,      &level.score[SC_BUG],           TEXT_SMASHING   },
+  { EL_BUG_UP,         &level.score[SC_BUG],           TEXT_SMASHING   },
+  { EL_BUG_LEFT,       &level.score[SC_BUG],           TEXT_SMASHING   },
+  { EL_BUG_DOWN,       &level.score[SC_BUG],           TEXT_SMASHING   },
+  { EL_BD_BUTTERFLY_RIGHT,&level.score[SC_BUG],                TEXT_SMASHING   },
+  { EL_BD_BUTTERFLY_UP,   &level.score[SC_BUG],                TEXT_SMASHING   },
+  { EL_BD_BUTTERFLY_LEFT, &level.score[SC_BUG],                TEXT_SMASHING   },
+  { EL_BD_BUTTERFLY_DOWN, &level.score[SC_BUG],                TEXT_SMASHING   },
+  { EL_SPACESHIP_RIGHT,        &level.score[SC_SPACESHIP],     TEXT_SMASHING   },
+  { EL_SPACESHIP_UP,   &level.score[SC_SPACESHIP],     TEXT_SMASHING   },
+  { EL_SPACESHIP_LEFT, &level.score[SC_SPACESHIP],     TEXT_SMASHING   },
+  { EL_SPACESHIP_DOWN, &level.score[SC_SPACESHIP],     TEXT_SMASHING   },
+  { EL_BD_FIREFLY_RIGHT,&level.score[SC_SPACESHIP],    TEXT_SMASHING   },
+  { EL_BD_FIREFLY_UP,  &level.score[SC_SPACESHIP],     TEXT_SMASHING   },
+  { EL_BD_FIREFLY_LEFT, &level.score[SC_SPACESHIP],    TEXT_SMASHING   },
+  { EL_BD_FIREFLY_DOWN, &level.score[SC_SPACESHIP],    TEXT_SMASHING   },
+  { EL_YAMYAM,         &level.score[SC_YAMYAM],        TEXT_SMASHING   },
+  { EL_DARK_YAMYAM,    &level.score[SC_YAMYAM],        TEXT_SMASHING   },
   { EL_ROBOT,          &level.score[SC_ROBOT],         TEXT_SMASHING   },
   { EL_PACMAN_RIGHT,   &level.score[SC_PACMAN],        TEXT_SMASHING   },
   { EL_PACMAN_UP,      &level.score[SC_PACMAN],        TEXT_SMASHING   },
   { EL_PACMAN_LEFT,    &level.score[SC_PACMAN],        TEXT_SMASHING   },
   { EL_PACMAN_DOWN,    &level.score[SC_PACMAN],        TEXT_SMASHING   },
-  { EL_NUT,            &level.score[SC_KOKOSNUSS],     TEXT_CRACKING   },
-  { EL_DYNAMITE,       &level.score[SC_DYNAMIT],       TEXT_COLLECTING },
-  { EL_KEY_1,          &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
-  { EL_KEY_2,          &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
-  { EL_KEY_3,          &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
-  { EL_KEY_4,          &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
-  { EL_EM_KEY_1_FILE,  &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
-  { EL_EM_KEY_2_FILE,  &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
-  { EL_EM_KEY_3_FILE,  &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
-  { EL_EM_KEY_4_FILE,  &level.score[SC_SCHLUESSEL],    TEXT_COLLECTING },
+  { EL_NUT,            &level.score[SC_NUT],           TEXT_CRACKING   },
+  { EL_DYNAMITE,       &level.score[SC_DYNAMITE],      TEXT_COLLECTING },
+  { EL_KEY_1,          &level.score[SC_KEY],           TEXT_COLLECTING },
+  { EL_KEY_2,          &level.score[SC_KEY],           TEXT_COLLECTING },
+  { EL_KEY_3,          &level.score[SC_KEY],           TEXT_COLLECTING },
+  { EL_KEY_4,          &level.score[SC_KEY],           TEXT_COLLECTING },
+  { EL_EM_KEY_1_FILE,  &level.score[SC_KEY],           TEXT_COLLECTING },
+  { EL_EM_KEY_2_FILE,  &level.score[SC_KEY],           TEXT_COLLECTING },
+  { EL_EM_KEY_3_FILE,  &level.score[SC_KEY],           TEXT_COLLECTING },
+  { EL_EM_KEY_4_FILE,  &level.score[SC_KEY],           TEXT_COLLECTING },
   { EL_AMOEBA_WET,     &level.amoeba_speed,            TEXT_SPEED      },
   { EL_AMOEBA_DRY,     &level.amoeba_speed,            TEXT_SPEED      },
   { EL_AMOEBA_FULL,    &level.amoeba_speed,            TEXT_SPEED      },
@@ -3417,6 +3410,9 @@ static boolean checkPropertiesConfig()
 
 static void DrawPropertiesConfig()
 {
+  boolean element_has_score = FALSE;
+  char *element_score_text = NULL;
+  int temporary_dummy_score = 0;
   int counter_id = ED_COUNTER_ID_ELEM_SCORE;
   int xoffset_right = getCounterGadgetWidth();
   int yoffset_right = ED_BORDER_SIZE;
@@ -3429,6 +3425,11 @@ static void DrawPropertiesConfig()
   {
     if (elements_with_counter[i].element == properties_element)
     {
+#if 1
+      counterbutton_info[counter_id].value = elements_with_counter[i].value;
+      element_score_text = elements_with_counter[i].text;
+      element_has_score = TRUE;
+#else
       int x = counterbutton_info[counter_id].x + xoffset_right;
       int y = counterbutton_info[counter_id].y + yoffset_right;
 
@@ -3437,12 +3438,30 @@ static void DrawPropertiesConfig()
 
       ModifyEditorCounter(counter_id,  *counterbutton_info[counter_id].value);
       MapCounterButtons(counter_id);
+#endif
       break;
     }
   }
 
-  if (HAS_CONTENT(properties_element) ||
-      IS_CUSTOM_ELEMENT(properties_element))
+  if (IS_CUSTOM_ELEMENT(properties_element))
+  {
+    counterbutton_info[counter_id].value = &temporary_dummy_score;
+    element_score_text = "Score for certain actions";
+    element_has_score = TRUE;
+  }
+
+  if (element_has_score)
+  {
+    int x = counterbutton_info[counter_id].x + xoffset_right;
+    int y = counterbutton_info[counter_id].y + yoffset_right;
+
+    DrawTextF(x, y, FONT_TEXT_1, element_score_text);
+
+    ModifyEditorCounter(counter_id,  *counterbutton_info[counter_id].value);
+    MapCounterButtons(counter_id);
+  }
+
+  if (HAS_CONTENT(properties_element))
   {
     /* draw stickybutton gadget */
     i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
@@ -3461,8 +3480,6 @@ static void DrawPropertiesConfig()
       else
        DrawElementContentAreas();
     }
-    else if (IS_CUSTOM_ELEMENT(properties_element))
-      DrawCustomChangedArea();
   }
 
   if (IS_GEM(properties_element))
@@ -3480,81 +3497,20 @@ static void DrawPropertiesConfig()
 
   if (IS_CUSTOM_ELEMENT(properties_element))
   {
-    int nr = properties_element - EL_CUSTOM_START;
-
-    CopyCustomElementPropertiesToEditor();
-
-    /* draw checkbutton gadget */
-    i = ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE;
-    x = checkbutton_info[i].x + xoffset_right2;
-    y = checkbutton_info[i].y + yoffset_right2;
-
-    checkbutton_info[i].value = &custom_element_properties[nr].indestructible;
+    CopyCustomElementPropertiesToEditor(properties_element);
 
-    DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
-    ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
-                GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
-    MapCheckbuttonGadget(i);
-
-    /* draw checkbutton gadget */
-    i = ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL;
-    x = checkbutton_info[i].x + xoffset_right2;
-    y = checkbutton_info[i].y + yoffset_right2;
-
-    checkbutton_info[i].value = &custom_element_properties[nr].can_fall;
-
-    DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
-    ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
-                GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
-    MapCheckbuttonGadget(i);
-
-    /* draw checkbutton gadget */
-    i = ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH;
-    x = checkbutton_info[i].x + xoffset_right2;
-    y = checkbutton_info[i].y + yoffset_right2;
-
-    checkbutton_info[i].value = &custom_element_properties[nr].can_smash;
-
-    DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
-    ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
-                GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
-    MapCheckbuttonGadget(i);
-
-    /* draw checkbutton gadget */
-    i = ED_CHECKBUTTON_ID_CUSTOM_PUSHABLE;
-    x = checkbutton_info[i].x + xoffset_right2;
-    y = checkbutton_info[i].y + yoffset_right2;
-
-    checkbutton_info[i].value = &custom_element_properties[nr].pushable;
-
-    DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
-    ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
-                GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
-    MapCheckbuttonGadget(i);
-
-    /* draw checkbutton gadget */
-    i = ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY;
-    x = checkbutton_info[i].x + xoffset_right2;
-    y = checkbutton_info[i].y + yoffset_right2;
-
-    checkbutton_info[i].value = &custom_element_properties[nr].slippery;
-
-    DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
-    ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
-                GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
-    MapCheckbuttonGadget(i);
-
-    /* draw selectbox gadget */
-    i = ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE;
-    x = selectbox_info[i].x + xoffset_right2;
-    y = selectbox_info[i].y + yoffset_right2;
-
-    selectbox_info[i].index = &index_change_cause;
-
-    DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text);
-    ModifyGadget(level_editor_gadget[selectbox_info[i].gadget_id],
-                GDI_SELECTBOX_INDEX, *selectbox_info[i].index, GDI_END);
-    MapSelectboxGadget(i);
+    for (i =  ED_CHECKBUTTON_ID_CUSTOM_FIRST;
+        i <= ED_CHECKBUTTON_ID_CUSTOM_LAST; i++)
+    {
+      /* draw checkbutton gadget */
+      x = checkbutton_info[i].x + xoffset_right2;
+      y = checkbutton_info[i].y + yoffset_right2;
+
+      DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
+      ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
+                  GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+      MapCheckbuttonGadget(i);
+    }
   }
 }
 
@@ -3741,7 +3697,7 @@ static void DrawPropertiesTabulatorGadgets()
   struct GadgetDesign *gd = &gd_gi->alt_design[GD_BUTTON_UNPRESSED];
   int gd_x = gd->x + gd_gi->border.width / 2;
   int gd_y = gd->y + gd_gi->height - 1;
-  Pixel line_color = GetPixel(gd->bitmap, gd_x, gd_y);
+  Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y);
   int id_first = ED_TEXTBUTTON_ID_PROPERTIES_INFO;
   int id_last  = ED_TEXTBUTTON_ID_PROPERTIES_INFO;
   int i;
@@ -3759,28 +3715,75 @@ static void DrawPropertiesTabulatorGadgets()
     int gadget_id = textbutton_info[i].gadget_id;
     struct GadgetInfo *gi = level_editor_gadget[gadget_id];
     boolean active = (i != edit_mode_properties);
-    Pixel color = (active ? BLACK_PIXEL : line_color);
 
-    /* draw solid or black line below tabulator button */
-    FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width, 1, color);
+    /* draw background line below tabulator button */
+    ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width,1);
+
+    /* draw solid line below inactive tabulator buttons */
+    if (!active && tab_color != BLACK_PIXEL)   /* black => transparent */
+      FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width,1, tab_color);
 
     ModifyGadget(gi, GDI_ACTIVE, active, GDI_END);
     MapTextbuttonGadget(i);
   }
 
   /* draw little border line below tabulator buttons */
-  FillRectangle(drawto, gd_gi->x, gd_gi->y + gd_gi->height + 1,
-               3 * gd_gi->width + 2 * ED_GADGET_DISTANCE, ED_GADGET_DISTANCE,
-               line_color);
+  if (tab_color != BLACK_PIXEL)                        /* black => transparent */
+    FillRectangle(drawto, gd_gi->x, gd_gi->y + gd_gi->height + 1,
+                 3 * gd_gi->width + 2 * ED_GADGET_DISTANCE,
+                 ED_GADGET_DISTANCE, tab_color);
 }
 
 static void DrawPropertiesInfo()
 {
+  static struct
+  {
+    int value;
+    char *text;
+  }
+  properties[] =
+  {
+    /* configurable properties */
+    { EP_INDESTRUCTIBLE,       "- undestructible"                      },
+    { EP_DIGGABLE,             "- diggable"                            },
+    { EP_COLLECTIBLE,          "- collectible"                         },
+    { EP_PUSHABLE,             "- pushable"                            },
+    { EP_CAN_FALL,             "- can fall"                            },
+    { EP_CAN_SMASH,            "- can smash other objects"             },
+    { EP_CAN_MOVE,             "- can move"                            },
+    { EP_SLIPPERY,             "- slippery for falling objects"        },
+    { EP_EM_SLIPPERY_WALL,     "- slippery for some gems (EM style)"   },
+    { EP_WALKABLE_OVER,                "- player can walk over it"             },
+    { EP_WALKABLE_INSIDE,      "- player can walk inside it"           },
+    { EP_WALKABLE_UNDER,       "- player can walk under it"            },
+    { EP_PASSABLE_OVER,                "- player can pass over it"             },
+    { EP_PASSABLE_INSIDE,      "- player can pass through it"          },
+    { EP_PASSABLE_UNDER,       "- player can pass under it"            },
+
+    /* pre-defined properties */
+    { EP_CAN_PASS_MAGIC_WALL,  "- can pass magic walls"                },
+    { EP_DONT_TOUCH,           "- deadly when touched"                 },
+    { EP_ENEMY,                        "- can kill the player"                 },
+    { EP_DONT_GO_TO,           "- deadly when walked to"               },
+    { EP_CAN_EXPLODE,          "- can explode"                         },
+    { EP_HAS_CONTENT,          "- can contain other elements"          },
+
+    { -1,                      NULL                                    }
+  };
   char *filename = getElementDescriptionFilename(properties_element);
-  int num_elements_in_level;
+  char *percentage_text = "In this level:";
+  char *properties_text = "Standard properties:";
   float percentage;
+  int num_elements_in_level;
+  int num_standard_properties = 0;
+  int font1_nr = FONT_TEXT_1;
+  int font2_nr = FONT_TEXT_2;
+  int font1_width = getFontWidth(font1_nr);
+  int font2_height = getFontHeight(font2_nr);
+  int pad_x = ED_SETTINGS_XPOS;
+  int pad_y = 5 * TILEY;
   int screen_line = 2;
-  int x, y;
+  int i, x, y;
 
   num_elements_in_level = 0;
   for (y=0; y<lev_fieldy; y++) 
@@ -3789,9 +3792,34 @@ static void DrawPropertiesInfo()
        num_elements_in_level++;
   percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy);
 
-  DrawTextF(ED_SETTINGS_XPOS, 5 * TILEY, FONT_TEXT_1, "In this level:");
-  DrawTextF(ED_SETTINGS_XPOS + 15 * getFontWidth(FONT_TEXT_1), 5 * TILEY,
-           FONT_TEXT_2, "%d (%.2f%%)", num_elements_in_level, percentage);
+  DrawTextF(pad_x, pad_y, font1_nr, percentage_text);
+  DrawTextF(pad_x + strlen(percentage_text) * font1_width, pad_y,
+           font2_nr, "%d (%.2f%%)", num_elements_in_level, percentage);
+
+  for (i=0; properties[i].value != -1; i++)
+    if (HAS_PROPERTY(properties_element, properties[i].value))
+      num_standard_properties++;
+
+#if 1
+  if (num_standard_properties > 0)
+  {
+    DrawTextF(pad_x, pad_y + screen_line * font2_height, font1_nr,
+             properties_text);
+    screen_line++;
+
+    for (i=0; properties[i].value != -1; i++)
+    {
+      if (!HAS_PROPERTY(properties_element, properties[i].value))
+       continue;
+
+      DrawTextF(pad_x, pad_y + screen_line * font2_height, font2_nr,
+               properties[i].text);
+      screen_line++;
+    }
+
+    screen_line++;
+  }
+#endif
 
   PrintInfoText("Description:", FONT_TEXT_1, screen_line);
   if (PrintElementDescriptionFromFile(filename, screen_line + 1) == 0)
@@ -3800,7 +3828,36 @@ static void DrawPropertiesInfo()
 
 static void DrawPropertiesAdvanced()
 {
-  DrawText(SX + ED_SETTINGS_XPOS, SY + 5 * TILEY, "Coming soon!", FONT_TEXT_1);
+  int xoffset_right2 = ED_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE;
+  int yoffset_right2 = ED_BORDER_SIZE;
+  int i, x, y;
+
+  DrawText(SX + ED_SETTINGS_XPOS, SY + 5 * TILEY,
+          "Under construction! :-)", FONT_TEXT_1);
+
+  /* draw stickybutton gadget */
+  i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
+  x = checkbutton_info[i].x + xoffset_right2;
+  y = checkbutton_info[i].y + yoffset_right2;
+
+  DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
+  ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
+              GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+  MapCheckbuttonGadget(i);
+
+  DrawCustomChangedArea();
+
+  /* draw selectbox gadget */
+  i = ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE;
+  x = selectbox_info[i].x + xoffset_right2;
+  y = selectbox_info[i].y + yoffset_right2;
+
+  selectbox_info[i].index = &index_change_cause;
+
+  DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text);
+  ModifyGadget(level_editor_gadget[selectbox_info[i].gadget_id],
+              GDI_SELECTBOX_INDEX, *selectbox_info[i].index, GDI_END);
+  MapSelectboxGadget(i);
 }
 
 static void DrawPropertiesWindow()
@@ -4794,7 +4851,7 @@ static void HandleCheckbuttons(struct GadgetInfo *gi)
 
   if (type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST &&
       type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST)
-    CopyCustomElementPropertiesToGame();
+    CopyCustomElementPropertiesToGame(properties_element);
 }
 
 static void HandleControlButtons(struct GadgetInfo *gi)
@@ -4963,7 +5020,8 @@ static void HandleControlButtons(struct GadgetInfo *gi)
     case GADGET_ID_FLOOD_FILL:
     case GADGET_ID_GRAB_BRUSH:
     case GADGET_ID_PICK_ELEMENT:
-      last_drawing_function = drawing_function;
+      if (drawing_function != GADGET_ID_PICK_ELEMENT)
+       last_drawing_function = drawing_function;
       drawing_function = id;
       draw_with_brush = FALSE;
       break;
@@ -5067,7 +5125,7 @@ static void HandleControlButtons(struct GadgetInfo *gi)
          TapeStartRecording();
 
        level_editor_test_game = TRUE;
-       game_status = PLAYING;
+       game_status = GAME_MODE_PLAYING;
 
        InitGame();
       }
@@ -5225,7 +5283,7 @@ void HandleEditorGadgetInfoText(void *ptr)
   char shortcut[MAX_OUTPUT_LINESIZE + 1];
   int max_infotext_len = getMaxInfoTextLength();
 
-  if (game_status != LEVELED)
+  if (game_status != GAME_MODE_EDITOR)
     return;
 
   ClearEditorGadgetInfoText();
@@ -5406,7 +5464,7 @@ void RequestExitLevelEditor(boolean ask_if_level_has_changed)
     /*
     CloseDoor(DOOR_CLOSE_ALL);
     */
-    game_status = MAINMENU;
+    game_status = GAME_MODE_MAIN;
     DrawMainMenu();
   }
   else