added support for amoeba settings in BD engine to level editor
[rocksndiamonds.git] / src / editor.c
index ca5e06b9b778d097517f190b87a78bc3d7c5f121..6e24056011ad3e6ccc4e2e3f0a50fbf25dd87e90 100644 (file)
@@ -429,6 +429,24 @@ enum
   GADGET_ID_LEVELSET_NUM_LEVELS_DOWN,
   GADGET_ID_LEVELSET_NUM_LEVELS_TEXT,
   GADGET_ID_LEVELSET_NUM_LEVELS_UP,
+  GADGET_ID_BD_CYCLE_DELAY_MS_DOWN,
+  GADGET_ID_BD_CYCLE_DELAY_MS_TEXT,
+  GADGET_ID_BD_CYCLE_DELAY_MS_UP,
+  GADGET_ID_BD_CYCLE_DELAY_C64_DOWN,
+  GADGET_ID_BD_CYCLE_DELAY_C64_TEXT,
+  GADGET_ID_BD_CYCLE_DELAY_C64_UP,
+  GADGET_ID_BD_HATCHING_DELAY_CYCLES_DOWN,
+  GADGET_ID_BD_HATCHING_DELAY_CYCLES_TEXT,
+  GADGET_ID_BD_HATCHING_DELAY_CYCLES_UP,
+  GADGET_ID_BD_HATCHING_DELAY_SECONDS_DOWN,
+  GADGET_ID_BD_HATCHING_DELAY_SECONDS_TEXT,
+  GADGET_ID_BD_HATCHING_DELAY_SECONDS_UP,
+  GADGET_ID_BD_PUSHING_PROB_DOWN,
+  GADGET_ID_BD_PUSHING_PROB_TEXT,
+  GADGET_ID_BD_PUSHING_PROB_UP,
+  GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_DOWN,
+  GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_TEXT,
+  GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_UP,
   GADGET_ID_ELEMENT_VALUE1_DOWN,
   GADGET_ID_ELEMENT_VALUE1_TEXT,
   GADGET_ID_ELEMENT_VALUE1_UP,
@@ -538,6 +556,12 @@ enum
   GADGET_ID_MAGIC_BALL_CONTENT_7,
   GADGET_ID_ANDROID_CONTENT,
   GADGET_ID_AMOEBA_CONTENT,
+  GADGET_ID_BD_AMOEBA_CONTENT_TOO_BIG,
+  GADGET_ID_BD_AMOEBA_CONTENT_ENCLOSED,
+  GADGET_ID_BD_AMOEBA_2_CONTENT_TOO_BIG,
+  GADGET_ID_BD_AMOEBA_2_CONTENT_ENCLOSED,
+  GADGET_ID_BD_AMOEBA_2_CONTENT_EXPLODING,
+  GADGET_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE,
   GADGET_ID_START_ELEMENT,
   GADGET_ID_ARTWORK_ELEMENT,
   GADGET_ID_EXPLOSION_ELEMENT,
@@ -571,6 +595,7 @@ enum
   GADGET_ID_TIME_OR_STEPS,
   GADGET_ID_TIME_SCORE_BASE,
   GADGET_ID_GAME_ENGINE_TYPE,
+  GADGET_ID_BD_SCHEDULING_TYPE,
   GADGET_ID_LEVELSET_SAVE_MODE,
   GADGET_ID_WIND_DIRECTION,
   GADGET_ID_PLAYER_SPEED,
@@ -650,6 +675,11 @@ enum
   GADGET_ID_RANDOM_QUANTITY,
   GADGET_ID_RANDOM_RESTRICTED,
   GADGET_ID_BD_INTERMISSION,
+  GADGET_ID_BD_PAL_TIMING,
+  GADGET_ID_BD_LINE_SHIFTING_BORDERS,
+  GADGET_ID_BD_SCAN_FIRST_AND_LAST_ROW,
+  GADGET_ID_BD_SHORT_EXPLOSIONS,
+  GADGET_ID_BD_GRAVITY_AFFECTS_ALL,
   GADGET_ID_STICK_ELEMENT,
   GADGET_ID_EM_SLIPPERY_GEMS,
   GADGET_ID_EM_EXPLODES_BY_FIRE,
@@ -682,6 +712,13 @@ enum
   GADGET_ID_CAN_MOVE_INTO_ACID,
   GADGET_ID_DONT_COLLIDE_WITH,
   GADGET_ID_BD_DIAGONAL_MOVEMENTS,
