added support for gravity settings in BD engine to level editor
[rocksndiamonds.git] / src / files.c
index e6e2281694d66a945891aa0c3abcb3a55d2cf850..b405986f92cbb27ad077924c8d6d57b38aed4028 100644 (file)
@@ -165,7 +165,6 @@ static struct LevelFileConfigInfo chunk_config_INFO[] =
     TYPE_INTEGER,                      CONF_VALUE_8_BIT(1),
     &li.game_engine_type,              GAME_ENGINE_TYPE_RND
   },
-
   {
     -1,                                        SAVE_CONF_ALWAYS,
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
@@ -176,150 +175,146 @@ static struct LevelFileConfigInfo chunk_config_INFO[] =
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(2),
     &li.fieldy,                                STD_LEV_FIELDY
   },
-
   {
     -1,                                        SAVE_CONF_ALWAYS,
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(3),
     &li.time,                          100
   },
-
   {
     -1,                                        SAVE_CONF_ALWAYS,
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(4),
     &li.gems_needed,                   0
   },
-
   {
     -1,                                        -1,
     TYPE_INTEGER,                      CONF_VALUE_32_BIT(2),
     &li.random_seed,                   0
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
     &li.use_step_counter,              FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_BITFIELD,                     CONF_VALUE_8_BIT(4),
     &li.wind_direction_initial,                MV_NONE
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(5),
     &li.em_slippery_gems,              FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(6),
     &li.use_custom_template,           FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_BITFIELD,                     CONF_VALUE_32_BIT(1),
     &li.can_move_into_acid_bits,       ~0      // default: everything can
   },
-
   {
     -1,                                        -1,
     TYPE_BITFIELD,                     CONF_VALUE_8_BIT(7),
     &li.dont_collide_with_bits,                ~0      // default: always deadly
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(8),
     &li.em_explodes_by_fire,           FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(5),
     &li.score[SC_TIME_BONUS],          1
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(9),
     &li.auto_exit_sokoban,             FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(10),
     &li.auto_count_gems,               FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(11),
     &li.solved_by_one_player,          FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_INTEGER,                      CONF_VALUE_8_BIT(12),
     &li.time_score_base,               1
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(13),
     &li.rate_time_over_score,          FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(14),
     &li.bd_intermission,               FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_INTEGER,                      CONF_VALUE_8_BIT(15),
     &li.bd_scheduling_type,            GD_SCHEDULING_MILLISECONDS
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(16),
     &li.bd_pal_timing,                 FALSE
   },
-
   {
     -1,                                        -1,
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(6),
     &li.bd_cycle_delay_ms,             200
   },
-
   {
     -1,                                        -1,
     TYPE_INTEGER,                      CONF_VALUE_8_BIT(17),
     &li.bd_cycle_delay_c64,            0
   },
-
   {
     -1,                                        -1,
     TYPE_INTEGER,                      CONF_VALUE_8_BIT(18),
     &li.bd_hatching_delay_cycles,      21
   },
-
   {
     -1,                                        -1,
     TYPE_INTEGER,                      CONF_VALUE_8_BIT(19),
     &li.bd_hatching_delay_seconds,     2
   },
-
   {
     -1,                                        -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(20),
     &li.bd_line_shifting_borders,      FALSE
   },
+  {
+    -1,                                        -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(21),
+    &li.bd_scan_first_and_last_row,    TRUE
+  },
+  {
+    -1,                                        -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(22),
+    &li.bd_short_explosions,           TRUE
+  },
+  {
+    -1,                                        -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(23),
+    &li.bd_gravity_affects_all,                TRUE
+  },
+  {
+    -1,                                        -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(24),
+    &li.bd_cave_random_seed_c64,       0
+  },
 
   {
     -1,                                        -1,
@@ -612,11 +607,37 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
   },
 
   // (these values are only valid for BD style levels)
+  // (some values for BD style amoeba following below)
   {
     EL_BD_PLAYER,                      -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
     &li.bd_diagonal_movements,         FALSE
   },
+  {
+    EL_BD_PLAYER,                      -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.bd_topmost_player_active,      TRUE
+  },
+  {
+    EL_BD_PLAYER,                      -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(3),
+    &li.bd_pushing_prob,               25
+  },
+  {
+    EL_BD_PLAYER,                      -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(4),
+    &li.bd_pushing_prob_with_sweet,    100
+  },
+  {
+    EL_BD_PLAYER,                      -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(5),
+    &li.bd_push_mega_rock_with_sweet,  FALSE
+  },
+  {
+    EL_BD_PLAYER,                      -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(6),
+    &li.bd_snap_element,               EL_EMPTY
+  },
 
   {
     EL_BD_DIAMOND,                     -1,
@@ -624,6 +645,278 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
     &li.score[SC_DIAMOND_EXTRA],       20
   },
 
