added updating metadata for current level set and creating new level sets
authorHolger Schemel <info@artsoft.org>
Sun, 15 Oct 2017 19:38:47 +0000 (21:38 +0200)
committerHolger Schemel <info@artsoft.org>
Fri, 23 Mar 2018 22:21:14 +0000 (23:21 +0100)
src/editor.c
src/libgame/setup.c
src/libgame/setup.h

index d78703f3fdb6778df28484b1cd23ea635d65f198..ce772508756c57a322a451fec2dc922d1601fc4a 100644 (file)
 #define GADGET_ID_LEVEL_RANDOM_SEED_DOWN (GADGET_ID_COUNTER_FIRST + 21)
 #define GADGET_ID_LEVEL_RANDOM_SEED_TEXT (GADGET_ID_COUNTER_FIRST + 22)
 #define GADGET_ID_LEVEL_RANDOM_SEED_UP (GADGET_ID_COUNTER_FIRST + 23)
-#define GADGET_ID_ELEMENT_VALUE1_DOWN  (GADGET_ID_COUNTER_FIRST + 24)
-#define GADGET_ID_ELEMENT_VALUE1_TEXT  (GADGET_ID_COUNTER_FIRST + 25)
-#define GADGET_ID_ELEMENT_VALUE1_UP    (GADGET_ID_COUNTER_FIRST + 26)
-#define GADGET_ID_ELEMENT_VALUE2_DOWN  (GADGET_ID_COUNTER_FIRST + 27)
-#define GADGET_ID_ELEMENT_VALUE2_TEXT  (GADGET_ID_COUNTER_FIRST + 28)
-#define GADGET_ID_ELEMENT_VALUE2_UP    (GADGET_ID_COUNTER_FIRST + 29)
-#define GADGET_ID_ELEMENT_VALUE3_DOWN  (GADGET_ID_COUNTER_FIRST + 30)
-#define GADGET_ID_ELEMENT_VALUE3_TEXT  (GADGET_ID_COUNTER_FIRST + 31)
-#define GADGET_ID_ELEMENT_VALUE3_UP    (GADGET_ID_COUNTER_FIRST + 32)
-#define GADGET_ID_ELEMENT_VALUE4_DOWN  (GADGET_ID_COUNTER_FIRST + 33)
-#define GADGET_ID_ELEMENT_VALUE4_TEXT  (GADGET_ID_COUNTER_FIRST + 34)
-#define GADGET_ID_ELEMENT_VALUE4_UP    (GADGET_ID_COUNTER_FIRST + 35)
-#define GADGET_ID_YAMYAM_CONTENT_DOWN  (GADGET_ID_COUNTER_FIRST + 36)
-#define GADGET_ID_YAMYAM_CONTENT_TEXT  (GADGET_ID_COUNTER_FIRST + 37)
-#define GADGET_ID_YAMYAM_CONTENT_UP    (GADGET_ID_COUNTER_FIRST + 38)
-#define GADGET_ID_BALL_CONTENT_DOWN    (GADGET_ID_COUNTER_FIRST + 39)
-#define GADGET_ID_BALL_CONTENT_TEXT    (GADGET_ID_COUNTER_FIRST + 40)
-#define GADGET_ID_BALL_CONTENT_UP      (GADGET_ID_COUNTER_FIRST + 41)
-#define GADGET_ID_ANDROID_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 42)
-#define GADGET_ID_ANDROID_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 43)
-#define GADGET_ID_ANDROID_CONTENT_UP   (GADGET_ID_COUNTER_FIRST + 44)
-#define GADGET_ID_ENVELOPE_XSIZE_DOWN  (GADGET_ID_COUNTER_FIRST + 45)
-#define GADGET_ID_ENVELOPE_XSIZE_TEXT  (GADGET_ID_COUNTER_FIRST + 46)
-#define GADGET_ID_ENVELOPE_XSIZE_UP    (GADGET_ID_COUNTER_FIRST + 47)
-#define GADGET_ID_ENVELOPE_YSIZE_DOWN  (GADGET_ID_COUNTER_FIRST + 48)
-#define GADGET_ID_ENVELOPE_YSIZE_TEXT  (GADGET_ID_COUNTER_FIRST + 49)
-#define GADGET_ID_ENVELOPE_YSIZE_UP    (GADGET_ID_COUNTER_FIRST + 50)
-#define GADGET_ID_INVENTORY_SIZE_DOWN  (GADGET_ID_COUNTER_FIRST + 51)
-#define GADGET_ID_INVENTORY_SIZE_TEXT  (GADGET_ID_COUNTER_FIRST + 52)
-#define GADGET_ID_INVENTORY_SIZE_UP    (GADGET_ID_COUNTER_FIRST + 53)
-#define GADGET_ID_CUSTOM_SCORE_DOWN    (GADGET_ID_COUNTER_FIRST + 54)
-#define GADGET_ID_CUSTOM_SCORE_TEXT    (GADGET_ID_COUNTER_FIRST + 55)
-#define GADGET_ID_CUSTOM_SCORE_UP      (GADGET_ID_COUNTER_FIRST + 56)
-#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 57)
-#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 58)
-#define GADGET_ID_CUSTOM_GEMCOUNT_UP   (GADGET_ID_COUNTER_FIRST + 59)
-#define GADGET_ID_CUSTOM_VALUE_FIX_DOWN        (GADGET_ID_COUNTER_FIRST + 60)
-#define GADGET_ID_CUSTOM_VALUE_FIX_TEXT        (GADGET_ID_COUNTER_FIRST + 61)
-#define GADGET_ID_CUSTOM_VALUE_FIX_UP  (GADGET_ID_COUNTER_FIRST + 62)
-#define GADGET_ID_CUSTOM_VALUE_RND_DOWN        (GADGET_ID_COUNTER_FIRST + 63)
-#define GADGET_ID_CUSTOM_VALUE_RND_TEXT        (GADGET_ID_COUNTER_FIRST + 64)
-#define GADGET_ID_CUSTOM_VALUE_RND_UP  (GADGET_ID_COUNTER_FIRST + 65)
-#define GADGET_ID_PUSH_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 66)
-#define GADGET_ID_PUSH_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 67)
-#define GADGET_ID_PUSH_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 68)
-#define GADGET_ID_PUSH_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 69)
-#define GADGET_ID_PUSH_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 70)
-#define GADGET_ID_PUSH_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 71)
-#define GADGET_ID_DROP_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 72)
-#define GADGET_ID_DROP_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 73)
-#define GADGET_ID_DROP_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 74)
-#define GADGET_ID_DROP_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 75)
-#define GADGET_ID_DROP_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 76)
-#define GADGET_ID_DROP_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 77)
-#define GADGET_ID_MOVE_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 78)
-#define GADGET_ID_MOVE_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 79)
-#define GADGET_ID_MOVE_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 80)
-#define GADGET_ID_MOVE_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 81)
-#define GADGET_ID_MOVE_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 82)
-#define GADGET_ID_MOVE_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 83)
-#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 84)
-#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 85)
-#define GADGET_ID_EXPLOSION_DELAY_UP   (GADGET_ID_COUNTER_FIRST + 86)
-#define GADGET_ID_IGNITION_DELAY_DOWN  (GADGET_ID_COUNTER_FIRST + 87)
-#define GADGET_ID_IGNITION_DELAY_TEXT  (GADGET_ID_COUNTER_FIRST + 88)
-#define GADGET_ID_IGNITION_DELAY_UP    (GADGET_ID_COUNTER_FIRST + 89)
-#define GADGET_ID_CHANGE_DELAY_FIX_DOWN        (GADGET_ID_COUNTER_FIRST + 90)
-#define GADGET_ID_CHANGE_DELAY_FIX_TEXT        (GADGET_ID_COUNTER_FIRST + 91)
-#define GADGET_ID_CHANGE_DELAY_FIX_UP  (GADGET_ID_COUNTER_FIRST + 92)
-#define GADGET_ID_CHANGE_DELAY_RND_DOWN        (GADGET_ID_COUNTER_FIRST + 93)
-#define GADGET_ID_CHANGE_DELAY_RND_TEXT        (GADGET_ID_COUNTER_FIRST + 94)
-#define GADGET_ID_CHANGE_DELAY_RND_UP  (GADGET_ID_COUNTER_FIRST + 95)
-#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 96)
-#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 97)
-#define GADGET_ID_CHANGE_CONT_RND_UP   (GADGET_ID_COUNTER_FIRST + 98)
-#define GADGET_ID_GROUP_CONTENT_DOWN   (GADGET_ID_COUNTER_FIRST + 99)
-#define GADGET_ID_GROUP_CONTENT_TEXT   (GADGET_ID_COUNTER_FIRST + 100)
-#define GADGET_ID_GROUP_CONTENT_UP     (GADGET_ID_COUNTER_FIRST + 101)
+#define GADGET_ID_LEVELSET_NUM_LEVELS_DOWN (GADGET_ID_COUNTER_FIRST + 24)
+#define GADGET_ID_LEVELSET_NUM_LEVELS_TEXT (GADGET_ID_COUNTER_FIRST + 25)
+#define GADGET_ID_LEVELSET_NUM_LEVELS_UP   (GADGET_ID_COUNTER_FIRST + 26)
+#define GADGET_ID_ELEMENT_VALUE1_DOWN  (GADGET_ID_COUNTER_FIRST + 27)
+#define GADGET_ID_ELEMENT_VALUE1_TEXT  (GADGET_ID_COUNTER_FIRST + 28)
+#define GADGET_ID_ELEMENT_VALUE1_UP    (GADGET_ID_COUNTER_FIRST + 29)
+#define GADGET_ID_ELEMENT_VALUE2_DOWN  (GADGET_ID_COUNTER_FIRST + 30)
+#define GADGET_ID_ELEMENT_VALUE2_TEXT  (GADGET_ID_COUNTER_FIRST + 31)
+#define GADGET_ID_ELEMENT_VALUE2_UP    (GADGET_ID_COUNTER_FIRST + 32)
+#define GADGET_ID_ELEMENT_VALUE3_DOWN  (GADGET_ID_COUNTER_FIRST + 33)
+#define GADGET_ID_ELEMENT_VALUE3_TEXT  (GADGET_ID_COUNTER_FIRST + 34)
+#define GADGET_ID_ELEMENT_VALUE3_UP    (GADGET_ID_COUNTER_FIRST + 35)
+#define GADGET_ID_ELEMENT_VALUE4_DOWN  (GADGET_ID_COUNTER_FIRST + 36)
+#define GADGET_ID_ELEMENT_VALUE4_TEXT  (GADGET_ID_COUNTER_FIRST + 37)
+#define GADGET_ID_ELEMENT_VALUE4_UP    (GADGET_ID_COUNTER_FIRST + 38)
+#define GADGET_ID_YAMYAM_CONTENT_DOWN  (GADGET_ID_COUNTER_FIRST + 39)
+#define GADGET_ID_YAMYAM_CONTENT_TEXT  (GADGET_ID_COUNTER_FIRST + 40)
+#define GADGET_ID_YAMYAM_CONTENT_UP    (GADGET_ID_COUNTER_FIRST + 41)
+#define GADGET_ID_BALL_CONTENT_DOWN    (GADGET_ID_COUNTER_FIRST + 42)
+#define GADGET_ID_BALL_CONTENT_TEXT    (GADGET_ID_COUNTER_FIRST + 43)
+#define GADGET_ID_BALL_CONTENT_UP      (GADGET_ID_COUNTER_FIRST + 44)
+#define GADGET_ID_ANDROID_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 45)
+#define GADGET_ID_ANDROID_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 46)
+#define GADGET_ID_ANDROID_CONTENT_UP   (GADGET_ID_COUNTER_FIRST + 47)
+#define GADGET_ID_ENVELOPE_XSIZE_DOWN  (GADGET_ID_COUNTER_FIRST + 48)
+#define GADGET_ID_ENVELOPE_XSIZE_TEXT  (GADGET_ID_COUNTER_FIRST + 49)
+#define GADGET_ID_ENVELOPE_XSIZE_UP    (GADGET_ID_COUNTER_FIRST + 50)
+#define GADGET_ID_ENVELOPE_YSIZE_DOWN  (GADGET_ID_COUNTER_FIRST + 51)
+#define GADGET_ID_ENVELOPE_YSIZE_TEXT  (GADGET_ID_COUNTER_FIRST + 52)
+#define GADGET_ID_ENVELOPE_YSIZE_UP    (GADGET_ID_COUNTER_FIRST + 53)
+#define GADGET_ID_INVENTORY_SIZE_DOWN  (GADGET_ID_COUNTER_FIRST + 54)
+#define GADGET_ID_INVENTORY_SIZE_TEXT  (GADGET_ID_COUNTER_FIRST + 55)
+#define GADGET_ID_INVENTORY_SIZE_UP    (GADGET_ID_COUNTER_FIRST + 56)
+#define GADGET_ID_CUSTOM_SCORE_DOWN    (GADGET_ID_COUNTER_FIRST + 57)
+#define GADGET_ID_CUSTOM_SCORE_TEXT    (GADGET_ID_COUNTER_FIRST + 58)
+#define GADGET_ID_CUSTOM_SCORE_UP      (GADGET_ID_COUNTER_FIRST + 59)
+#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 60)
+#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 61)
+#define GADGET_ID_CUSTOM_GEMCOUNT_UP   (GADGET_ID_COUNTER_FIRST + 62)
+#define GADGET_ID_CUSTOM_VALUE_FIX_DOWN        (GADGET_ID_COUNTER_FIRST + 63)
+#define GADGET_ID_CUSTOM_VALUE_FIX_TEXT        (GADGET_ID_COUNTER_FIRST + 64)
+#define GADGET_ID_CUSTOM_VALUE_FIX_UP  (GADGET_ID_COUNTER_FIRST + 65)
+#define GADGET_ID_CUSTOM_VALUE_RND_DOWN        (GADGET_ID_COUNTER_FIRST + 66)
+#define GADGET_ID_CUSTOM_VALUE_RND_TEXT        (GADGET_ID_COUNTER_FIRST + 67)
+#define GADGET_ID_CUSTOM_VALUE_RND_UP  (GADGET_ID_COUNTER_FIRST + 68)
+#define GADGET_ID_PUSH_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 69)
+#define GADGET_ID_PUSH_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 70)
+#define GADGET_ID_PUSH_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 71)
+#define GADGET_ID_PUSH_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 72)
+#define GADGET_ID_PUSH_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 73)
+#define GADGET_ID_PUSH_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 74)
+#define GADGET_ID_DROP_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 75)
+#define GADGET_ID_DROP_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 76)
+#define GADGET_ID_DROP_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 77)
+#define GADGET_ID_DROP_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 78)
+#define GADGET_ID_DROP_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 79)
+#define GADGET_ID_DROP_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 80)
+#define GADGET_ID_MOVE_DELAY_FIX_DOWN  (GADGET_ID_COUNTER_FIRST + 81)
+#define GADGET_ID_MOVE_DELAY_FIX_TEXT  (GADGET_ID_COUNTER_FIRST + 82)
+#define GADGET_ID_MOVE_DELAY_FIX_UP    (GADGET_ID_COUNTER_FIRST + 83)
+#define GADGET_ID_MOVE_DELAY_RND_DOWN  (GADGET_ID_COUNTER_FIRST + 84)
+#define GADGET_ID_MOVE_DELAY_RND_TEXT  (GADGET_ID_COUNTER_FIRST + 85)
+#define GADGET_ID_MOVE_DELAY_RND_UP    (GADGET_ID_COUNTER_FIRST + 86)
+#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 87)
+#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 88)
+#define GADGET_ID_EXPLOSION_DELAY_UP   (GADGET_ID_COUNTER_FIRST + 89)
+#define GADGET_ID_IGNITION_DELAY_DOWN  (GADGET_ID_COUNTER_FIRST + 90)
+#define GADGET_ID_IGNITION_DELAY_TEXT  (GADGET_ID_COUNTER_FIRST + 91)
+#define GADGET_ID_IGNITION_DELAY_UP    (GADGET_ID_COUNTER_FIRST + 92)
+#define GADGET_ID_CHANGE_DELAY_FIX_DOWN        (GADGET_ID_COUNTER_FIRST + 93)
+#define GADGET_ID_CHANGE_DELAY_FIX_TEXT        (GADGET_ID_COUNTER_FIRST + 94)
+#define GADGET_ID_CHANGE_DELAY_FIX_UP  (GADGET_ID_COUNTER_FIRST + 95)
+#define GADGET_ID_CHANGE_DELAY_RND_DOWN        (GADGET_ID_COUNTER_FIRST + 96)
+#define GADGET_ID_CHANGE_DELAY_RND_TEXT        (GADGET_ID_COUNTER_FIRST + 97)
+#define GADGET_ID_CHANGE_DELAY_RND_UP  (GADGET_ID_COUNTER_FIRST + 98)
+#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 99)
+#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 100)
+#define GADGET_ID_CHANGE_CONT_RND_UP   (GADGET_ID_COUNTER_FIRST + 101)
+#define GADGET_ID_GROUP_CONTENT_DOWN   (GADGET_ID_COUNTER_FIRST + 102)
+#define GADGET_ID_GROUP_CONTENT_TEXT   (GADGET_ID_COUNTER_FIRST + 103)
+#define GADGET_ID_GROUP_CONTENT_UP     (GADGET_ID_COUNTER_FIRST + 104)
 
 /* drawing area identifiers */