+  GADGET_ID_BD_TOPMOST_PLAYER_ACTIVE,
+  GADGET_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET,
+  GADGET_ID_BD_MAGIC_WALL_WAIT_HATCHING,
+  GADGET_ID_BD_MAGIC_WALL_STOPS_AMOEBA,
+  GADGET_ID_BD_AMOEBA_WAIT_FOR_HATCHING,
+  GADGET_ID_BD_AMOEBA_START_IMMEDIATELY,
+  GADGET_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA,
   GADGET_ID_ENVELOPE_AUTOWRAP,
   GADGET_ID_ENVELOPE_CENTERED,
   GADGET_ID_MM_LASER_RED,
@@ -750,6 +787,12 @@ enum
   ED_COUNTER_ID_LEVEL_RANDOM_SEED,
   ED_COUNTER_ID_LEVELSET_NUM_LEVELS,
   ED_COUNTER_ID_LEVEL_RANDOM,
+  ED_COUNTER_ID_BD_CYCLE_DELAY_MS,
+  ED_COUNTER_ID_BD_CYCLE_DELAY_C64,
+  ED_COUNTER_ID_BD_HATCHING_DELAY_CYCLES,
+  ED_COUNTER_ID_BD_HATCHING_DELAY_SECONDS,
+  ED_COUNTER_ID_BD_PUSHING_PROB,
+  ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET,
   ED_COUNTER_ID_ELEMENT_VALUE1,
   ED_COUNTER_ID_ELEMENT_VALUE2,
   ED_COUNTER_ID_ELEMENT_VALUE3,
@@ -864,6 +907,7 @@ enum
   ED_SELECTBOX_ID_TIME_OR_STEPS,
   ED_SELECTBOX_ID_TIME_SCORE_BASE,
   ED_SELECTBOX_ID_GAME_ENGINE_TYPE,
+  ED_SELECTBOX_ID_BD_SCHEDULING_TYPE,
   ED_SELECTBOX_ID_LEVELSET_SAVE_MODE,
   ED_SELECTBOX_ID_WIND_DIRECTION,
   ED_SELECTBOX_ID_PLAYER_SPEED,
@@ -903,6 +947,9 @@ enum
 #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_ENGINE_FIRST   ED_SELECTBOX_ID_BD_SCHEDULING_TYPE
+#define ED_SELECTBOX_ID_ENGINE_LAST    ED_SELECTBOX_ID_BD_SCHEDULING_TYPE
+
 #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
@@ -968,6 +1015,11 @@ enum
   ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_3,
   ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2,
   ED_CHECKBUTTON_ID_BD_INTERMISSION,
+  ED_CHECKBUTTON_ID_BD_PAL_TIMING,
+  ED_CHECKBUTTON_ID_BD_LINE_SHIFTING_BORDERS,
+  ED_CHECKBUTTON_ID_BD_SCAN_FIRST_AND_LAST_ROW,
+  ED_CHECKBUTTON_ID_BD_SHORT_EXPLOSIONS,
+  ED_CHECKBUTTON_ID_BD_GRAVITY_AFFECTS_ALL,
   ED_CHECKBUTTON_ID_STICK_ELEMENT,
   ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS,
   ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE,
@@ -1000,6 +1052,13 @@ enum
   ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID,
   ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH,
   ED_CHECKBUTTON_ID_BD_DIAGONAL_MOVEMENTS,
+  ED_CHECKBUTTON_ID_BD_TOPMOST_PLAYER_ACTIVE,
+  ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET,
+  ED_CHECKBUTTON_ID_BD_MAGIC_WALL_WAIT_HATCHING,
+  ED_CHECKBUTTON_ID_BD_MAGIC_WALL_STOPS_AMOEBA,
+  ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING,
+  ED_CHECKBUTTON_ID_BD_AMOEBA_START_IMMEDIATELY,
+  ED_CHECKBUTTON_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA,
   ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP,
   ED_CHECKBUTTON_ID_ENVELOPE_CENTERED,
   ED_CHECKBUTTON_ID_MM_LASER_RED,
@@ -1049,7 +1108,7 @@ enum
 #define ED_CHECKBUTTON_ID_EDITOR_LAST  ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2
 
 #define ED_CHECKBUTTON_ID_ENGINE_FIRST ED_CHECKBUTTON_ID_BD_INTERMISSION
-#define ED_CHECKBUTTON_ID_ENGINE_LAST  ED_CHECKBUTTON_ID_BD_INTERMISSION
+#define ED_CHECKBUTTON_ID_ENGINE_LAST  ED_CHECKBUTTON_ID_BD_GRAVITY_AFFECTS_ALL
 
 #define ED_CHECKBUTTON_ID_CUSTOM1_FIRST        ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC
 #define ED_CHECKBUTTON_ID_CUSTOM1_LAST ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE
