changed "http" to "https" in URLs
[rocksndiamonds.git] / src / editor.c
index 5d38017e711084f4951f5270aaaa43ec995e6d6b..3b8d0f5a3c8787fd1145e151c9e865b482121b07 100644 (file)
@@ -4,7 +4,7 @@
 // (c) 1995-2014 by Artsoft Entertainment
 //                         Holger Schemel
 //                 info@artsoft.org
-//                 http://www.artsoft.org/
+//                 https://www.artsoft.org/
 // ----------------------------------------------------------------------------
 // editor.c
 // ============================================================================
@@ -642,7 +642,7 @@ enum
   GADGET_ID_USE_TIME_ORB_BUG,
   GADGET_ID_USE_LIFE_BUGS,
   GADGET_ID_RANDOM_BALL_CONTENT,
-  GADGET_ID_INITIAL_BALL_STATE,
+  GADGET_ID_INITIAL_BALL_ACTIVE,
   GADGET_ID_GROW_INTO_DIGGABLE,
   GADGET_ID_SB_FIELDS_NEEDED,
   GADGET_ID_SB_OBJECTS_NEEDED,
@@ -947,7 +947,7 @@ enum
   ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG,
   ED_CHECKBUTTON_ID_USE_LIFE_BUGS,
   ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT,
-  ED_CHECKBUTTON_ID_INITIAL_BALL_STATE,
+  ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE,
   ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE,
   ED_CHECKBUTTON_ID_SB_FIELDS_NEEDED,
   ED_CHECKBUTTON_ID_SB_OBJECTS_NEEDED,
@@ -1965,6 +1965,10 @@ static struct ValueTextInfo options_change_direct_action[] =
 #endif
   { CE_VALUE_GETS_ZERO,                "CE value gets 0"               },
   { CE_SCORE_GETS_ZERO,                "CE score gets 0"               },
+  { CE_UNDEFINED,              " "                             },
+  { CE_HEADLINE_SPECIAL_EVENTS,        "[mouse events]"                },
+  { CE_CLICKED_BY_MOUSE,       "clicked by mouse"              },
+  { CE_PRESSED_BY_MOUSE,       "pressed by mouse"              },
 
   { -1,                                NULL                            }
 };
@@ -1994,6 +1998,10 @@ static struct ValueTextInfo options_change_other_action[] =
   { CE_SCORE_CHANGES_OF_X,     "CE score changes of"           },
   { CE_VALUE_GETS_ZERO_OF_X,   "CE value gets 0 of"            },
   { CE_SCORE_GETS_ZERO_OF_X,   "CE score gets 0 of"            },
+  { CE_UNDEFINED,              " "                             },
+  { CE_HEADLINE_SPECIAL_EVENTS,        "[mouse events]"                },
+  { CE_MOUSE_CLICKED_ON_X,     "mouse clicked on"              },
+  { CE_MOUSE_PRESSED_ON_X,     "mouse pressed on"              },
 
   { -1,                                NULL                            }
 };
@@ -2084,10 +2092,11 @@ static struct ValueTextInfo options_action_type[] =
   { CA_SET_LEVEL_SCORE,                "set score"                     },
   { CA_SET_LEVEL_GEMS,         "set gems"                      },
   { CA_SET_LEVEL_WIND,         "set wind dir."                 },
-  { CA_SET_LEVEL_RANDOM_SEED,  "set rand. seed"                },
+  { CA_SET_LEVEL_RANDOM_SEED,  "set random seed"               },
   { CA_UNDEFINED,              " "                             },
   { CA_HEADLINE_PLAYER_ACTIONS,        "[player]"                      },
   { CA_MOVE_PLAYER,            "move player"                   },
+  { CA_MOVE_PLAYER_NEW,                "move player new"               },
   { CA_EXIT_PLAYER,            "exit player"                   },
   { CA_KILL_PLAYER,            "kill player"                   },
   { CA_SET_PLAYER_KEYS,                "set keys"                      },
@@ -2413,6 +2422,7 @@ action_arg_options[] =
   { CA_EXIT_PLAYER,            0,      options_action_arg_player,      },
   { CA_KILL_PLAYER,            0,      options_action_arg_player,      },
   { CA_MOVE_PLAYER,            0,      options_action_arg_direction,   },