-#define GADGET_ID_DRAWING_AREA_FIRST   (GADGET_ID_COUNTER_FIRST + 102)
+#define GADGET_ID_DRAWING_AREA_FIRST   (GADGET_ID_COUNTER_FIRST + 105)
 
 #define GADGET_ID_DRAWING_LEVEL                (GADGET_ID_DRAWING_AREA_FIRST + 0)
 #define GADGET_ID_YAMYAM_CONTENT_0     (GADGET_ID_DRAWING_AREA_FIRST + 1)
 
 #define GADGET_ID_LEVEL_NAME           (GADGET_ID_TEXT_INPUT_FIRST + 0)
 #define GADGET_ID_LEVEL_AUTHOR         (GADGET_ID_TEXT_INPUT_FIRST + 1)
-#define GADGET_ID_ELEMENT_NAME         (GADGET_ID_TEXT_INPUT_FIRST + 2)
+#define GADGET_ID_LEVELSET_NAME                (GADGET_ID_TEXT_INPUT_FIRST + 2)
+#define GADGET_ID_LEVELSET_AUTHOR      (GADGET_ID_TEXT_INPUT_FIRST + 3)
+#define GADGET_ID_ELEMENT_NAME         (GADGET_ID_TEXT_INPUT_FIRST + 4)
 
 /* text area identifiers */