+  {
+    EL_BD_MAGIC_WALL,                  -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.bd_magic_wall_wait_hatching,   FALSE
+  },
+  {
+    EL_BD_MAGIC_WALL,                  -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.bd_magic_wall_stops_amoeba,    TRUE
+  },
+  {
+    EL_BD_MAGIC_WALL,                  -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
+    &li.bd_magic_wall_diamond_to,      EL_BD_ROCK_FALLING
+  },
+  {
+    EL_BD_MAGIC_WALL,                  -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(2),
+    &li.bd_magic_wall_rock_to,         EL_BD_DIAMOND_FALLING
+  },
+  {
+    EL_BD_MAGIC_WALL,                  -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(3),
+    &li.bd_magic_wall_mega_rock_to,    EL_BD_NITRO_PACK_FALLING
+  },
+  {
+    EL_BD_MAGIC_WALL,                  -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(4),
+    &li.bd_magic_wall_nut_to,          EL_BD_NUT_FALLING
+  },
+  {
+    EL_BD_MAGIC_WALL,                  -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(5),
+    &li.bd_magic_wall_nitro_pack_to,   EL_BD_MEGA_ROCK_FALLING
+  },
+  {
+    EL_BD_MAGIC_WALL,                  -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(6),
+    &li.bd_magic_wall_flying_diamond_to, EL_BD_FLYING_ROCK_FLYING
+  },
+  {
+    EL_BD_MAGIC_WALL,                  -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(7),
+    &li.bd_magic_wall_flying_rock_to,  EL_BD_FLYING_DIAMOND_FLYING
+  },
+
+  {
+    EL_BD_CLOCK,                       -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(1),
+    &li.bd_clock_extra_time,           30
+  },
+
+  {
+    EL_BD_VOODOO_DOLL,                 -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.bd_voodoo_collects_diamonds,   FALSE
+  },
+  {
+    EL_BD_VOODOO_DOLL,                 -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.bd_voodoo_hurt_kills_player,   FALSE
+  },
+  {
+    EL_BD_VOODOO_DOLL,                 -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(3),
+    &li.bd_voodoo_dies_by_rock,                FALSE
+  },
+  {
+    EL_BD_VOODOO_DOLL,                 -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(4),
+    &li.bd_voodoo_vanish_by_explosion, TRUE
+  },
+  {
+    EL_BD_VOODOO_DOLL,                 -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(5),
+    &li.bd_voodoo_penalty_time,                30
+  },
+
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.bd_slime_is_predictable,       TRUE
+  },
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(2),
+    &li.bd_slime_permeability_rate,    100
+  },
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(3),
+    &li.bd_slime_permeability_bits_c64,        0
+  },
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_INTEGER,                      CONF_VALUE_32_BIT(1),
+    &li.bd_slime_random_seed_c64,      -1
+  },
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
+    &li.bd_slime_eats_element_1,       EL_BD_DIAMOND
+  },
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(2),
+    &li.bd_slime_converts_to_element_1,        EL_BD_DIAMOND_FALLING
+  },
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(3),
+    &li.bd_slime_eats_element_2,       EL_BD_ROCK
+  },
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(4),
+    &li.bd_slime_converts_to_element_2,        EL_BD_ROCK_FALLING
+  },
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(5),
+    &li.bd_slime_eats_element_3,       EL_BD_NUT
+  },
+  {
+    EL_BD_SLIME,                       -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(6),
+    &li.bd_slime_converts_to_element_3,        EL_BD_NUT_FALLING
+  },
+
+  {
+    EL_BD_ACID,                                -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
+    &li.bd_acid_eats_element,          EL_BD_SAND
+  },
+  {
+    EL_BD_ACID,                                -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(1),
+    &li.bd_acid_spread_rate,           3
+  },
+  {
+    EL_BD_ACID,                                -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(2),
+    &li.bd_acid_turns_to_element,      EL_BD_EXPLODING_3
+  },
+
+  {
+    EL_BD_BITER,                       -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(1),
+    &li.bd_biter_move_delay,           0
+  },
+  {
+    EL_BD_BITER,                       -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
+    &li.bd_biter_eats_element,         EL_BD_DIAMOND
+  },
+
+  {
+    EL_BD_BLADDER,                     -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
+    &li.bd_bladder_converts_by_element,        EL_BD_VOODOO_DOLL
+  },
+
+  {
+    EL_BD_EXPANDABLE_WALL_ANY,         -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.bd_change_expanding_wall,      FALSE
+  },
+  {
+    EL_BD_EXPANDABLE_WALL_ANY,         -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
+    &li.bd_expanding_wall_looks_like,  EL_BD_WALL
+  },
+
+  {
+    EL_BD_REPLICATOR,                  -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.bd_replicators_active,         TRUE
+  },
+  {
+    EL_BD_REPLICATOR,                  -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(2),
+    &li.bd_replicator_create_delay,    4
+  },
+
+  {
+    EL_BD_CONVEYOR_LEFT,               -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.bd_conveyor_belts_active,      TRUE
+  },
+  {
+    EL_BD_CONVEYOR_LEFT,               -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.bd_conveyor_belts_changed,     FALSE
+  },
+
+  {
+    EL_BD_WATER,                       -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.bd_water_cannot_flow_down,     FALSE
+  },
+
+  {
+    EL_BD_NUT,                         -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
+    &li.bd_nut_content,                        EL_BD_NUT_BREAKING_1
+  },
+
+  {
+    EL_BD_PNEUMATIC_HAMMER,            -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(1),
+    &li.bd_hammer_walls_break_delay,   5
+  },
+  {
+    EL_BD_PNEUMATIC_HAMMER,            -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.bd_hammer_walls_reappear,      FALSE
+  },
+  {
+    EL_BD_PNEUMATIC_HAMMER,            -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(3),
+    &li.bd_hammer_walls_reappear_delay,        100
+  },
+
+  {
+    EL_BD_SKELETON,                    -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(1),
+    &li.bd_num_skeletons_needed_for_pot, 5
+  },
+  {
+    EL_BD_SKELETON,                    -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(2),
+    &li.bd_skeleton_worth_num_diamonds,        0
+  },
+
+  {
+    EL_BD_CREATURE_SWITCH,             -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.bd_creatures_start_backwards,  FALSE
+  },
+  {
+    EL_BD_CREATURE_SWITCH,             -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.bd_creatures_turn_on_hatching, FALSE
+  },
+  {
+    EL_BD_CREATURE_SWITCH,             -1,
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
+    &li.bd_creatures_auto_turn_delay,  0
+  },
+
+  {
+    EL_BD_GRAVITY_SWITCH,              -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(1),
+    &li.bd_gravity_direction,          GD_MV_DOWN
+  },
+  {
+    EL_BD_GRAVITY_SWITCH,              -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.bd_gravity_switch_active,      FALSE
+  },
+  {
+    EL_BD_GRAVITY_SWITCH,              -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(3),
+    &li.bd_gravity_switch_delay,       10
+  },
+
+  {
+    EL_BD_SAND,                                -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
+    &li.bd_sand_looks_like,            EL_BD_SAND
+  },
+
   // (the following values are related to various game elements)
 
   {
@@ -686,6 +979,7 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
     &li.score[SC_CRYSTAL],             10
   },
 