+  { CA_MOVE_PLAYER_NEW,                0,      options_action_arg_direction,   },
   { CA_RESTART_LEVEL,          0,      options_action_arg_none,        },
   { CA_SHOW_ENVELOPE,          0,      options_action_arg_envelope,    },
   { CA_SET_LEVEL_TIME,         3,      options_action_arg_number,      },
@@ -2665,7 +2675,7 @@ static struct
   {
     ED_ELEMENT_SETTINGS_XPOS(1),       ED_ELEMENT_SETTINGS_YPOS(13),
     GADGET_ID_ACTION_TYPE,             GADGET_ID_NONE,
-    -1,
+    15,
     options_action_type,
     &custom_element_change.action_type,
     NULL, NULL, NULL,                  "action on specified condition"
@@ -3060,8 +3070,8 @@ static struct
   },
   {
     ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(1),
-    GADGET_ID_INITIAL_BALL_STATE,      GADGET_ID_NONE,
-    &level.ball_state_initial,
+    GADGET_ID_INITIAL_BALL_ACTIVE,     GADGET_ID_NONE,
+    &level.ball_active_initial,
     NULL, NULL,
     "magic ball initially activated",  "activate magic ball after level start"
   },
@@ -3462,7 +3472,7 @@ static struct
   int gadget_id_align;
   int *value;
   int area_xsize, area_ysize;
-  char *text_left, *text_right, *text_below, *infotext;
+  char *text_left, *text_right, *text_above, *text_below, *infotext;
 } drawingarea_info[ED_NUM_DRAWING_AREAS] =
 {
   // ---------- level playfield content ---------------------------------------
@@ -3473,7 +3483,7 @@ static struct
     GADGET_ID_DRAWING_LEVEL,           GADGET_ID_NONE,
     NULL,
     -1, -1,    // these values are not constant, but can change at runtime
-    NULL, NULL, NULL,                  NULL
+    NULL, NULL, NULL, NULL,            NULL
   },
 
   // ---------- yam yam content -----------------------------------------------
@@ -3483,56 +3493,56 @@ static struct
     ED_AREA_YAMYAM_CONTENT_XOFF(0),    ED_AREA_YAMYAM_CONTENT_YOFF(0),
     GADGET_ID_YAMYAM_CONTENT_0,                GADGET_ID_NONE,
     &level.yamyam_content[0].e[0][0],  3, 3,