-#define GADGET_ID_TEXT_AREA_FIRST      (GADGET_ID_TEXT_INPUT_FIRST + 3)
+#define GADGET_ID_TEXT_AREA_FIRST      (GADGET_ID_TEXT_INPUT_FIRST + 5)
 
 #define GADGET_ID_ENVELOPE_INFO                (GADGET_ID_TEXT_AREA_FIRST + 0)
 
 
 #define GADGET_ID_TIME_OR_STEPS                (GADGET_ID_SELECTBOX_FIRST + 0)
 #define GADGET_ID_GAME_ENGINE_TYPE     (GADGET_ID_SELECTBOX_FIRST + 1)
-#define GADGET_ID_WIND_DIRECTION       (GADGET_ID_SELECTBOX_FIRST + 2)
-#define GADGET_ID_PLAYER_SPEED         (GADGET_ID_SELECTBOX_FIRST + 3)
-#define GADGET_ID_CUSTOM_WALK_TO_ACTION        (GADGET_ID_SELECTBOX_FIRST + 4)
-#define GADGET_ID_CUSTOM_EXPLOSION_TYPE        (GADGET_ID_SELECTBOX_FIRST + 5)
-#define GADGET_ID_CUSTOM_DEADLINESS    (GADGET_ID_SELECTBOX_FIRST + 6)
-#define GADGET_ID_CUSTOM_MOVE_PATTERN  (GADGET_ID_SELECTBOX_FIRST + 7)
-#define GADGET_ID_CUSTOM_MOVE_DIRECTION        (GADGET_ID_SELECTBOX_FIRST + 8)
-#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 9)
-#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 10)
-#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 11)
-#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 12)
-#define GADGET_ID_CUSTOM_ACCESS_TYPE   (GADGET_ID_SELECTBOX_FIRST + 13)
-#define GADGET_ID_CUSTOM_ACCESS_LAYER  (GADGET_ID_SELECTBOX_FIRST + 14)
-#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 15)
-#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 16)
-#define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 17)
-#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 18)
-#define GADGET_ID_CHANGE_OTHER_ACTION  (GADGET_ID_SELECTBOX_FIRST + 19)
-#define GADGET_ID_CHANGE_SIDE          (GADGET_ID_SELECTBOX_FIRST + 20)
-#define GADGET_ID_CHANGE_PLAYER                (GADGET_ID_SELECTBOX_FIRST + 21)
-#define GADGET_ID_CHANGE_PAGE          (GADGET_ID_SELECTBOX_FIRST + 22)
-#define GADGET_ID_CHANGE_REPLACE_WHEN  (GADGET_ID_SELECTBOX_FIRST + 23)
-#define GADGET_ID_ACTION_TYPE          (GADGET_ID_SELECTBOX_FIRST + 24)
-#define GADGET_ID_ACTION_MODE          (GADGET_ID_SELECTBOX_FIRST + 25)
-#define GADGET_ID_ACTION_ARG           (GADGET_ID_SELECTBOX_FIRST + 26)
-#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 27)
-#define GADGET_ID_GROUP_CHOICE_MODE    (GADGET_ID_SELECTBOX_FIRST + 28)
+#define GADGET_ID_LEVELSET_SAVE_MODE   (GADGET_ID_SELECTBOX_FIRST + 2)
+#define GADGET_ID_WIND_DIRECTION       (GADGET_ID_SELECTBOX_FIRST + 3)
+#define GADGET_ID_PLAYER_SPEED         (GADGET_ID_SELECTBOX_FIRST + 4)
+#define GADGET_ID_CUSTOM_WALK_TO_ACTION        (GADGET_ID_SELECTBOX_FIRST + 5)
+#define GADGET_ID_CUSTOM_EXPLOSION_TYPE        (GADGET_ID_SELECTBOX_FIRST + 6)
+#define GADGET_ID_CUSTOM_DEADLINESS    (GADGET_ID_SELECTBOX_FIRST + 7)
+#define GADGET_ID_CUSTOM_MOVE_PATTERN  (GADGET_ID_SELECTBOX_FIRST + 8)
+#define GADGET_ID_CUSTOM_MOVE_DIRECTION        (GADGET_ID_SELECTBOX_FIRST + 9)
+#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 10)
+#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 11)
+#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 12)
+#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 13)
+#define GADGET_ID_CUSTOM_ACCESS_TYPE   (GADGET_ID_SELECTBOX_FIRST + 14)
+#define GADGET_ID_CUSTOM_ACCESS_LAYER  (GADGET_ID_SELECTBOX_FIRST + 15)
+#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 16)
+#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 17)
+#define GADGET_ID_CHANGE_TIME_UNITS    (GADGET_ID_SELECTBOX_FIRST + 18)
+#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 19)
+#define GADGET_ID_CHANGE_OTHER_ACTION  (GADGET_ID_SELECTBOX_FIRST + 20)
+#define GADGET_ID_CHANGE_SIDE          (GADGET_ID_SELECTBOX_FIRST + 21)
+#define GADGET_ID_CHANGE_PLAYER                (GADGET_ID_SELECTBOX_FIRST + 22)
+#define GADGET_ID_CHANGE_PAGE          (GADGET_ID_SELECTBOX_FIRST + 23)
+#define GADGET_ID_CHANGE_REPLACE_WHEN  (GADGET_ID_SELECTBOX_FIRST + 24)
+#define GADGET_ID_ACTION_TYPE          (GADGET_ID_SELECTBOX_FIRST + 25)
+#define GADGET_ID_ACTION_MODE          (GADGET_ID_SELECTBOX_FIRST + 26)
+#define GADGET_ID_ACTION_ARG           (GADGET_ID_SELECTBOX_FIRST + 27)
+#define GADGET_ID_SELECT_CHANGE_PAGE   (GADGET_ID_SELECTBOX_FIRST + 28)
+#define GADGET_ID_GROUP_CHOICE_MODE    (GADGET_ID_SELECTBOX_FIRST + 29)
 
 /* textbutton identifiers */