@@ -1095,6 +1154,12 @@ enum
   ED_DRAWING_ID_MAGIC_BALL_CONTENT_7,
   ED_DRAWING_ID_ANDROID_CONTENT,
   ED_DRAWING_ID_AMOEBA_CONTENT,
+  ED_DRAWING_ID_BD_AMOEBA_CONTENT_TOO_BIG,
+  ED_DRAWING_ID_BD_AMOEBA_CONTENT_ENCLOSED,
+  ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_TOO_BIG,
+  ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_ENCLOSED,
+  ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_EXPLODING,
+  ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE,
   ED_DRAWING_ID_START_ELEMENT,
   ED_DRAWING_ID_ARTWORK_ELEMENT,
   ED_DRAWING_ID_EXPLOSION_ELEMENT,
@@ -1482,9 +1547,63 @@ static struct
     &random_placement_value,
     "random element placement:",       NULL, "in"
   },
+  {
+    ED_COUNTER_ID_BD_CYCLE_DELAY_MS,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(3),
+    50,                                        500,
+    GADGET_ID_BD_CYCLE_DELAY_MS_DOWN,  GADGET_ID_BD_CYCLE_DELAY_MS_UP,
+    GADGET_ID_BD_CYCLE_DELAY_MS_TEXT,  GADGET_ID_NONE,
+    &level.bd_cycle_delay_ms,
+    NULL,                              NULL, "game cycle delay (ms)"
+  },
+  {
+    ED_COUNTER_ID_BD_CYCLE_DELAY_C64,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(3),
+    0,                                 32,
+    GADGET_ID_BD_CYCLE_DELAY_C64_DOWN, GADGET_ID_BD_CYCLE_DELAY_C64_UP,
+    GADGET_ID_BD_CYCLE_DELAY_C64_TEXT, GADGET_ID_NONE,
+    &level.bd_cycle_delay_c64,
+    NULL,                              NULL, "game cycle delay (C64-style)"
+  },
+  {
+    ED_COUNTER_ID_BD_HATCHING_DELAY_CYCLES,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(4),
+    1,                                 40,
+    GADGET_ID_BD_HATCHING_DELAY_CYCLES_DOWN,   GADGET_ID_BD_HATCHING_DELAY_CYCLES_UP,
+    GADGET_ID_BD_HATCHING_DELAY_CYCLES_TEXT,   GADGET_ID_NONE,
+    &level.bd_hatching_delay_cycles,
+    NULL,                              NULL, "hatching delay (cycles)"
+  },
+  {
+    ED_COUNTER_ID_BD_HATCHING_DELAY_SECONDS,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(4),
+    1,                                 40,
+    GADGET_ID_BD_HATCHING_DELAY_SECONDS_DOWN,  GADGET_ID_BD_HATCHING_DELAY_SECONDS_UP,
+    GADGET_ID_BD_HATCHING_DELAY_SECONDS_TEXT,  GADGET_ID_NONE,
+    &level.bd_hatching_delay_seconds,
+    NULL,                              NULL, "hatching delay (seconds)"
+  },
 
   // ---------- element settings: configure (various elements) ----------------
 
+  {
+    ED_COUNTER_ID_BD_PUSHING_PROB,
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(2),
+    0,                                 100,
+    GADGET_ID_BD_PUSHING_PROB_DOWN,    GADGET_ID_BD_PUSHING_PROB_UP,
+    GADGET_ID_BD_PUSHING_PROB_TEXT,    GADGET_ID_NONE,
+    &level.bd_pushing_prob,
+    NULL,                              NULL, "push probability"
+  },
+  {
+    ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET,
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(3),
+    0,                                 100,
+    GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_DOWN, GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_UP,
+    GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_TEXT, GADGET_ID_NONE,
+    &level.bd_pushing_prob_with_sweet,
+    NULL,                              NULL, "push probability with sweet"
+  },
   {
     ED_COUNTER_ID_ELEMENT_VALUE1,
     ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(0),
@@ -2528,6 +2647,19 @@ static struct ValueTextInfo options_group_choice_mode[] =
   { -1,                                NULL                            }
 };
 