-    NULL, NULL, "1",                   NULL
+    NULL, NULL, NULL, "1",             NULL
   },
   {
     ED_AREA_YAMYAM_CONTENT_XPOS,       ED_AREA_YAMYAM_CONTENT_YPOS,
     ED_AREA_YAMYAM_CONTENT_XOFF(1),    ED_AREA_YAMYAM_CONTENT_YOFF(1),
     GADGET_ID_YAMYAM_CONTENT_1,                GADGET_ID_NONE,
     &level.yamyam_content[1].e[0][0],  3, 3,
-    NULL, NULL, "2",                   NULL
+    NULL, NULL, NULL, "2",             NULL
   },
   {
     ED_AREA_YAMYAM_CONTENT_XPOS,       ED_AREA_YAMYAM_CONTENT_YPOS,
     ED_AREA_YAMYAM_CONTENT_XOFF(2),    ED_AREA_YAMYAM_CONTENT_YOFF(2),
     GADGET_ID_YAMYAM_CONTENT_2,                GADGET_ID_NONE,
     &level.yamyam_content[2].e[0][0],  3, 3,
-    NULL, NULL, "3",                   NULL
+    NULL, NULL, NULL, "3",             NULL
   },
   {
     ED_AREA_YAMYAM_CONTENT_XPOS,       ED_AREA_YAMYAM_CONTENT_YPOS,
     ED_AREA_YAMYAM_CONTENT_XOFF(3),    ED_AREA_YAMYAM_CONTENT_YOFF(3),
     GADGET_ID_YAMYAM_CONTENT_3,                GADGET_ID_NONE,
     &level.yamyam_content[3].e[0][0],  3, 3,
-    NULL, NULL, "4",                   NULL
+    NULL, NULL, NULL, "4",             NULL
   },
   {
     ED_AREA_YAMYAM_CONTENT_XPOS,       ED_AREA_YAMYAM_CONTENT_YPOS,
     ED_AREA_YAMYAM_CONTENT_XOFF(4),    ED_AREA_YAMYAM_CONTENT_YOFF(4),
     GADGET_ID_YAMYAM_CONTENT_4,                GADGET_ID_NONE,
     &level.yamyam_content[4].e[0][0],  3, 3,
-    NULL, NULL, "5",                   NULL
+    NULL, NULL, NULL, "5",             NULL
   },
   {
     ED_AREA_YAMYAM_CONTENT_XPOS,       ED_AREA_YAMYAM_CONTENT_YPOS,
     ED_AREA_YAMYAM_CONTENT_XOFF(5),    ED_AREA_YAMYAM_CONTENT_YOFF(5),
     GADGET_ID_YAMYAM_CONTENT_5,                GADGET_ID_NONE,
     &level.yamyam_content[5].e[0][0],  3, 3,
-    NULL, NULL, "6",                   NULL
+    NULL, NULL, NULL, "6",             NULL
   },
   {
     ED_AREA_YAMYAM_CONTENT_XPOS,       ED_AREA_YAMYAM_CONTENT_YPOS,
     ED_AREA_YAMYAM_CONTENT_XOFF(6),    ED_AREA_YAMYAM_CONTENT_YOFF(6),
     GADGET_ID_YAMYAM_CONTENT_6,                GADGET_ID_NONE,
     &level.yamyam_content[6].e[0][0],  3, 3,
-    NULL, NULL, "7",                   NULL
+    NULL, NULL, NULL, "7",             NULL
   },
   {
     ED_AREA_YAMYAM_CONTENT_XPOS,       ED_AREA_YAMYAM_CONTENT_YPOS,
     ED_AREA_YAMYAM_CONTENT_XOFF(7),    ED_AREA_YAMYAM_CONTENT_YOFF(7),
     GADGET_ID_YAMYAM_CONTENT_7,                GADGET_ID_NONE,
     &level.yamyam_content[7].e[0][0],  3, 3,
-    NULL, NULL, "8",                   NULL
+    NULL, NULL, NULL, "8",             NULL
   },
 
   // ---------- magic ball content --------------------------------------------
@@ -3542,66 +3552,66 @@ static struct
     ED_AREA_MAGIC_BALL_CONTENT_XOFF(0),        ED_AREA_MAGIC_BALL_CONTENT_YOFF(0),
     GADGET_ID_MAGIC_BALL_CONTENT_0,    GADGET_ID_NONE,
     &level.ball_content[0].e[0][0],    3, 3,