-#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 29)
+#define GADGET_ID_TEXTBUTTON_FIRST     (GADGET_ID_SELECTBOX_FIRST + 30)
 
 #define GADGET_ID_LEVELINFO_LEVEL      (GADGET_ID_TEXTBUTTON_FIRST + 0)
-#define GADGET_ID_LEVELINFO_EDITOR     (GADGET_ID_TEXTBUTTON_FIRST + 1)
-#define GADGET_ID_PROPERTIES_INFO      (GADGET_ID_TEXTBUTTON_FIRST + 2)
-#define GADGET_ID_PROPERTIES_CONFIG    (GADGET_ID_TEXTBUTTON_FIRST + 3)
-#define GADGET_ID_PROPERTIES_CONFIG_1  (GADGET_ID_TEXTBUTTON_FIRST + 4)
-#define GADGET_ID_PROPERTIES_CONFIG_2  (GADGET_ID_TEXTBUTTON_FIRST + 5)
-#define GADGET_ID_PROPERTIES_CHANGE    (GADGET_ID_TEXTBUTTON_FIRST + 6)
-#define GADGET_ID_SAVE_AS_TEMPLATE_1   (GADGET_ID_TEXTBUTTON_FIRST + 7)
-#define GADGET_ID_SAVE_AS_TEMPLATE_2   (GADGET_ID_TEXTBUTTON_FIRST + 8)
-#define GADGET_ID_ADD_CHANGE_PAGE      (GADGET_ID_TEXTBUTTON_FIRST + 9)
-#define GADGET_ID_DEL_CHANGE_PAGE      (GADGET_ID_TEXTBUTTON_FIRST + 10)
+#define GADGET_ID_LEVELINFO_LEVELSET   (GADGET_ID_TEXTBUTTON_FIRST + 1)
+#define GADGET_ID_LEVELINFO_EDITOR     (GADGET_ID_TEXTBUTTON_FIRST + 2)
+#define GADGET_ID_PROPERTIES_INFO      (GADGET_ID_TEXTBUTTON_FIRST + 3)
+#define GADGET_ID_PROPERTIES_CONFIG    (GADGET_ID_TEXTBUTTON_FIRST + 4)
+#define GADGET_ID_PROPERTIES_CONFIG_1  (GADGET_ID_TEXTBUTTON_FIRST + 5)
+#define GADGET_ID_PROPERTIES_CONFIG_2  (GADGET_ID_TEXTBUTTON_FIRST + 6)
+#define GADGET_ID_PROPERTIES_CHANGE    (GADGET_ID_TEXTBUTTON_FIRST + 7)
+#define GADGET_ID_SAVE_AS_TEMPLATE_1   (GADGET_ID_TEXTBUTTON_FIRST + 8)
+#define GADGET_ID_SAVE_AS_TEMPLATE_2   (GADGET_ID_TEXTBUTTON_FIRST + 9)
+#define GADGET_ID_SAVE_LEVELSET                (GADGET_ID_TEXTBUTTON_FIRST + 10)
+#define GADGET_ID_ADD_CHANGE_PAGE      (GADGET_ID_TEXTBUTTON_FIRST + 11)
+#define GADGET_ID_DEL_CHANGE_PAGE      (GADGET_ID_TEXTBUTTON_FIRST + 12)
 
 /* graphicbutton identifiers */