+static struct ValueTextInfo options_bd_scheduling_type[] =
+{
+  { GD_SCHEDULING_MILLISECONDS,          "Milliseconds"                },
+  { GD_SCHEDULING_BD1,           "BD1"                         },
+  { GD_SCHEDULING_BD2,           "BD2"                         },
+  { GD_SCHEDULING_PLCK,                  "Construction Kit"            },
+  { GD_SCHEDULING_CRDR,                  "Crazy Dream 7"               },
+  { GD_SCHEDULING_BD1_ATARI,     "Atari BD1"                   },
+  { GD_SCHEDULING_BD2_PLCK_ATARI, "Atari BD2 / PLCK"           },
+
+  { -1,                                  NULL                          }
+};
+
 static struct ValueTextInfo *action_arg_modes[] =
 {
   options_action_mode_none,
@@ -2611,6 +2743,15 @@ static struct
     &level.game_engine_type,
     NULL, "game engine:", NULL,                "game engine"
   },
+  {
+    ED_SELECTBOX_ID_BD_SCHEDULING_TYPE,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(1),
+    GADGET_ID_BD_SCHEDULING_TYPE,      GADGET_ID_NONE,
+    -1,
+    options_bd_scheduling_type,
+    &level.bd_scheduling_type,
+    NULL, "scheduling type:", NULL,    "level timing"
+  },
   {
     ED_SELECTBOX_ID_LEVELSET_SAVE_MODE,
     ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(10),
@@ -3254,6 +3395,46 @@ static struct
     "Boulder Dash game engine settings:", NULL,
     "intermission",                    "level is an intermission level"
   },
+  {
+    ED_CHECKBUTTON_ID_BD_PAL_TIMING,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(2),
+    GADGET_ID_BD_PAL_TIMING,           GADGET_ID_NONE,
+    &level.bd_pal_timing,
+    NULL, NULL,
+    "PAL timing",                      "use slower timer (like PAL C64)"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_LINE_SHIFTING_BORDERS,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(6),
+    GADGET_ID_BD_LINE_SHIFTING_BORDERS,        GADGET_ID_NONE,
+    &level.bd_line_shifting_borders,
+    "Compatibility settings:", NULL,
+    "line-shifting borders",           "use line-shifting wrap-around"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_SCAN_FIRST_AND_LAST_ROW,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(7),
+    GADGET_ID_BD_SCAN_FIRST_AND_LAST_ROW, GADGET_ID_NONE,
+    &level.bd_scan_first_and_last_row,
+    NULL, NULL,
+    "scan first and last row",         "also process top/bottom border rows"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_SHORT_EXPLOSIONS,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(8),
+    GADGET_ID_BD_SHORT_EXPLOSIONS,     GADGET_ID_NONE,
+    &level.bd_short_explosions,
+    NULL, NULL,
+    "short explosions",                        "use four game cycles for explosions"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_GRAVITY_AFFECTS_ALL,
+    ED_LEVEL_SETTINGS_XPOS(0),         ED_LEVEL_SETTINGS_YPOS(9),
+    GADGET_ID_BD_GRAVITY_AFFECTS_ALL,  GADGET_ID_NONE,
+    &level.bd_gravity_affects_all,
+    NULL, NULL,
+    "gravity change affects everything", "gravity affects all falling objects"
+  },
 
   // ---------- element settings: configure (various elements) ----------------
 
@@ -3513,6 +3694,62 @@ static struct
     NULL, NULL,
     "can move diagonally",             "player can move diagonally"
   },
+  {
+    ED_CHECKBUTTON_ID_BD_TOPMOST_PLAYER_ACTIVE,
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(1),
+    GADGET_ID_BD_TOPMOST_PLAYER_ACTIVE,        GADGET_ID_NONE,
+    &level.bd_topmost_player_active,
+    NULL, NULL,
+    "topmost player is active",                "use first player found on playfield"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET,
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(4),
+    GADGET_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET, GADGET_ID_NONE,
+    &level.bd_push_mega_rock_with_sweet,
+    NULL, NULL,
+    "mega rocks pushable with sweet",  "push mega rocks after eating sweet"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_MAGIC_WALL_WAIT_HATCHING,
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(1),
+    GADGET_ID_BD_MAGIC_WALL_WAIT_HATCHING, GADGET_ID_NONE,
+    &level.bd_magic_wall_wait_hatching,
+    NULL, NULL,
+    "wait for player's birth",         "timer start waits for player's birth"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_MAGIC_WALL_STOPS_AMOEBA,
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(2),
+    GADGET_ID_BD_MAGIC_WALL_STOPS_AMOEBA, GADGET_ID_NONE,
+    &level.bd_magic_wall_stops_amoeba,
+    NULL, NULL,
+    "turn amoeba to diamonds",         "activation changes amoeba to diamonds"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING,
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(1),
+    GADGET_ID_BD_AMOEBA_WAIT_FOR_HATCHING, GADGET_ID_NONE,
+    &level.bd_amoeba_wait_for_hatching,
+    NULL, NULL,
+    "wait for player's birth",         "timer start waits for player's birth"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_AMOEBA_START_IMMEDIATELY,
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(2),
+    GADGET_ID_BD_AMOEBA_START_IMMEDIATELY, GADGET_ID_NONE,
+    &level.bd_amoeba_start_immediately,
+    NULL, NULL,
+    "start growing immediately",       "start slow growth time immediately"
+  },
+  {
+    ED_CHECKBUTTON_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA,
+    ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(9),
+    GADGET_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA, GADGET_ID_NONE,
+    &level.bd_amoeba_2_explode_by_amoeba,
+    NULL, NULL,
+    "explodes if touched by amoeba",   "amoeba 2 explodes if touched by amoeba"
+  },
   {
     ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP,
     ED_ELEMENT_SETTINGS_XPOS(0),       ED_ELEMENT_SETTINGS_YPOS(1),
@@ -3984,6 +4221,60 @@ static struct
     "content:", NULL, NULL, NULL,      "amoeba content"
   },
 