-    NULL, NULL, "1",                   NULL
+    NULL, NULL, NULL, "1",             NULL
   },
   {
     ED_AREA_MAGIC_BALL_CONTENT_XPOS,   ED_AREA_MAGIC_BALL_CONTENT_YPOS,
     ED_AREA_MAGIC_BALL_CONTENT_XOFF(1),        ED_AREA_MAGIC_BALL_CONTENT_YOFF(1),
     GADGET_ID_MAGIC_BALL_CONTENT_1,    GADGET_ID_NONE,
     &level.ball_content[1].e[0][0],    3, 3,
-    NULL, NULL, "2",                   NULL
+    NULL, NULL, NULL, "2",             NULL
   },
   {
     ED_AREA_MAGIC_BALL_CONTENT_XPOS,   ED_AREA_MAGIC_BALL_CONTENT_YPOS,
     ED_AREA_MAGIC_BALL_CONTENT_XOFF(2),        ED_AREA_MAGIC_BALL_CONTENT_YOFF(2),
     GADGET_ID_MAGIC_BALL_CONTENT_2,    GADGET_ID_NONE,
     &level.ball_content[2].e[0][0],    3, 3,
-    NULL, NULL, "3",                   NULL
+    NULL, NULL, NULL, "3",             NULL
   },
   {
     ED_AREA_MAGIC_BALL_CONTENT_XPOS,   ED_AREA_MAGIC_BALL_CONTENT_YPOS,
     ED_AREA_MAGIC_BALL_CONTENT_XOFF(3),        ED_AREA_MAGIC_BALL_CONTENT_YOFF(3),
     GADGET_ID_MAGIC_BALL_CONTENT_3,    GADGET_ID_NONE,
     &level.ball_content[3].e[0][0],    3, 3,
-    NULL, NULL, "4",                   NULL
+    NULL, NULL, NULL, "4",             NULL
   },
   {
     ED_AREA_MAGIC_BALL_CONTENT_XPOS,   ED_AREA_MAGIC_BALL_CONTENT_YPOS,
     ED_AREA_MAGIC_BALL_CONTENT_XOFF(4),        ED_AREA_MAGIC_BALL_CONTENT_YOFF(4),
     GADGET_ID_MAGIC_BALL_CONTENT_4,    GADGET_ID_NONE,
     &level.ball_content[4].e[0][0],    3, 3,
-    NULL, NULL, "5",                   NULL
+    NULL, NULL, NULL, "5",             NULL
   },
   {
     ED_AREA_MAGIC_BALL_CONTENT_XPOS,   ED_AREA_MAGIC_BALL_CONTENT_YPOS,
     ED_AREA_MAGIC_BALL_CONTENT_XOFF(5),        ED_AREA_MAGIC_BALL_CONTENT_YOFF(5),
     GADGET_ID_MAGIC_BALL_CONTENT_5,    GADGET_ID_NONE,
     &level.ball_content[5].e[0][0],    3, 3,
-    NULL, NULL, "6",                   NULL
+    NULL, NULL, NULL, "6",             NULL
   },
   {
     ED_AREA_MAGIC_BALL_CONTENT_XPOS,   ED_AREA_MAGIC_BALL_CONTENT_YPOS,
     ED_AREA_MAGIC_BALL_CONTENT_XOFF(6),        ED_AREA_MAGIC_BALL_CONTENT_YOFF(6),
     GADGET_ID_MAGIC_BALL_CONTENT_6,    GADGET_ID_NONE,
     &level.ball_content[6].e[0][0],    3, 3,
-    NULL, NULL, "7",                   NULL
+    NULL, NULL, NULL, "7",             NULL
   },
   {
     ED_AREA_MAGIC_BALL_CONTENT_XPOS,   ED_AREA_MAGIC_BALL_CONTENT_YPOS,
     ED_AREA_MAGIC_BALL_CONTENT_XOFF(7),        ED_AREA_MAGIC_BALL_CONTENT_YOFF(7),
     GADGET_ID_MAGIC_BALL_CONTENT_7,    GADGET_ID_NONE,
     &level.ball_content[7].e[0][0],    3, 3,
-    NULL, NULL, "8",                   NULL
+    NULL, NULL, NULL, "8",             NULL
   },
 
   // ---------- android content -----------------------------------------------
 
   {
-    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(5),
+    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(6),
     ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_ANDROID_CONTENT,         GADGET_ID_NONE,
     &level.android_clone_element[0],   MAX_ANDROID_ELEMENTS, 1,
-    "elements:", NULL, NULL,           "elements android can clone"
+    NULL, NULL, "elements:", NULL,     "elements android can clone"
   },
 
   // ---------- amoeba content ------------------------------------------------
@@ -3611,7 +3621,7 @@ static struct
     ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_AMOEBA_CONTENT,          GADGET_ID_NONE,
     &level.amoeba_content,             1, 1,
-    "content:", NULL, NULL,            "amoeba content"
+    "content:", NULL, NULL, NULL,      "amoeba content"
   },
 
   // ---------- level start element -------------------------------------------
@@ -3621,7 +3631,7 @@ static struct
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_START_ELEMENT,           GADGET_ID_USE_START_ELEMENT,
     &level.start_element[0],           1, 1,
-    NULL, NULL, NULL,                  "level start element"
+    NULL, NULL, NULL, NULL,            "level start element"
   },
 
   // ---------- player artwork element ----------------------------------------
@@ -3631,7 +3641,7 @@ static struct
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_ARTWORK_ELEMENT,         GADGET_ID_USE_ARTWORK_ELEMENT,
     &level.artwork_element[0],         1, 1,