-#define GADGET_ID_GRAPHICBUTTON_FIRST  (GADGET_ID_TEXTBUTTON_FIRST + 11)
+#define GADGET_ID_GRAPHICBUTTON_FIRST  (GADGET_ID_TEXTBUTTON_FIRST + 13)
 
 #define GADGET_ID_PREV_CHANGE_PAGE     (GADGET_ID_GRAPHICBUTTON_FIRST + 0)
 #define GADGET_ID_NEXT_CHANGE_PAGE     (GADGET_ID_GRAPHICBUTTON_FIRST + 1)
 #define ED_COUNTER_ID_LEVEL_TIMELIMIT  4
 #define ED_COUNTER_ID_LEVEL_TIMESCORE  5
 #define ED_COUNTER_ID_LEVEL_RANDOM_SEED        6
-#define ED_COUNTER_ID_LEVEL_RANDOM     7
-#define ED_COUNTER_ID_ELEMENT_VALUE1   8
-#define ED_COUNTER_ID_ELEMENT_VALUE2   9
-#define ED_COUNTER_ID_ELEMENT_VALUE3   10
-#define ED_COUNTER_ID_ELEMENT_VALUE4   11
-#define ED_COUNTER_ID_YAMYAM_CONTENT   12
-#define ED_COUNTER_ID_BALL_CONTENT     13
-#define ED_COUNTER_ID_ANDROID_CONTENT  14
-#define ED_COUNTER_ID_ENVELOPE_XSIZE   15
-#define ED_COUNTER_ID_ENVELOPE_YSIZE   16
-#define ED_COUNTER_ID_INVENTORY_SIZE   17
-#define ED_COUNTER_ID_CUSTOM_SCORE     18
-#define ED_COUNTER_ID_CUSTOM_GEMCOUNT  19
-#define ED_COUNTER_ID_CUSTOM_VALUE_FIX 20
-#define ED_COUNTER_ID_CUSTOM_VALUE_RND 21
-#define ED_COUNTER_ID_PUSH_DELAY_FIX   22
-#define ED_COUNTER_ID_PUSH_DELAY_RND   23
-#define ED_COUNTER_ID_DROP_DELAY_FIX   24
-#define ED_COUNTER_ID_DROP_DELAY_RND   25
-#define ED_COUNTER_ID_MOVE_DELAY_FIX   26
-#define ED_COUNTER_ID_MOVE_DELAY_RND   27
-#define ED_COUNTER_ID_EXPLOSION_DELAY  28
-#define ED_COUNTER_ID_IGNITION_DELAY   29
-#define ED_COUNTER_ID_GROUP_CONTENT    30
-#define ED_COUNTER_ID_CHANGE_DELAY_FIX 31
-#define ED_COUNTER_ID_CHANGE_DELAY_RND 32
-#define ED_COUNTER_ID_CHANGE_CONT_RND  33
-
-#define ED_NUM_COUNTERBUTTONS          34
+#define ED_COUNTER_ID_LEVELSET_NUM_LEVELS 7
+#define ED_COUNTER_ID_LEVEL_RANDOM     8
+#define ED_COUNTER_ID_ELEMENT_VALUE1   9
+#define ED_COUNTER_ID_ELEMENT_VALUE2   10
+#define ED_COUNTER_ID_ELEMENT_VALUE3   11
+#define ED_COUNTER_ID_ELEMENT_VALUE4   12
+#define ED_COUNTER_ID_YAMYAM_CONTENT   13
+#define ED_COUNTER_ID_BALL_CONTENT     14
+#define ED_COUNTER_ID_ANDROID_CONTENT  15
+#define ED_COUNTER_ID_ENVELOPE_XSIZE   16
+#define ED_COUNTER_ID_ENVELOPE_YSIZE   17
+#define ED_COUNTER_ID_INVENTORY_SIZE   18
+#define ED_COUNTER_ID_CUSTOM_SCORE     19
+#define ED_COUNTER_ID_CUSTOM_GEMCOUNT  20
+#define ED_COUNTER_ID_CUSTOM_VALUE_FIX 21
+#define ED_COUNTER_ID_CUSTOM_VALUE_RND 22
+#define ED_COUNTER_ID_PUSH_DELAY_FIX   23
+#define ED_COUNTER_ID_PUSH_DELAY_RND   24
+#define ED_COUNTER_ID_DROP_DELAY_FIX   25
+#define ED_COUNTER_ID_DROP_DELAY_RND   26
+#define ED_COUNTER_ID_MOVE_DELAY_FIX   27
+#define ED_COUNTER_ID_MOVE_DELAY_RND   28
+#define ED_COUNTER_ID_EXPLOSION_DELAY  29
+#define ED_COUNTER_ID_IGNITION_DELAY   30
+#define ED_COUNTER_ID_GROUP_CONTENT    31
+#define ED_COUNTER_ID_CHANGE_DELAY_FIX 32
+#define ED_COUNTER_ID_CHANGE_DELAY_RND 33
+#define ED_COUNTER_ID_CHANGE_CONT_RND  34
+
+#define ED_NUM_COUNTERBUTTONS          35
 
 #define ED_COUNTER_ID_LEVEL_FIRST      ED_COUNTER_ID_LEVEL_XSIZE
 #define ED_COUNTER_ID_LEVEL_LAST       ED_COUNTER_ID_LEVEL_RANDOM_SEED
+#define ED_COUNTER_ID_LEVELSET_FIRST   ED_COUNTER_ID_LEVELSET_NUM_LEVELS
+#define ED_COUNTER_ID_LEVELSET_LAST    ED_COUNTER_ID_LEVELSET_NUM_LEVELS
 #define ED_COUNTER_ID_EDITOR_FIRST     ED_COUNTER_ID_LEVEL_RANDOM
 #define ED_COUNTER_ID_EDITOR_LAST      ED_COUNTER_ID_LEVEL_RANDOM
 
 /* values for text input gadgets */
 #define ED_TEXTINPUT_ID_LEVEL_NAME     0
 #define ED_TEXTINPUT_ID_LEVEL_AUTHOR   1