+  // ---------- BD amoeba content ------------------------------------------------
+
+  {
+    ED_DRAWING_ID_BD_AMOEBA_CONTENT_TOO_BIG,
+    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(7),
+    ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
+    GADGET_ID_BD_AMOEBA_CONTENT_TOO_BIG, GADGET_ID_NONE,
+    &level.bd_amoeba_content_too_big,  1, 1,
+    "if too big, changes to:", NULL, NULL, NULL,       "BD amoeba content if too big"
+  },
+  {
+    ED_DRAWING_ID_BD_AMOEBA_CONTENT_ENCLOSED,
+    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(8),
+    ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
+    GADGET_ID_BD_AMOEBA_CONTENT_ENCLOSED, GADGET_ID_NONE,
+    &level.bd_amoeba_content_enclosed, 1, 1,
+    "if enclosed, changes to:", NULL, NULL, NULL,      "BD amoeba content if enclosed"
+  },
+
+  // ---------- BD amoeba 2 content ------------------------------------------------
+
+  {
+    ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_TOO_BIG,
+    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(7),
+    ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
+    GADGET_ID_BD_AMOEBA_2_CONTENT_TOO_BIG, GADGET_ID_NONE,
+    &level.bd_amoeba_2_content_too_big,        1, 1,
+    "if too big, changes to:", NULL, NULL, NULL,       "BD amoeba 2 content if too big"
+  },
+  {
+    ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_ENCLOSED,
+    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(8),
+    ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
+    GADGET_ID_BD_AMOEBA_2_CONTENT_ENCLOSED, GADGET_ID_NONE,
+    &level.bd_amoeba_2_content_enclosed,       1, 1,
+    "if enclosed, changes to:", NULL, NULL, NULL,      "BD amoeba 2 content if enclosed"
+  },
+  {
+    ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_EXPLODING,
+    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(10),
+    ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
+    GADGET_ID_BD_AMOEBA_2_CONTENT_EXPLODING, GADGET_ID_NONE,
+    &level.bd_amoeba_2_content_exploding,      1, 1,
+    "if exploding, changes to:", NULL, NULL, NULL,     "BD amoeba 2 content if exploding"
+  },
+  {
+    ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE,
+    ED_AREA_1X1_SETTINGS_XPOS(0),      ED_AREA_1X1_SETTINGS_YPOS(11),
+    ED_AREA_1X1_SETTINGS_XOFF,         ED_AREA_1X1_SETTINGS_YOFF,
+    GADGET_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE,  GADGET_ID_NONE,
+    &level.bd_amoeba_2_content_looks_like,     1, 1,
+    "use graphic of element:", NULL, NULL, NULL,       "BD amoeba 2 looks like this element"
+  },
+
   // ---------- level start element -------------------------------------------
 
   {
@@ -4328,7 +4619,7 @@ static int editor_el_boulderdash_native[] =
   EL_BD_AMOEBA,
   EL_BD_BUTTERFLY_UP,
   EL_BD_FIREFLY_UP,
-  EL_EXIT_CLOSED,
+  EL_BD_EXIT_CLOSED,
 
   EL_BD_BUTTERFLY_LEFT,
   EL_BD_FIREFLY_LEFT,
@@ -4338,7 +4629,7 @@ static int editor_el_boulderdash_native[] =
   EL_BD_INBOX,
   EL_BD_BUTTERFLY_DOWN,
   EL_BD_FIREFLY_DOWN,
-  EL_EXIT_OPEN,
+  EL_BD_EXIT_OPEN,
 
   EL_BD_AMOEBA_2,
   EL_BD_BUTTERFLY_2_UP,
@@ -7958,17 +8249,10 @@ static void MapCounterButtons(int id)
 
   ModifyEditorCounterValue(id, *counterbutton_info[id].value);
 
-  // set position for "value[1,2,3,4]" counter gadgets (score in most cases)
-  if (id >= ED_COUNTER_ID_ELEMENT_VALUE1 &&
-      id <= ED_COUNTER_ID_ELEMENT_VALUE4)
-  {
-    ModifyGadget(gi_down, GDI_Y,
-                SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END);
-    ModifyGadget(gi_text, GDI_Y,
-                SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END);
-    ModifyGadget(gi_up,   GDI_Y,
-                SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END);
-  }
+  // set position for counter gadgets with dynamically determined position
+  ModifyGadget(gi_down, GDI_Y, SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END);
+  ModifyGadget(gi_text, GDI_Y, SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END);
+  ModifyGadget(gi_up,   GDI_Y, SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END);
 
   // vertical position might have changed after setting position above
   y = gi_up->y + yoffset;
@@ -10007,9 +10291,25 @@ static void DrawLevelConfigEngine(void)
 {
   int i;
 
+  // draw counter gadgets
+  if (level.bd_scheduling_type == GD_SCHEDULING_MILLISECONDS)
+  {
+    MapCounterButtons(ED_COUNTER_ID_BD_CYCLE_DELAY_MS);
+    MapCounterButtons(ED_COUNTER_ID_BD_HATCHING_DELAY_CYCLES);
+  }
+  else
+  {
+    MapCounterButtons(ED_COUNTER_ID_BD_CYCLE_DELAY_C64);
+    MapCounterButtons(ED_COUNTER_ID_BD_HATCHING_DELAY_SECONDS);
+  }
+
   // draw checkbutton gadgets
   for (i = ED_CHECKBUTTON_ID_ENGINE_FIRST; i <= ED_CHECKBUTTON_ID_ENGINE_LAST; i++)
     MapCheckbuttonGadget(i);
+
+  // draw selectbox gadgets
+  for (i = ED_SELECTBOX_ID_ENGINE_FIRST; i <= ED_SELECTBOX_ID_ENGINE_LAST; i++)
+    MapSelectboxGadget(i);
 }
 
 static void DrawLevelConfigWindow(void)
@@ -10486,11 +10786,15 @@ static void DrawPropertiesInfo(void)
 }
 
 #define TEXT_COLLECTING                "Score for collecting"