-    NULL, NULL, NULL,                  "element for player artwork"
+    NULL, NULL, NULL, NULL,            "element for player artwork"
   },
 
   // ---------- player explosion element --------------------------------------
@@ -3641,7 +3651,7 @@ static struct
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_EXPLOSION_ELEMENT,       GADGET_ID_USE_EXPLOSION_ELEMENT,
     &level.explosion_element[0],       1, 1,
-    NULL, NULL, NULL,                  "element for player explosion"
+    NULL, NULL, NULL, NULL,            "element for player explosion"
   },
 
   // ---------- player initial inventory --------------------------------------
@@ -3651,7 +3661,7 @@ static struct
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_INVENTORY_CONTENT,       GADGET_ID_USE_INITIAL_INVENTORY,
     &level.initial_inventory_content[0][0], MAX_INITIAL_INVENTORY_SIZE, 1,
-    NULL, NULL, NULL,                  "content for initial inventory"
+    NULL, NULL, NULL, NULL,            "content for initial inventory"
   },
 
   // ---------- element settings: configure 1 (custom elements) ---------------
@@ -3663,7 +3673,7 @@ static struct
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_CUSTOM_GRAPHIC,          GADGET_ID_CUSTOM_USE_GRAPHIC,
     &custom_element.gfx_element_initial,1, 1,
-    NULL, NULL, NULL,                  "custom graphic element"
+    NULL, NULL, NULL, NULL,            "custom graphic element"
   },
 
   // ---------- element settings: configure 2 (custom elements) ---------------
@@ -3675,7 +3685,7 @@ static struct
     0,                                 ED_AREA_3X3_SETTINGS_YOFF,
     GADGET_ID_CUSTOM_CONTENT,          GADGET_ID_NONE, // align three rows
     &custom_element.content.e[0][0],   3, 3,
-    "content:", NULL, NULL,            NULL
+    "content:", NULL, NULL, NULL,      NULL
   },
 
   // ---------- custom enter and leave element (when moving) ------------------
@@ -3685,14 +3695,14 @@ static struct
     ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_CUSTOM_MOVE_ENTER,       GADGET_ID_NONE,
     &custom_element.move_enter_element,        1, 1,
-    "can dig:", " ", NULL,             "element that can be digged/collected"
+    "can dig:", " ", NULL, NULL,       "element that can be digged/collected"
   },
   {
     -1,                                        ED_AREA_1X1_SETTINGS_YPOS(3),
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_CUSTOM_MOVE_LEAVE,       GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE,
     &custom_element.move_leave_element,        1, 1,
-    NULL, NULL, NULL,                  "element that will be left behind"
+    NULL, NULL, NULL, NULL,            "element that will be left behind"
   },
 
   // ---------- element settings: advanced (custom elements) ------------------
@@ -3704,7 +3714,7 @@ static struct
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_CUSTOM_CHANGE_TARGET,    GADGET_ID_CUSTOM_CAN_CHANGE,
     &custom_element_change.target_element, 1, 1,
-    NULL, "after/when:", NULL,         "new target element after change"
+    NULL, "after/when:", NULL, NULL,   "new target element after change"
   },
 
   // ---------- custom change content (extended change target) ----------------
@@ -3714,7 +3724,7 @@ static struct
     0,                                 ED_AREA_3X3_SETTINGS_YOFF,
     GADGET_ID_CUSTOM_CHANGE_CONTENT,   GADGET_ID_NONE, // align three rows
     &custom_element_change.target_content.e[0][0], 3, 3,
-    NULL, NULL, NULL,                  "new extended elements after change"
+    NULL, NULL, NULL, NULL,            "new extended elements after change"
   },
 
   // ---------- custom change trigger (element causing change) ----------------
@@ -3724,7 +3734,7 @@ static struct
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_CUSTOM_CHANGE_TRIGGER,   GADGET_ID_CHANGE_OTHER_ACTION,
     &custom_element_change.initial_trigger_element, 1, 1,
-    NULL, NULL, NULL,                  "other element triggering change"
+    NULL, NULL, NULL, NULL,            "other element triggering change"
   },
 
   // ---------- custom change action (element used for action) ----------------