+  // (amoeba values used by R'n'D game engine only)
   {
     EL_BD_AMOEBA,                      -1,
     TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
@@ -701,6 +995,93 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
     &li.grow_into_diggable,            TRUE
   },
+  // (amoeba values used by BD game engine only)
+  {
+    EL_BD_AMOEBA,                      -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.bd_amoeba_wait_for_hatching,   FALSE
+  },
+  {
+    EL_BD_AMOEBA,                      -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(3),
+    &li.bd_amoeba_start_immediately,   TRUE
+  },
+  {
+    EL_BD_AMOEBA,                      -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(4),
+    &li.bd_amoeba_2_explode_by_amoeba, TRUE
+  },
+  {
+    EL_BD_AMOEBA,                      -1,
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(3),
+    &li.bd_amoeba_threshold_too_big,   200
+  },
+  {
+    EL_BD_AMOEBA,                      -1,
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(4),
+    &li.bd_amoeba_slow_growth_time,    200
+  },
+  {
+    EL_BD_AMOEBA,                      -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(5),
+    &li.bd_amoeba_slow_growth_rate,    3
+  },
+  {
+    EL_BD_AMOEBA,                      -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(6),
+    &li.bd_amoeba_fast_growth_rate,    25
+  },
+  {
+    EL_BD_AMOEBA,                      -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(5),
+    &li.bd_amoeba_content_too_big,     EL_BD_ROCK
+  },
+  {
+    EL_BD_AMOEBA,                      -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(6),
+    &li.bd_amoeba_content_enclosed,    EL_BD_DIAMOND
+  },
+
+  {
+    EL_BD_AMOEBA_2,                    -1,
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(3),
+    &li.bd_amoeba_2_threshold_too_big, 200
+  },
+  {
+    EL_BD_AMOEBA_2,                    -1,
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(4),
+    &li.bd_amoeba_2_slow_growth_time,  200
+  },
+  {
+    EL_BD_AMOEBA_2,                    -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(5),
+    &li.bd_amoeba_2_slow_growth_rate,  3
+  },
+  {
+    EL_BD_AMOEBA_2,                    -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(6),
+    &li.bd_amoeba_2_fast_growth_rate,  25
+  },
+  {
+    EL_BD_AMOEBA_2,                    -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(5),
+    &li.bd_amoeba_2_content_too_big,   EL_BD_ROCK
+  },
+  {
+    EL_BD_AMOEBA_2,                    -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(6),
+    &li.bd_amoeba_2_content_enclosed,  EL_BD_DIAMOND
+  },
+  {
+    EL_BD_AMOEBA_2,                    -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(7),
+    &li.bd_amoeba_2_content_exploding, EL_EMPTY
+  },
+  {
+    EL_BD_AMOEBA_2,                    -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(8),
+    &li.bd_amoeba_2_content_looks_like,        EL_BD_AMOEBA_2
+  },
 
   {
     EL_YAMYAM,                         -1,
@@ -3739,49 +4120,154 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
 // functions for loading BD level
 // ----------------------------------------------------------------------------
 
+#define LEVEL_TO_CAVE(e)       (map_element_RND_to_BD_cave(e))
+#define CAVE_TO_LEVEL(e)       (map_element_BD_to_RND_cave(e))
+
 static void CopyNativeLevel_RND_to_BD(struct LevelInfo *level)
 {
   struct LevelInfo_BD *level_bd = level->native_bd_level;
   GdCave *cave = NULL; // will be changed below
   int cave_w = MIN(level->fieldx, MAX_PLAYFIELD_WIDTH);
   int cave_h = MIN(level->fieldy, MAX_PLAYFIELD_HEIGHT);
-  int i, x, y;
+  int x, y;
 
   setLevelInfoToDefaults_BD_Ext(cave_w, cave_h);
 
   // cave and map newly allocated when set to defaults above
   cave = level_bd->cave;
 
-  for (i = 0; i < 5; i++)
-  {
-    cave->level_time[i]                        = level->time;
-    cave->level_diamonds[i]            = level->gems_needed;
-    cave->level_magic_wall_time[i]     = level->time_magic_wall;
+  // level type
+  cave->intermission                   = level->bd_intermission;
 
-    cave->level_speed[i]               = level->bd_cycle_delay_ms;
-    cave->level_ckdelay[i]             = level->bd_cycle_delay_c64;
-    cave->level_hatching_delay_frame[i]        = level->bd_hatching_delay_cycles;
-    cave->level_hatching_delay_time[i] = level->bd_hatching_delay_seconds;
+  // level settings
+  cave->level_time[0]                  = level->time;
+  cave->level_diamonds[0]              = level->gems_needed;
 
-    cave->level_timevalue[i]           = level->score[SC_TIME_BONUS];
-  }
+  // game timing
+  cave->scheduling                     = level->bd_scheduling_type;
+  cave->pal_timing                     = level->bd_pal_timing;
+  cave->level_speed[0]                 = level->bd_cycle_delay_ms;
+  cave->level_ckdelay[0]               = level->bd_cycle_delay_c64;
+  cave->level_hatching_delay_frame[0]  = level->bd_hatching_delay_cycles;
+  cave->level_hatching_delay_time[0]   = level->bd_hatching_delay_seconds;
 
+  // scores
+  cave->level_timevalue[0]             = level->score[SC_TIME_BONUS];
   cave->diamond_value                  = level->score[SC_EMERALD];
   cave->extra_diamond_value            = level->score[SC_DIAMOND_EXTRA];
 
-  cave->scheduling                     = level->bd_scheduling_type;
-  cave->pal_timing                     = level->bd_pal_timing;
-  cave->intermission                   = level->bd_intermission;
-  cave->diagonal_movements             = level->bd_diagonal_movements;
-
+  // compatibility settings
   cave->lineshift                      = level->bd_line_shifting_borders;
+  cave->border_scan_first_and_last     = level->bd_scan_first_and_last_row;
+  cave->short_explosions               = level->bd_short_explosions;
+  cave->gravity_affects_all            = level->bd_gravity_affects_all;
 
+  // player properties
+  cave->diagonal_movements             = level->bd_diagonal_movements;
+  cave->active_is_first_found          = level->bd_topmost_player_active;
+  cave->pushing_stone_prob             = level->bd_pushing_prob            * 10000;
+  cave->pushing_stone_prob_sweet       = level->bd_pushing_prob_with_sweet * 10000;
+  cave->mega_stones_pushable_with_sweet        = level->bd_push_mega_rock_with_sweet;
+  cave->snap_element                   = LEVEL_TO_CAVE(level->bd_snap_element);
+
+  // element properties
+  cave->level_bonus_time[0]            = level->bd_clock_extra_time;
+  cave->voodoo_collects_diamonds       = level->bd_voodoo_collects_diamonds;
+  cave->voodoo_any_hurt_kills_player   = level->bd_voodoo_hurt_kills_player;
+  cave->voodoo_dies_by_stone           = level->bd_voodoo_dies_by_rock;
+  cave->voodoo_disappear_in_explosion  = level->bd_voodoo_vanish_by_explosion;
+  cave->level_penalty_time[0]          = level->bd_voodoo_penalty_time;
+  cave->level_magic_wall_time[0]       = level->time_magic_wall;
+  cave->magic_timer_wait_for_hatching  = level->bd_magic_wall_wait_hatching;
+  cave->magic_wall_stops_amoeba                = level->bd_magic_wall_stops_amoeba;
+
+  cave->magic_diamond_to               = LEVEL_TO_CAVE(level->bd_magic_wall_diamond_to);
+  cave->magic_stone_to                 = LEVEL_TO_CAVE(level->bd_magic_wall_rock_to);
+  cave->magic_mega_stone_to            = LEVEL_TO_CAVE(level->bd_magic_wall_mega_rock_to);
+  cave->magic_nut_to                   = LEVEL_TO_CAVE(level->bd_magic_wall_nut_to);
+  cave->magic_nitro_pack_to            = LEVEL_TO_CAVE(level->bd_magic_wall_nitro_pack_to);
+  cave->magic_flying_diamond_to                = LEVEL_TO_CAVE(level->bd_magic_wall_flying_diamond_to);
+  cave->magic_flying_stone_to          = LEVEL_TO_CAVE(level->bd_magic_wall_flying_rock_to);
+
+  cave->amoeba_timer_wait_for_hatching = level->bd_amoeba_wait_for_hatching;
+  cave->amoeba_timer_started_immediately= level->bd_amoeba_start_immediately;
+  cave->amoeba_2_explodes_by_amoeba    = level->bd_amoeba_2_explode_by_amoeba;
+  cave->level_amoeba_threshold[0]      = level->bd_amoeba_threshold_too_big;
+  cave->level_amoeba_time[0]           = level->bd_amoeba_slow_growth_time;
+  cave->amoeba_growth_prob             = level->bd_amoeba_slow_growth_rate * 10000;
+  cave->amoeba_fast_growth_prob                = level->bd_amoeba_fast_growth_rate * 10000;
+  cave->level_amoeba_2_threshold[0]    = level->bd_amoeba_2_threshold_too_big;
+  cave->level_amoeba_2_time[0]         = level->bd_amoeba_2_slow_growth_time;
+  cave->amoeba_2_growth_prob           = level->bd_amoeba_2_slow_growth_rate * 10000;
+  cave->amoeba_2_fast_growth_prob      = level->bd_amoeba_2_fast_growth_rate * 10000;
+
+  cave->amoeba_too_big_effect          = LEVEL_TO_CAVE(level->bd_amoeba_content_too_big);
+  cave->amoeba_enclosed_effect         = LEVEL_TO_CAVE(level->bd_amoeba_content_enclosed);
+  cave->amoeba_2_too_big_effect                = LEVEL_TO_CAVE(level->bd_amoeba_2_content_too_big);
+  cave->amoeba_2_enclosed_effect       = LEVEL_TO_CAVE(level->bd_amoeba_2_content_enclosed);
+  cave->amoeba_2_explosion_effect      = LEVEL_TO_CAVE(level->bd_amoeba_2_content_exploding);
+  cave->amoeba_2_looks_like            = LEVEL_TO_CAVE(level->bd_amoeba_2_content_looks_like);
+
+  cave->slime_predictable              = level->bd_slime_is_predictable;
+  cave->slime_correct_random           = level->bd_slime_correct_random;
+  cave->level_slime_permeability[0]    = level->bd_slime_permeability_rate * 10000;
+  cave->level_slime_permeability_c64[0]        = level->bd_slime_permeability_bits_c64;
+  cave->level_slime_seed_c64[0]                = level->bd_slime_random_seed_c64;
+  cave->level_rand[0]                  = level->bd_cave_random_seed_c64;
+  cave->slime_eats_1                   = LEVEL_TO_CAVE(level->bd_slime_eats_element_1);
+  cave->slime_converts_1               = LEVEL_TO_CAVE(level->bd_slime_converts_to_element_1);
+  cave->slime_eats_2                   = LEVEL_TO_CAVE(level->bd_slime_eats_element_2);
+  cave->slime_converts_2               = LEVEL_TO_CAVE(level->bd_slime_converts_to_element_2);
+  cave->slime_eats_3                   = LEVEL_TO_CAVE(level->bd_slime_eats_element_3);
+  cave->slime_converts_3               = LEVEL_TO_CAVE(level->bd_slime_converts_to_element_3);
+
+  cave->acid_eats_this                 = LEVEL_TO_CAVE(level->bd_acid_eats_element);
+  cave->acid_spread_ratio              = level->bd_acid_spread_rate * 10000;
+  cave->acid_turns_to                  = LEVEL_TO_CAVE(level->bd_acid_turns_to_element);
+
+  cave->biter_delay_frame              = level->bd_biter_move_delay;
+  cave->biter_eat                      = LEVEL_TO_CAVE(level->bd_biter_eats_element);
+
+  cave->bladder_converts_by            = LEVEL_TO_CAVE(level->bd_bladder_converts_by_element);
+
+  cave->expanding_wall_changed         = level->bd_change_expanding_wall;
+
+  cave->replicators_active             = level->bd_replicators_active;
+  cave->replicator_delay_frame         = level->bd_replicator_create_delay;
+
+  cave->conveyor_belts_active          = level->bd_conveyor_belts_active;
+  cave->conveyor_belts_direction_changed= level->bd_conveyor_belts_changed;
+
+  cave->water_does_not_flow_down       = level->bd_water_cannot_flow_down;
+
+  cave->nut_turns_to_when_crushed      = LEVEL_TO_CAVE(level->bd_nut_content);
+
+  cave->pneumatic_hammer_frame         = level->bd_hammer_walls_break_delay;
+  cave->hammered_walls_reappear                = level->bd_hammer_walls_reappear;
+  cave->hammered_wall_reappear_frame   = level->bd_hammer_walls_reappear_delay;
+
+  cave->skeletons_needed_for_pot       = level->bd_num_skeletons_needed_for_pot;
+  cave->skeletons_worth_diamonds       = level->bd_skeleton_worth_num_diamonds;
+
+  cave->expanding_wall_looks_like      = LEVEL_TO_CAVE(level->bd_expanding_wall_looks_like);
+  cave->dirt_looks_like                        = LEVEL_TO_CAVE(level->bd_sand_looks_like);
+
+  cave->creatures_backwards                     = level->bd_creatures_start_backwards;
+  cave->creatures_direction_auto_change_on_start = level->bd_creatures_turn_on_hatching;
+  cave->creatures_direction_auto_change_time    = level->bd_creatures_auto_turn_delay;
+
+  cave->gravity                                = level->bd_gravity_direction;
+  cave->gravity_switch_active          = level->bd_gravity_switch_active;
+  cave->gravity_change_time            = level->bd_gravity_switch_delay;
+
+  // level name
   strncpy(cave->name, level->name, sizeof(GdString));
   cave->name[sizeof(GdString) - 1] = '\0';
 
+  // playfield elements
   for (x = 0; x < cave->w; x++)
     for (y = 0; y < cave->h; y++)
-      cave->map[y][x] = map_element_RND_to_BD(level->field[x][y]);
+      cave->map[y][x] = LEVEL_TO_CAVE(level->field[x][y]);
 }
 
 static void CopyNativeLevel_BD_to_RND(struct LevelInfo *level)
@@ -3794,34 +4280,140 @@ static void CopyNativeLevel_BD_to_RND(struct LevelInfo *level)
   level->fieldx = MIN(cave->w, MAX_LEV_FIELDX);
   level->fieldy = MIN(cave->h, MAX_LEV_FIELDY);
 
+  // level type
+  level->bd_intermission               = cave->intermission;
+
+  // level settings
   level->time                          = cave->level_time[bd_level_nr];
   level->gems_needed                   = cave->level_diamonds[bd_level_nr];
-  level->time_magic_wall               = cave->level_magic_wall_time[bd_level_nr];
 
+  // game timing
+  level->bd_scheduling_type            = cave->scheduling;
+  level->bd_pal_timing                 = cave->pal_timing;
   level->bd_cycle_delay_ms             = cave->level_speed[bd_level_nr];
   level->bd_cycle_delay_c64            = cave->level_ckdelay[bd_level_nr];
   level->bd_hatching_delay_cycles      = cave->level_hatching_delay_frame[bd_level_nr];
   level->bd_hatching_delay_seconds     = cave->level_hatching_delay_time[bd_level_nr];
 
+  // scores
   level->score[SC_TIME_BONUS]          = cave->level_timevalue[bd_level_nr];
   level->score[SC_EMERALD]             = cave->diamond_value;
   level->score[SC_DIAMOND_EXTRA]       = cave->extra_diamond_value;
 
-  level->bd_scheduling_type            = cave->scheduling;
-  level->bd_pal_timing                 = cave->pal_timing;
-  level->bd_intermission               = cave->intermission;
-  level->bd_diagonal_movements         = cave->diagonal_movements;
-
+  // compatibility settings
   level->bd_line_shifting_borders      = cave->lineshift;
+  level->bd_scan_first_and_last_row    = cave->border_scan_first_and_last;
+  level->bd_short_explosions           = cave->short_explosions;
+  level->bd_gravity_affects_all                = cave->gravity_affects_all;
 
+  // player properties
+  level->bd_diagonal_movements         = cave->diagonal_movements;
+  level->bd_topmost_player_active      = cave->active_is_first_found;
+  level->bd_pushing_prob               = cave->pushing_stone_prob       / 10000;
+  level->bd_pushing_prob_with_sweet    = cave->pushing_stone_prob_sweet / 10000;
+  level->bd_push_mega_rock_with_sweet  = cave->mega_stones_pushable_with_sweet;
+  level->bd_snap_element               = CAVE_TO_LEVEL(cave->snap_element);
+
+  // element properties
+  level->bd_clock_extra_time           = cave->level_bonus_time[bd_level_nr];
+  level->bd_voodoo_collects_diamonds   = cave->voodoo_collects_diamonds;
+  level->bd_voodoo_hurt_kills_player   = cave->voodoo_any_hurt_kills_player;
+  level->bd_voodoo_dies_by_rock                = cave->voodoo_dies_by_stone;
+  level->bd_voodoo_vanish_by_explosion = cave->voodoo_disappear_in_explosion;
+  level->bd_voodoo_penalty_time                = cave->level_penalty_time[bd_level_nr];
+  level->time_magic_wall               = cave->level_magic_wall_time[bd_level_nr];
+  level->bd_magic_wall_wait_hatching   = cave->magic_timer_wait_for_hatching;
+  level->bd_magic_wall_stops_amoeba    = cave->magic_wall_stops_amoeba;
+
+  level->bd_magic_wall_diamond_to      = CAVE_TO_LEVEL(cave->magic_diamond_to);
+  level->bd_magic_wall_rock_to         = CAVE_TO_LEVEL(cave->magic_stone_to);
+  level->bd_magic_wall_mega_rock_to    = CAVE_TO_LEVEL(cave->magic_mega_stone_to);
+  level->bd_magic_wall_nut_to          = CAVE_TO_LEVEL(cave->magic_nut_to);
+  level->bd_magic_wall_nitro_pack_to   = CAVE_TO_LEVEL(cave->magic_nitro_pack_to);
+  level->bd_magic_wall_flying_diamond_to= CAVE_TO_LEVEL(cave->magic_flying_diamond_to);
+  level->bd_magic_wall_flying_rock_to  = CAVE_TO_LEVEL(cave->magic_flying_stone_to);
+
+  level->bd_amoeba_wait_for_hatching   = cave->amoeba_timer_wait_for_hatching;
+  level->bd_amoeba_start_immediately   = cave->amoeba_timer_started_immediately;
+  level->bd_amoeba_2_explode_by_amoeba = cave->amoeba_2_explodes_by_amoeba;
+  level->bd_amoeba_threshold_too_big   = cave->level_amoeba_threshold[bd_level_nr];
+  level->bd_amoeba_slow_growth_time    = cave->level_amoeba_time[bd_level_nr];
+  level->bd_amoeba_slow_growth_rate    = cave->amoeba_growth_prob      / 10000;
+  level->bd_amoeba_fast_growth_rate    = cave->amoeba_fast_growth_prob / 10000;
+  level->bd_amoeba_2_threshold_too_big = cave->level_amoeba_2_threshold[bd_level_nr];
+  level->bd_amoeba_2_slow_growth_time  = cave->level_amoeba_2_time[bd_level_nr];
+  level->bd_amoeba_2_slow_growth_rate  = cave->amoeba_2_growth_prob      / 10000;
+  level->bd_amoeba_2_fast_growth_rate  = cave->amoeba_2_fast_growth_prob / 10000;
+
+  level->bd_amoeba_content_too_big     = CAVE_TO_LEVEL(cave->amoeba_too_big_effect);
+  level->bd_amoeba_content_enclosed    = CAVE_TO_LEVEL(cave->amoeba_enclosed_effect);
+  level->bd_amoeba_2_content_too_big   = CAVE_TO_LEVEL(cave->amoeba_2_too_big_effect);
+  level->bd_amoeba_2_content_enclosed  = CAVE_TO_LEVEL(cave->amoeba_2_enclosed_effect);
+  level->bd_amoeba_2_content_exploding = CAVE_TO_LEVEL(cave->amoeba_2_explosion_effect);
+  level->bd_amoeba_2_content_looks_like        = CAVE_TO_LEVEL(cave->amoeba_2_looks_like);
+
+  level->bd_slime_is_predictable       = cave->slime_predictable;
+  level->bd_slime_correct_random       = cave->slime_correct_random;
+  level->bd_slime_permeability_rate    = cave->level_slime_permeability[bd_level_nr] / 10000;
+  level->bd_slime_permeability_bits_c64        = cave->level_slime_permeability_c64[bd_level_nr];
+  level->bd_slime_random_seed_c64      = cave->level_slime_seed_c64[bd_level_nr];
+  level->bd_cave_random_seed_c64       = cave->level_rand[bd_level_nr];
+  level->bd_slime_eats_element_1       = CAVE_TO_LEVEL(cave->slime_eats_1);
+  level->bd_slime_converts_to_element_1        = CAVE_TO_LEVEL(cave->slime_converts_1);
+  level->bd_slime_eats_element_2       = CAVE_TO_LEVEL(cave->slime_eats_2);
+  level->bd_slime_converts_to_element_2        = CAVE_TO_LEVEL(cave->slime_converts_2);
+  level->bd_slime_eats_element_3       = CAVE_TO_LEVEL(cave->slime_eats_3);
+  level->bd_slime_converts_to_element_3        = CAVE_TO_LEVEL(cave->slime_converts_3);
+
+  level->bd_acid_eats_element          = CAVE_TO_LEVEL(cave->acid_eats_this);
+  level->bd_acid_spread_rate           = cave->acid_spread_ratio / 10000;
+  level->bd_acid_turns_to_element      = CAVE_TO_LEVEL(cave->acid_turns_to);
+
+  level->bd_biter_move_delay           = cave->biter_delay_frame;
+  level->bd_biter_eats_element         = CAVE_TO_LEVEL(cave->biter_eat);
+
+  level->bd_bladder_converts_by_element        = CAVE_TO_LEVEL(cave->bladder_converts_by);
+
+  level->bd_change_expanding_wall      = cave->expanding_wall_changed;
+
+  level->bd_replicators_active         = cave->replicators_active;
+  level->bd_replicator_create_delay    = cave->replicator_delay_frame;
+
+  level->bd_conveyor_belts_active      = cave->conveyor_belts_active;
+  level->bd_conveyor_belts_changed     = cave->conveyor_belts_direction_changed;
+
+  level->bd_water_cannot_flow_down     = cave->water_does_not_flow_down;
+
+  level->bd_nut_content                        = CAVE_TO_LEVEL(cave->nut_turns_to_when_crushed);
+
+  level->bd_hammer_walls_break_delay   = cave->pneumatic_hammer_frame;
+  level->bd_hammer_walls_reappear      = cave->hammered_walls_reappear;
+  level->bd_hammer_walls_reappear_delay        = cave->hammered_wall_reappear_frame;
+
+  level->bd_num_skeletons_needed_for_pot= cave->skeletons_needed_for_pot;
+  level->bd_skeleton_worth_num_diamonds        = cave->skeletons_worth_diamonds;
+
+  level->bd_expanding_wall_looks_like  = CAVE_TO_LEVEL(cave->expanding_wall_looks_like);
+  level->bd_sand_looks_like            = CAVE_TO_LEVEL(cave->dirt_looks_like);
+
+  level->bd_creatures_start_backwards  = cave->creatures_backwards;
+  level->bd_creatures_turn_on_hatching = cave->creatures_direction_auto_change_on_start;
+  level->bd_creatures_auto_turn_delay  = cave->creatures_direction_auto_change_time;
+
+  level->bd_gravity_direction          = cave->gravity;
+  level->bd_gravity_switch_active      = cave->gravity_switch_active;
+  level->bd_gravity_switch_delay       = cave->gravity_change_time;
+
+  // level name
   char *cave_name = getStringPrint("%s / %d", cave->name, bd_level_nr + 1);
 
   strncpy(level->name, cave_name, MAX_LEVEL_NAME_LEN);
   level->name[MAX_LEVEL_NAME_LEN] = '\0';
 
+  // playfield elements
   for (x = 0; x < level->fieldx; x++)
     for (y = 0; y < level->fieldy; y++)
-      level->field[x][y] = map_element_BD_to_RND(cave->map[y][x]);
+      level->field[x][y] = CAVE_TO_LEVEL(cave->map[y][x]);
 
   checked_free(cave_name);
 }
@@ -10154,6 +10746,10 @@ static struct TokenInfo editor_cascade_setup_tokens[] =
     TYPE_SWITCH,
     &setup.editor_cascade.el_bd_native,                "editor.cascade.el_bd_native"
   },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_bd_effects,       "editor.cascade.el_bd_effects"
+  },
   {
     TYPE_SWITCH,
     &setup.editor_cascade.el_em,               "editor.cascade.el_em"
@@ -10848,6 +11444,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
 
   si->editor.el_boulderdash            = TRUE;
   si->editor.el_boulderdash_native     = TRUE;
+  si->editor.el_boulderdash_effects    = TRUE;
   si->editor.el_emerald_mine           = TRUE;
   si->editor.el_emerald_mine_club      = TRUE;
   si->editor.el_more                   = TRUE;
@@ -11022,6 +11619,7 @@ static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si)
 {
   si->editor_cascade.el_bd             = TRUE;
   si->editor_cascade.el_bd_native      = TRUE;
+  si->editor_cascade.el_bd_effects     = FALSE;
   si->editor_cascade.el_em             = TRUE;
   si->editor_cascade.el_emc            = TRUE;
   si->editor_cascade.el_rnd            = TRUE;