-#define TEXT_COLLECTING_EXTRA  "Extra score for collecting"
+#define TEXT_COLLECTING_EXTRA  "Score for extra diamonds"
 #define TEXT_SMASHING          "Score for smashing"
 #define TEXT_SLURPING          "Score for slurping robot"
 #define TEXT_CRACKING          "Score for cracking"
 #define TEXT_AMOEBA_SPEED      "Speed of amoeba growth"
+#define TEXT_AMOEBA_THRESHOED  "Size for turning to rocks"
+#define TEXT_AMOEBA_SLOW_TIME  "Slow growth time (seconds)"
+#define TEXT_AMOEBA_SLOW_RATE  "Slow growth rate (percent)"
+#define TEXT_AMOEBA_FAST_RATE  "Fast growth rate (percent)"
 #define TEXT_DURATION          "Duration when activated"
 #define TEXT_DELAY_ON          "Delay before activating"
 #define TEXT_DELAY_OFF         "Delay before deactivating"
@@ -10593,6 +10897,14 @@ static struct
   { EL_AMOEBA_FULL,            &level.amoeba_speed,            TEXT_AMOEBA_SPEED       },
   { EL_BD_AMOEBA,              &level.amoeba_speed,            TEXT_AMOEBA_SPEED       },
   { EL_EMC_DRIPPER,            &level.amoeba_speed,            TEXT_AMOEBA_SPEED       },