-#define ED_TEXTINPUT_ID_ELEMENT_NAME   2
+#define ED_TEXTINPUT_ID_LEVELSET_NAME  2
+#define ED_TEXTINPUT_ID_LEVELSET_AUTHOR        3
+#define ED_TEXTINPUT_ID_ELEMENT_NAME   4
 
-#define ED_NUM_TEXTINPUT               3
+#define ED_NUM_TEXTINPUT               5
 
 #define ED_TEXTINPUT_ID_LEVEL_FIRST    ED_TEXTINPUT_ID_LEVEL_NAME
 #define ED_TEXTINPUT_ID_LEVEL_LAST     ED_TEXTINPUT_ID_LEVEL_AUTHOR
 
+#define ED_TEXTINPUT_ID_LEVELSET_FIRST ED_TEXTINPUT_ID_LEVELSET_NAME
+#define ED_TEXTINPUT_ID_LEVELSET_LAST  ED_TEXTINPUT_ID_LEVELSET_AUTHOR
+
 /* values for text area gadgets */
 #define ED_TEXTAREA_ID_ENVELOPE_INFO   0
 
 /* values for selectbox gadgets */
 #define ED_SELECTBOX_ID_TIME_OR_STEPS          0
 #define ED_SELECTBOX_ID_GAME_ENGINE_TYPE       1
-#define ED_SELECTBOX_ID_WIND_DIRECTION         2
-#define ED_SELECTBOX_ID_PLAYER_SPEED           3
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE     4
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER    5
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED        6
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION        7
-#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION  8
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN    9
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION  10      
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE   11
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 12
-#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS   13
-#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE   14
-#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS      15
-#define ED_SELECTBOX_ID_CUSTOM_EXPLOSION_TYPE  16
-#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      17
-#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION   18
-#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    19
-#define ED_SELECTBOX_ID_CHANGE_SIDE            20
-#define ED_SELECTBOX_ID_CHANGE_PLAYER          21
-#define ED_SELECTBOX_ID_CHANGE_PAGE            22
-#define ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN    23
-#define ED_SELECTBOX_ID_ACTION_TYPE            24
-#define ED_SELECTBOX_ID_ACTION_MODE            25
-#define ED_SELECTBOX_ID_ACTION_ARG             26
-#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     27
-#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE      28
-
-#define ED_NUM_SELECTBOX                       29
+#define ED_SELECTBOX_ID_LEVELSET_SAVE_MODE     2
+#define ED_SELECTBOX_ID_WIND_DIRECTION         3
+#define ED_SELECTBOX_ID_PLAYER_SPEED           4
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE     5
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER    6
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED        7
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION        8
+#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION  9
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN    10
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION  11
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE   12
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 13
+#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS   14
+#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE   15
+#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS      16
+#define ED_SELECTBOX_ID_CUSTOM_EXPLOSION_TYPE  17
+#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS      18
+#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION   19
+#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION    20
+#define ED_SELECTBOX_ID_CHANGE_SIDE            21
+#define ED_SELECTBOX_ID_CHANGE_PLAYER          22
+#define ED_SELECTBOX_ID_CHANGE_PAGE            23
+#define ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN    24
+#define ED_SELECTBOX_ID_ACTION_TYPE            25
+#define ED_SELECTBOX_ID_ACTION_MODE            26
+#define ED_SELECTBOX_ID_ACTION_ARG             27
+#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE     28
+#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE      29
+
+#define ED_NUM_SELECTBOX                       30
 
 #define ED_SELECTBOX_ID_LEVEL_FIRST    ED_SELECTBOX_ID_TIME_OR_STEPS
 #define ED_SELECTBOX_ID_LEVEL_LAST     ED_SELECTBOX_ID_GAME_ENGINE_TYPE
 
+#define ED_SELECTBOX_ID_LEVELSET_FIRST ED_SELECTBOX_ID_LEVELSET_SAVE_MODE
+#define ED_SELECTBOX_ID_LEVELSET_LAST  ED_SELECTBOX_ID_LEVELSET_SAVE_MODE
+
 #define ED_SELECTBOX_ID_CUSTOM1_FIRST  ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE
 #define ED_SELECTBOX_ID_CUSTOM1_LAST   ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION
 #define ED_SELECTBOX_ID_CUSTOM2_FIRST  ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN
 
 /* values for textbutton gadgets */
 #define ED_TEXTBUTTON_ID_LEVELINFO_LEVEL       0
-#define ED_TEXTBUTTON_ID_LEVELINFO_EDITOR      1
-#define ED_TEXTBUTTON_ID_PROPERTIES_INFO       2
-#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG     3
-#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1   4
-#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2   5
-#define ED_TEXTBUTTON_ID_PROPERTIES_CHANGE     6
-#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2    7
-#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1    8
-#define ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE       9
-#define ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE       10
-
-#define ED_NUM_TEXTBUTTONS                     11
+#define ED_TEXTBUTTON_ID_LEVELINFO_LEVELSET    1
+#define ED_TEXTBUTTON_ID_LEVELINFO_EDITOR      2
+#define ED_TEXTBUTTON_ID_PROPERTIES_INFO       3
+#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG     4
+#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1   5
+#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2   6
+#define ED_TEXTBUTTON_ID_PROPERTIES_CHANGE     7
+#define ED_TEXTBUTTON_ID_SAVE_LEVELSET         8
+#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2    9
+#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1    10
+#define ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE       11
+#define ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE       12
+
+#define ED_NUM_TEXTBUTTONS                     13
 
 #define ED_TAB_BUTTON_ID_LEVELINFO_FIRST ED_TEXTBUTTON_ID_LEVELINFO_LEVEL
 #define ED_TAB_BUTTON_ID_LEVELINFO_LAST  ED_TEXTBUTTON_ID_LEVELINFO_EDITOR
 
 /* sub-screens in the global settings section */
 #define ED_MODE_LEVELINFO_LEVEL                ED_TEXTBUTTON_ID_LEVELINFO_LEVEL
+#define ED_MODE_LEVELINFO_LEVELSET     ED_TEXTBUTTON_ID_LEVELINFO_LEVELSET
 #define ED_MODE_LEVELINFO_EDITOR       ED_TEXTBUTTON_ID_LEVELINFO_EDITOR
 
 /* sub-screens in the element properties section */
 #define RANDOM_USE_PERCENTAGE          0
 #define RANDOM_USE_QUANTITY            1
 
+/* values for level set save mode */
+#define LEVELSET_SAVE_MODE_UPDATE      0
+#define LEVELSET_SAVE_MODE_CREATE      1
+
 /* default value for element tile size in drawing area */
 #define DEFAULT_EDITOR_TILESIZE                MINI_TILESIZE
 