@@ -3734,7 +3744,7 @@ static struct
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_CUSTOM_CHANGE_ACTION,    GADGET_ID_ACTION_ARG,
     &custom_element_change.action_element, 1, 1,
-    NULL, NULL, NULL,                  "element used as action parameter"
+    NULL, NULL, NULL, NULL,            "element used as action parameter"
   },
 
   // ---------- group element content -----------------------------------------
@@ -3744,7 +3754,7 @@ static struct
     ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_GROUP_CONTENT,           GADGET_ID_NONE,
     &group_element_info.element[0],    MAX_ELEMENTS_IN_GROUP, 1,
-    "content:", NULL, NULL,            NULL
+    "content:", NULL, NULL, NULL,      NULL
   },
 
   // ---------- random background (for random painting) -----------------------
@@ -3754,7 +3764,7 @@ static struct
     0,                                 ED_AREA_1X1_LSETTINGS_YOFF,
     GADGET_ID_RANDOM_BACKGROUND,       GADGET_ID_RANDOM_RESTRICTED,
     &random_placement_background_element, 1, 1,
-    NULL, NULL, NULL,                  "random placement background"
+    NULL, NULL, NULL, NULL,            "random placement background"
   },
 };
 
@@ -4046,13 +4056,13 @@ static int editor_el_emerald_mine_club[] =
 
   EL_EMC_MAGIC_BALL,
   EL_EMC_MAGIC_BALL_SWITCH,
-  EL_SPRING,
-  EL_EMC_SPRING_BUMPER,
-
   EL_EMC_LENSES,
   EL_EMC_MAGNIFIER,
-  EL_EMPTY,
-  EL_EMPTY,
+
+  EL_SPRING_LEFT,
+  EL_SPRING,
+  EL_SPRING_RIGHT,
+  EL_EMC_SPRING_BUMPER,
 
   EL_BALLOON,
   EL_YAMYAM_UP,
@@ -7293,8 +7303,10 @@ static void MapDrawingArea(int id)
   int xoffset_below = getTextWidth(drawingarea_info[id].text_below, font_nr);
   int x_left  = gi->x - xoffset_left;
   int x_right = gi->x + gi->width + ED_DRAWINGAREA_TEXT_DISTANCE;
+  int x_above = gi->x - ED_DRAWINGAREA_BORDER_SIZE;
   int x_below = gi->x + (gi->width - xoffset_below) / 2;
   int y_side  = gi->y + (gi->height - font_height) / 2;
+  int y_above = gi->y - font_height - ED_DRAWINGAREA_TEXT_DISTANCE;
   int y_below = gi->y + gi->height + ED_DRAWINGAREA_TEXT_DISTANCE;
 
   if (drawingarea_info[id].text_left)
@@ -7303,6 +7315,9 @@ static void MapDrawingArea(int id)
   if (drawingarea_info[id].text_right)
     DrawText(x_right, y_side, drawingarea_info[id].text_right, font_nr);
 
+  if (drawingarea_info[id].text_above)
+    DrawText(x_above, y_above, drawingarea_info[id].text_above, font_nr);
+
   if (drawingarea_info[id].text_below)
     DrawText(x_below, y_below, drawingarea_info[id].text_below, font_nr);
 
@@ -7715,6 +7730,17 @@ static boolean PrepareSavingIntoPersonalLevelSet(void)
   leveldir_current =
     getTreeInfoFromIdentifier(leveldir_first, getLoginName());
 
+  // this may happen if "setup.internal.create_user_levelset" is FALSE
+  // or if file "levelinfo.conf" is missing in personal user level set
+  if (leveldir_current == NULL)
+  {
+    Request("Cannot find personal level set?!", REQ_CONFIRM);
+
+    leveldir_current = leveldir_former;
+
+    return FALSE;
+  }
+
   // find unused level number
   for (new_level_nr = leveldir_current->first_level; ; new_level_nr++)
   {
@@ -8128,6 +8154,8 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_SCORE_CHANGES) ? CE_SCORE_CHANGES :
      HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO) ? CE_VALUE_GETS_ZERO :
      HAS_CHANGE_EVENT(element, CE_SCORE_GETS_ZERO) ? CE_SCORE_GETS_ZERO :