+  { EL_BD_AMOEBA,              &level.bd_amoeba_threshold_too_big,     TEXT_AMOEBA_THRESHOED   },
+  { EL_BD_AMOEBA,              &level.bd_amoeba_slow_growth_time,      TEXT_AMOEBA_SLOW_TIME   },
+  { EL_BD_AMOEBA,              &level.bd_amoeba_slow_growth_rate,      TEXT_AMOEBA_SLOW_RATE   },
+  { EL_BD_AMOEBA,              &level.bd_amoeba_fast_growth_rate,      TEXT_AMOEBA_FAST_RATE   },
+  { EL_BD_AMOEBA_2,            &level.bd_amoeba_2_threshold_too_big,   TEXT_AMOEBA_THRESHOED   },
+  { EL_BD_AMOEBA_2,            &level.bd_amoeba_2_slow_growth_time,    TEXT_AMOEBA_SLOW_TIME   },
+  { EL_BD_AMOEBA_2,            &level.bd_amoeba_2_slow_growth_rate,    TEXT_AMOEBA_SLOW_RATE   },
+  { EL_BD_AMOEBA_2,            &level.bd_amoeba_2_fast_growth_rate,    TEXT_AMOEBA_FAST_RATE   },
   { EL_MAGIC_WALL,             &level.time_magic_wall,         TEXT_DURATION           },
   { EL_BD_MAGIC_WALL,          &level.time_magic_wall,         TEXT_DURATION           },
   { EL_DC_MAGIC_WALL,          &level.time_magic_wall,         TEXT_DURATION           },
@@ -10640,6 +10952,10 @@ static boolean checkPropertiesConfig(int element)
   if (element == EL_EMPTY_SPACE && level.game_engine_type != GAME_ENGINE_TYPE_RND)
     return FALSE;
 
+  // special case: BD style rock customization only available in BD game engine
+  if (element == EL_BD_ROCK && level.game_engine_type != GAME_ENGINE_TYPE_BD)
+    return FALSE;
+
   if (IS_GEM(element) ||
       IS_CUSTOM_ELEMENT(element) ||
       IS_GROUP_ELEMENT(element) ||
@@ -10655,12 +10971,19 @@ static boolean checkPropertiesConfig(int element)
       HAS_EDITOR_CONTENT(element) ||
       CAN_GROW(element) ||
       COULD_MOVE_INTO_ACID(element) ||
-      MAYBE_DONT_COLLIDE_WITH(element))
+      MAYBE_DONT_COLLIDE_WITH(element) ||
+      element == EL_BD_ROCK ||
+      element == EL_BD_MEGA_ROCK ||
+      element == EL_BD_SWEET)
+  {
     return TRUE;
+  }
   else
+  {
     for (i = 0; elements_with_counter[i].element != -1; i++)
       if (elements_with_counter[i].element == element)
        return TRUE;
+  }
 
   return FALSE;
 }
@@ -10746,6 +11069,24 @@ static void DrawPropertiesConfig(void)
   {
     if (elements_with_counter[i].element == properties_element)
     {
+      // special case: score for extra diamonds only available in BD game engine
+      if (elements_with_counter[i].element == EL_BD_DIAMOND &&
+         elements_with_counter[i].value == &level.score[SC_DIAMOND_EXTRA] &&
+         level.game_engine_type != GAME_ENGINE_TYPE_BD)
+       continue;
+
+      // special case: some amoeba counters only available in BD game engine
+      if (elements_with_counter[i].element == EL_BD_AMOEBA &&
+         elements_with_counter[i].value != &level.amoeba_speed &&
+         level.game_engine_type != GAME_ENGINE_TYPE_BD)
+       continue;
+
+      // special case: some amoeba counters only available in R'n'D game engine
+      if (elements_with_counter[i].element == EL_BD_AMOEBA &&
+         elements_with_counter[i].value == &level.amoeba_speed &&
+         level.game_engine_type == GAME_ENGINE_TYPE_BD)
+       continue;
+
       int counter_id = ED_COUNTER_ID_ELEMENT_VALUE1 + num_element_counters;
 
       counterbutton_info[counter_id].y =
@@ -10757,6 +11098,12 @@ static void DrawPropertiesConfig(void)
                (properties_element == EL_EMC_MAGIC_BALL     ? 2 : 0) +
                num_element_counters);
 
+      // special case: set amoeba counters for BD game engine separately
+      if ((properties_element == EL_BD_AMOEBA && level.game_engine_type == GAME_ENGINE_TYPE_BD) ||
+         (properties_element == EL_BD_AMOEBA_2))
+       counterbutton_info[counter_id].y =
+         ED_ELEMENT_SETTINGS_YPOS(3 + num_element_counters);
+
       counterbutton_info[counter_id].value = elements_with_counter[i].value;
       counterbutton_info[counter_id].text_right = elements_with_counter[i].text;
 
@@ -10766,6 +11113,12 @@ static void DrawPropertiesConfig(void)
        counterbutton_info[counter_id].min_value = 0;   // min neighbours
        counterbutton_info[counter_id].max_value = 8;   // max neighbours
       }