@@ -1267,6 +1294,12 @@ static struct ElementChangeInfo custom_element_change;
 static struct ElementGroupInfo group_element_info;
 static struct ElementInfo custom_element;
 
+static char levelset_name[MAX_LEVEL_NAME_LEN + 1];
+static char levelset_author[MAX_LEVEL_AUTHOR_LEN + 1];
+static int levelset_num_levels = 100;
+static int levelset_first_level_nr = 1;
+static int levelset_save_mode = LEVELSET_SAVE_MODE_UPDATE;
+
 static struct
 {
   int x, y;
@@ -1339,6 +1372,14 @@ static struct
     &level.random_seed,
     NULL,                              "random seed:", "(0 => random)"
   },
+  {
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(4),
+    1,                                 MAX_LEVELS,
+    GADGET_ID_LEVELSET_NUM_LEVELS_DOWN,        GADGET_ID_LEVELSET_NUM_LEVELS_UP,
+    GADGET_ID_LEVELSET_NUM_LEVELS_TEXT,        GADGET_ID_NONE,
+    &levelset_num_levels,
+    "number of levels:",               NULL, NULL,
+  },
   {
     ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(0),
     1,                                 100,
@@ -1586,14 +1627,28 @@ static struct
     GADGET_ID_LEVEL_NAME,
     MAX_LEVEL_NAME_LEN,
     level.name,
-    "Title:", "Title"
+    "Title:", "Title for this level"
   },
   {
     ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(2),
     GADGET_ID_LEVEL_AUTHOR,
     MAX_LEVEL_AUTHOR_LEN,
     level.author,
-    "Author:", "Author"
+    "Author:", "Author for this level"
+  },
+  {
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(0),
+    GADGET_ID_LEVELSET_NAME,
+    MAX_LEVEL_NAME_LEN,
+    levelset_name,
+    "Title:", "Title for this or new level set"
+  },
+  {
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(2),
+    GADGET_ID_LEVELSET_AUTHOR,
+    MAX_LEVEL_AUTHOR_LEN,
+    levelset_author,
+    "Author:", "Author for this or new level set"
   },
   {
     -1, -1,    /* these values are not constant, but can change at runtime */
@@ -1640,6 +1695,14 @@ static struct ValueTextInfo options_game_engine_type[] =
   { -1,                                NULL                            }
 };
 
+static struct ValueTextInfo options_levelset_save_mode[] =
+{
+  { LEVELSET_SAVE_MODE_UPDATE, "Update this level set"         },
+  { LEVELSET_SAVE_MODE_CREATE, "Create new level set"          },
+
+  { -1,                                NULL                            }
+};
+
 static struct ValueTextInfo options_wind_direction[] =
 {
   { MV_START_NONE,             "none"                          },
@@ -2354,6 +2417,14 @@ static struct
     &level.game_engine_type,
     NULL, "game engine:", NULL,                "game engine"
   },
+  {
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(9),
+    GADGET_ID_LEVELSET_SAVE_MODE,      GADGET_ID_NONE,
+    -1,
+    options_levelset_save_mode,
+    &levelset_save_mode,
+    "Action:", NULL, NULL,             "action when saving level set"
+  },
 
   /* ---------- element settings: configure (several elements) ------------- */
 
@@ -2610,7 +2681,13 @@ static struct
   },
   {
     -1,                                        -1,
-    GADGET_ID_LEVELINFO_EDITOR,                GADGET_ID_LEVELINFO_LEVEL,
+    GADGET_ID_LEVELINFO_LEVELSET,      GADGET_ID_LEVELINFO_LEVEL,
+    8,                                 "Levelset",
+    NULL, NULL, NULL,                  "Update this or create new level set"
+  },
+  {
+    -1,                                        -1,
+    GADGET_ID_LEVELINFO_EDITOR,                GADGET_ID_LEVELINFO_LEVELSET,
     8,                                 "Editor",
     NULL, NULL, NULL,                  "Configure editor properties"
   },
@@ -2650,6 +2727,12 @@ static struct
 
   /* ---------- level and editor settings (buttons) ------------------------ */
 
+  {
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(9),
+    GADGET_ID_SAVE_LEVELSET,           GADGET_ID_LEVELSET_SAVE_MODE,
+    -1,                                        "Save",
+    NULL, NULL, NULL,                  "Update or create level set"
+  },
   {
     ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(6),
     GADGET_ID_SAVE_AS_TEMPLATE_2,      GADGET_ID_NONE,
@@ -8140,6 +8223,19 @@ void InitZoomLevelSettings(int zoom_tilesize)
   MAX_ED_FIELDY = getMaxEdFieldY(FALSE);
 }
 
+static void InitLevelSetInfo()
+{
+  snprintf(levelset_name,   MAX_LEVEL_NAME_LEN + 1,
+          "%s", leveldir_current->name);
+  snprintf(levelset_author, MAX_LEVEL_AUTHOR_LEN + 1,
+          "%s", leveldir_current->author);
+
+  levelset_num_levels     = leveldir_current->levels;
+  levelset_first_level_nr = leveldir_current->first_level;
+
+  levelset_save_mode = LEVELSET_SAVE_MODE_UPDATE;
+}
+
 void DrawLevelEd()
 {
   int fade_mask = REDRAW_FIELD;
@@ -8157,6 +8253,7 @@ void DrawLevelEd()
   ClearField();
 
   InitZoomLevelSettings(-1);
+  InitLevelSetInfo();
 
   OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2 | DOOR_NO_DELAY);
 
@@ -8669,6 +8766,47 @@ static void DrawLevelInfoLevel()
     MapTextInputGadget(i);
 }
 
+static void DrawLevelInfoLevelSet_DirectoryInfo()
+{
+  char *directory_text = "Level set directory:";
+  char *directory_name = leveldir_current->subdir;
+  int font1_nr = FONT_TEXT_1;
+  int font2_nr = FONT_TEXT_2;
+  int font1_height = getFontHeight(font1_nr);
+  int yoffset_above = font1_height + ED_GADGET_LINE_DISTANCE;
+  int x = ED_LEVEL_SETTINGS_X(0);
+  int y = ED_LEVEL_SETTINGS_Y(6);
+
+  if (levelset_save_mode == LEVELSET_SAVE_MODE_CREATE)
+    directory_name = getNewUserLevelSubdir();
+
+  PrintInfoText(directory_text, font1_nr, x, y - yoffset_above);
+  PrintInfoText(directory_name, font2_nr, x, y);
+}
+
+static void DrawLevelInfoLevelSet()
+{
+  int i;
+
+  /* draw counter gadgets */
+  for (i = ED_COUNTER_ID_LEVELSET_FIRST; i <= ED_COUNTER_ID_LEVELSET_LAST; i++)
+    MapCounterButtons(i);
+
+  /* draw selectbox gadgets */
+  for (i = ED_SELECTBOX_ID_LEVELSET_FIRST; i <= ED_SELECTBOX_ID_LEVELSET_LAST; i++)
+    MapSelectboxGadget(i);
+
+  /* draw text input gadgets */
+  for (i = ED_TEXTINPUT_ID_LEVELSET_FIRST; i <= ED_TEXTINPUT_ID_LEVELSET_LAST; i++)
+    MapTextInputGadget(i);
+
+  /* draw textbutton gadgets */
+  MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_LEVELSET);
+
+  /* draw info text */
+  DrawLevelInfoLevelSet_DirectoryInfo();
+}
+
 static void DrawLevelInfoEditor()
 {
   int i;
@@ -8715,7 +8853,9 @@ static void DrawLevelInfoWindow()
 
   if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVEL)
     DrawLevelInfoLevel();