+     HAS_CHANGE_EVENT(element, CE_CLICKED_BY_MOUSE) ? CE_CLICKED_BY_MOUSE :
+     HAS_CHANGE_EVENT(element, CE_PRESSED_BY_MOUSE) ? CE_PRESSED_BY_MOUSE :
      custom_element_change.direct_action);
 
   // set "change by other element action" selectbox help value
@@ -8155,6 +8183,8 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_SCORE_CHANGES_OF_X) ? CE_SCORE_CHANGES_OF_X :
      HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO_OF_X) ? CE_VALUE_GETS_ZERO_OF_X :
      HAS_CHANGE_EVENT(element, CE_SCORE_GETS_ZERO_OF_X) ? CE_SCORE_GETS_ZERO_OF_X :
+     HAS_CHANGE_EVENT(element, CE_MOUSE_CLICKED_ON_X) ? CE_MOUSE_CLICKED_ON_X :
+     HAS_CHANGE_EVENT(element, CE_MOUSE_PRESSED_ON_X) ? CE_MOUSE_PRESSED_ON_X :
      custom_element_change.other_action);
 }
 
@@ -8286,6 +8316,8 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_SCORE_CHANGES] = FALSE;
   custom_element_change_events[CE_VALUE_GETS_ZERO] = FALSE;
   custom_element_change_events[CE_SCORE_GETS_ZERO] = FALSE;
+  custom_element_change_events[CE_CLICKED_BY_MOUSE] = FALSE;
+  custom_element_change_events[CE_PRESSED_BY_MOUSE] = FALSE;
   custom_element_change_events[custom_element_change.direct_action] =
     custom_element_change_events[CE_BY_DIRECT_ACTION];
 
@@ -8313,6 +8345,8 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_SCORE_CHANGES_OF_X] = FALSE;
   custom_element_change_events[CE_VALUE_GETS_ZERO_OF_X] = FALSE;
   custom_element_change_events[CE_SCORE_GETS_ZERO_OF_X] = FALSE;
+  custom_element_change_events[CE_MOUSE_CLICKED_ON_X] = FALSE;
+  custom_element_change_events[CE_MOUSE_PRESSED_ON_X] = FALSE;
   custom_element_change_events[custom_element_change.other_action] =
     custom_element_change_events[CE_BY_OTHER_ACTION];
 
@@ -9707,6 +9741,8 @@ static struct
   { EL_EMC_LENSES,     &level.lenses_score,            TEXT_COLLECTING },
   { EL_EMC_MAGNIFIER,  &level.magnify_score,           TEXT_COLLECTING },
   { EL_SPRING,         &level.slurp_score,             TEXT_SLURPING   },
+  { EL_SPRING_LEFT,    &level.slurp_score,             TEXT_SLURPING   },
+  { EL_SPRING_RIGHT,   &level.slurp_score,             TEXT_SLURPING   },
   { EL_EMC_LENSES,     &level.lenses_time,             TEXT_DURATION   },
   { EL_EMC_MAGNIFIER,  &level.magnify_time,            TEXT_DURATION   },
   { EL_MM_FUSE_ACTIVE, &level.mm_time_fuse,            TEXT_DELAY_OFF  },
@@ -9880,7 +9916,7 @@ static void DrawPropertiesConfig(void)
       DrawMagicBallContentAreas();
 
       MapCheckbuttonGadget(ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT);
-      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_STATE);
+      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE);
     }
     else if (properties_element == EL_EMC_ANDROID)
       DrawAndroidElementArea(properties_element);
@@ -9982,7 +10018,9 @@ static void DrawPropertiesConfig(void)
   if (MAYBE_DONT_COLLIDE_WITH(properties_element))
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH);
 
-  if (properties_element == EL_SPRING)
+  if (properties_element == EL_SPRING ||
+      properties_element == EL_SPRING_LEFT ||
+      properties_element == EL_SPRING_RIGHT)
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_SPRING_BUG);
 
   if (properties_element == EL_TIME_ORB_FULL)