+      else if (strEqual(elements_with_counter[i].text, TEXT_AMOEBA_SLOW_RATE) ||
+              strEqual(elements_with_counter[i].text, TEXT_AMOEBA_FAST_RATE))
+      {
+       counterbutton_info[counter_id].min_value = 0;   // min percent
+       counterbutton_info[counter_id].max_value = 100; // max percent
+      }
       else
       {
        // !!! CHANGE THIS FOR CERTAIN ELEMENTS !!!
@@ -10786,7 +11139,26 @@ static void DrawPropertiesConfig(void)
     // draw stickybutton gadget
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT);
 
-    if (IS_AMOEBOID(properties_element))
+    if (properties_element == EL_BD_AMOEBA && level.game_engine_type == GAME_ENGINE_TYPE_BD)
+    {
+      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING);
+      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_START_IMMEDIATELY);
+
+      MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_CONTENT_TOO_BIG);
+      MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_CONTENT_ENCLOSED);
+    }
+    else if (properties_element == EL_BD_AMOEBA_2)
+    {
+      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING);
+      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_START_IMMEDIATELY);
+      MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA);
+
+      MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_TOO_BIG);
+      MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_ENCLOSED);
+      MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_EXPLODING);
+      MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE);
+    }
+    else if (IS_AMOEBOID(properties_element))
       MapDrawingArea(ED_DRAWING_ID_AMOEBA_CONTENT);
     else if (properties_element == EL_YAMYAM ||
             properties_element == EL_YAMYAM_LEFT ||
@@ -10888,16 +11260,57 @@ static void DrawPropertiesConfig(void)
   }
 
   if (IS_BD_PLAYER_ELEMENT(properties_element))
+  {
+    counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB].y =
+      ED_ELEMENT_SETTINGS_YPOS(2);
+    counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET].y =
+      ED_ELEMENT_SETTINGS_YPOS(3);
+    checkbutton_info[ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET].y =
+      ED_ELEMENT_SETTINGS_YPOS(4);
+
+    // draw checkbutton gadgets
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_DIAGONAL_MOVEMENTS);
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_TOPMOST_PLAYER_ACTIVE);
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET);
+
+    // draw counter gadgets
+    MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB);
+    MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET);
+  }
 
-  if (IS_GEM(properties_element))
+  if (properties_element == EL_BD_ROCK && level.game_engine_type == GAME_ENGINE_TYPE_BD)
   {
-    checkbutton_info[ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS].y =
-      ED_ELEMENT_SETTINGS_XPOS(properties_element == EL_BD_DIAMOND ? 2 : 1);
+    counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB].y =
+      ED_ELEMENT_SETTINGS_YPOS(0);
+    counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET].y =
+      ED_ELEMENT_SETTINGS_YPOS(1);
 
-    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS);
+    MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB);
+    MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET);
+  }
+
+  if (properties_element == EL_BD_MEGA_ROCK ||
+      properties_element == EL_BD_SWEET)
+  {
+    counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET].y =
+      ED_ELEMENT_SETTINGS_YPOS(0);
+    checkbutton_info[ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET].y =
+      ED_ELEMENT_SETTINGS_YPOS(1);
+
+    MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET);
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET);
   }
 
+  if (properties_element == EL_BD_MAGIC_WALL)
+  {
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_WAIT_HATCHING);
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_STOPS_AMOEBA);
+  }
+
+  // special case: slippery walls option for gems only available in R'n'D game engine
+  if (IS_GEM(properties_element) && level.game_engine_type == GAME_ENGINE_TYPE_RND)
+    MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS);
+
   if (properties_element == EL_EM_DYNAMITE)
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE);
 
@@ -10932,7 +11345,7 @@ static void DrawPropertiesConfig(void)
       properties_element == EL_BIOMAZE)
     MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_LIFE_BUGS);
 
-  if (CAN_GROW(properties_element))
+  if (CAN_GROW(properties_element) && level.game_engine_type != GAME_ENGINE_TYPE_BD)
   {
     checkbutton_info[ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE].y =
       ED_ELEMENT_SETTINGS_YPOS(HAS_EDITOR_CONTENT(properties_element) ? 1 : 0);
@@ -14519,6 +14932,11 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi)
     ReinitializeElementList();
     ModifyEditorElementList();
   }
+  else if (type_id == ED_SELECTBOX_ID_BD_SCHEDULING_TYPE)
+  {
+    // update BD cycle delay counter gadgets depending on BD scheduling type
+    DrawLevelConfigWindow();
+  }
 
   // do not mark level as modified for certain non-level-changing gadgets
   if (type_id == ED_SELECTBOX_ID_LEVELSET_SAVE_MODE ||