-  else /* (edit_mode_levelinfo == ED_MODE_LEVELINFO_EDITOR) */
+  else if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVELSET)
+    DrawLevelInfoLevelSet();
+  else if (edit_mode_levelinfo == ED_MODE_LEVELINFO_EDITOR)
     DrawLevelInfoEditor();
 }
 
@@ -12313,8 +12453,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi)
     CopyElementPropertiesToGame(properties_element);
 
   /* do not mark level as modified for certain non-level-changing gadgets */
-  if (counter_id >= ED_COUNTER_ID_EDITOR_FIRST &&
-      counter_id <= ED_COUNTER_ID_EDITOR_LAST)
+  if ((counter_id >= ED_COUNTER_ID_LEVELSET_FIRST &&
+       counter_id <= ED_COUNTER_ID_LEVELSET_LAST) ||
+      (counter_id >= ED_COUNTER_ID_EDITOR_FIRST &&
+       counter_id <= ED_COUNTER_ID_EDITOR_LAST))
     return;
 
   level.changed = TRUE;
@@ -12333,6 +12475,11 @@ static void HandleTextInputGadgets(struct GadgetInfo *gi)
     ModifyEditorElementList(); /* update changed button info text */
   }
 
+  /* do not mark level as modified for certain non-level-changing gadgets */
+  if (type_id >= ED_TEXTINPUT_ID_LEVELSET_FIRST &&
+      type_id <= ED_TEXTINPUT_ID_LEVELSET_LAST)
+    return;
+
   level.changed = TRUE;
 }
 
@@ -12355,7 +12502,11 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi)
 
   *selectbox_info[type_id].value = value_new;
 
-  if (type_id == ED_SELECTBOX_ID_SELECT_CHANGE_PAGE)
+  if (type_id == ED_SELECTBOX_ID_LEVELSET_SAVE_MODE)
+  {
+    DrawLevelInfoWindow();
+  }
+  else if (type_id == ED_SELECTBOX_ID_SELECT_CHANGE_PAGE)
   {
     element_info[properties_element].current_change_page = gi->selectbox.index;
 
@@ -12386,7 +12537,8 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi)
   }
 
   /* do not mark level as modified for certain non-level-changing gadgets */
-  if (type_id == ED_SELECTBOX_ID_SELECT_CHANGE_PAGE)
+  if (type_id == ED_SELECTBOX_ID_LEVELSET_SAVE_MODE ||
+      type_id == ED_SELECTBOX_ID_SELECT_CHANGE_PAGE)
     return;
 
   level.changed = TRUE;
@@ -12432,6 +12584,63 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi)
     /* restore original "level.field" (needed to track playfield changes) */
     CopyPlayfield(FieldBackup, level.field);
   }
+  else if (type_id == ED_TEXTBUTTON_ID_SAVE_LEVELSET)
+  {
+    if (levelset_save_mode == LEVELSET_SAVE_MODE_UPDATE &&
+       leveldir_current->readonly)
+    {
+      Request("This level set is read only!", REQ_CONFIRM);
+
+      return;
+    }
+
+    if (strEqual(levelset_name, ""))
+    {
+      Request("Please enter level set title!", REQ_CONFIRM);
+
+      return;
+    }
+
+    if (strEqual(levelset_author, ""))
+    {
+      Request("Please enter level set author!", REQ_CONFIRM);
+
+      return;
+    }
+
+    if (levelset_save_mode == LEVELSET_SAVE_MODE_UPDATE)
+    {
+      if (UpdateUserLevelSet(leveldir_current->subdir,
+                            levelset_name,
+                            levelset_author,
+                            levelset_num_levels,
+                            levelset_first_level_nr))
+      {
+       Request("Level set updated!", REQ_CONFIRM);
+      }
+      else
+      {
+       Request("Updating level set failed!", REQ_CONFIRM);
+      }
+    }
+    else
+    {
+      if (CreateUserLevelSet(getNewUserLevelSubdir(),
+                            levelset_name,
+                            levelset_author,
+                            levelset_num_levels,
+                            levelset_first_level_nr))
+      {
+       Request("New level set created!", REQ_CONFIRM);
+      }
+      else
+      {
+       Request("Creating new level set failed!", REQ_CONFIRM);
+      }
+
+      DrawLevelInfoWindow();   // update (increment) level set directory name
+    }
+  }
   else if (type_id == ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE &&
           custom_element.num_change_pages < MAX_CHANGE_PAGES)
   {
index 54e5eeeea21f6d9e51ed870c1c4fbd187a16eeb9..5784ac496183c72cf174fecd4649a923f3648908 100644 (file)
@@ -202,6 +202,28 @@ char *getCurrentLevelDir()
   return getLevelDirFromTreeInfo(leveldir_current);
 }
 
+char *getNewUserLevelSubdir()
+{
+  static char *new_level_subdir = NULL;
+  char *subdir_prefix = getLoginName();
+  char subdir_suffix[10];
+  int max_suffix_number = 1000;
+  int i = 0;
+
+  while (++i < max_suffix_number)
+  {
+    sprintf(subdir_suffix, "_%d", i);
+
+    checked_free(new_level_subdir);
+    new_level_subdir = getStringCat2(subdir_prefix, subdir_suffix);
+
+    if (!directoryExists(getUserLevelDir(new_level_subdir)))
+      break;
+  }
+
+  return new_level_subdir;
+}
+
 static char *getTapeDir(char *level_subdir)
 {
   static char *tape_dir = NULL;
index 8dbd1694133a0fa4b56506b049ae972fed5f201d..5679506daccf361bf41d10c78f48750484e91a6d 100644 (file)
@@ -271,6 +271,7 @@ char *getPersonalDataDir(void);
 char *getUserGameDataDir(void);
 char *getSetupDir(void);
 char *getCurrentLevelDir(void);
+char *getNewUserLevelSubdir(void);
 
 void createDirectory(char *, char *, int);
 void InitUserDataDirectory(void);