From: Holger Schemel Date: Tue, 2 Apr 2024 17:55:41 +0000 (+0200) Subject: added option for BD1 magic wall / amoeba bug for native BD engine X-Git-Tag: 4.4.0.0-test-1~111 X-Git-Url: https://git.artsoft.org/?a=commitdiff_plain;h=0f6b2c62e0c72652c8b2093995845e02b91c51d3;p=rocksndiamonds.git added option for BD1 magic wall / amoeba bug for native BD engine --- diff --git a/src/editor.c b/src/editor.c index a91aba1d..1f17252a 100644 --- a/src/editor.c +++ b/src/editor.c @@ -752,6 +752,7 @@ enum GADGET_ID_BD_MAGIC_WALL_ZERO_INFINITE, GADGET_ID_BD_MAGIC_WALL_WAIT_HATCHING, GADGET_ID_BD_MAGIC_WALL_STOPS_AMOEBA, + GADGET_ID_BD_MAGIC_WALL_BREAK_SCAN, GADGET_ID_BD_AMOEBA_WAIT_FOR_HATCHING, GADGET_ID_BD_AMOEBA_START_IMMEDIATELY, GADGET_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA, @@ -1109,6 +1110,7 @@ enum ED_CHECKBUTTON_ID_BD_MAGIC_WALL_ZERO_INFINITE, ED_CHECKBUTTON_ID_BD_MAGIC_WALL_WAIT_HATCHING, ED_CHECKBUTTON_ID_BD_MAGIC_WALL_STOPS_AMOEBA, + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_BREAK_SCAN, ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING, ED_CHECKBUTTON_ID_BD_AMOEBA_START_IMMEDIATELY, ED_CHECKBUTTON_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA, @@ -3849,6 +3851,14 @@ static struct NULL, NULL, "Stop amoeba and turn to diamonds", "Activation changes amoeba to diamonds" }, + { + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_BREAK_SCAN, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_BD_MAGIC_WALL_BREAK_SCAN, GADGET_ID_NONE, + &level.bd_magic_wall_break_scan, + NULL, NULL, + "Emulate amoeba bug in BD1", "Use buggy BD1 behavior" + }, { ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING, ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), @@ -4487,7 +4497,7 @@ static struct { ED_DRAWING_ID_BD_MAGIC_WALL_DIAMOND_TO, - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(5), + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(6), ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_BD_MAGIC_WALL_DIAMOND_TO, GADGET_ID_NONE, &level.bd_magic_wall_diamond_to, 1, 1, @@ -4495,7 +4505,7 @@ static struct }, { ED_DRAWING_ID_BD_MAGIC_WALL_ROCK_TO, - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(6), + 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_MAGIC_WALL_ROCK_TO, GADGET_ID_NONE, &level.bd_magic_wall_rock_to, 1, 1, @@ -4503,7 +4513,7 @@ static struct }, { ED_DRAWING_ID_BD_MAGIC_WALL_MEGA_ROCK_TO, - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(7), + 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_MAGIC_WALL_MEGA_ROCK_TO, GADGET_ID_NONE, &level.bd_magic_wall_mega_rock_to, 1, 1, @@ -4511,7 +4521,7 @@ static struct }, { ED_DRAWING_ID_BD_MAGIC_WALL_NUT_TO, - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(8), + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(9), ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_BD_MAGIC_WALL_NUT_TO, GADGET_ID_NONE, &level.bd_magic_wall_nut_to, 1, 1, @@ -4519,7 +4529,7 @@ static struct }, { ED_DRAWING_ID_BD_MAGIC_WALL_NITRO_PACK_TO, - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(9), + 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_MAGIC_WALL_NITRO_PACK_TO, GADGET_ID_NONE, &level.bd_magic_wall_nitro_pack_to, 1, 1, @@ -4527,7 +4537,7 @@ static struct }, { ED_DRAWING_ID_BD_MAGIC_WALL_FLYING_DIAMOND_TO, - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(10), + 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_MAGIC_WALL_FLYING_DIAMOND_TO, GADGET_ID_NONE, &level.bd_magic_wall_flying_diamond_to, 1, 1, @@ -4535,7 +4545,7 @@ static struct }, { ED_DRAWING_ID_BD_MAGIC_WALL_FLYING_ROCK_TO, - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(11), + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(12), ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_BD_MAGIC_WALL_FLYING_ROCK_TO, GADGET_ID_NONE, &level.bd_magic_wall_flying_rock_to, 1, 1, @@ -11938,6 +11948,7 @@ static void DrawPropertiesConfig(void) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_ZERO_INFINITE); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_WAIT_HATCHING); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_STOPS_AMOEBA); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_BREAK_SCAN); MapDrawingArea(ED_DRAWING_ID_BD_MAGIC_WALL_DIAMOND_TO); MapDrawingArea(ED_DRAWING_ID_BD_MAGIC_WALL_ROCK_TO); diff --git a/src/files.c b/src/files.c index 25943b63..040a9448 100644 --- a/src/files.c +++ b/src/files.c @@ -742,6 +742,11 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] = TYPE_BOOLEAN, CONF_VALUE_8_BIT(3), &li.bd_magic_wall_zero_infinite, TRUE }, + { + EL_BD_MAGIC_WALL, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(4), + &li.bd_magic_wall_break_scan, FALSE + }, { EL_BD_MAGIC_WALL, -1, TYPE_ELEMENT, CONF_VALUE_16_BIT(1), @@ -4272,6 +4277,7 @@ static void CopyNativeLevel_RND_to_BD(struct LevelInfo *level) cave->magic_timer_zero_is_infinite = level->bd_magic_wall_zero_infinite; 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_wall_breakscan = level->bd_magic_wall_break_scan; 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); @@ -4436,6 +4442,7 @@ static void CopyNativeLevel_BD_to_RND(struct LevelInfo *level) level->bd_magic_wall_zero_infinite = cave->magic_timer_zero_is_infinite; 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_break_scan = cave->magic_wall_breakscan; 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); diff --git a/src/game_bd/bd_c64import.c b/src/game_bd/bd_c64import.c index 61486da7..9047c75f 100644 --- a/src/game_bd/bd_c64import.c +++ b/src/game_bd/bd_c64import.c @@ -221,6 +221,7 @@ GdPropertyDefault gd_defaults_bd1[] = {CAVE_OFFSET(intermission_instantlife), TRUE}, {CAVE_OFFSET(intermission_rewardlife), FALSE}, {CAVE_OFFSET(magic_wall_stops_amoeba), TRUE}, + {CAVE_OFFSET(magic_wall_breakscan), TRUE}, {CAVE_OFFSET(magic_timer_zero_is_infinite), TRUE}, {CAVE_OFFSET(magic_timer_wait_for_hatching), FALSE}, {CAVE_OFFSET(pushing_stone_prob), 250000}, diff --git a/src/game_bd/bd_cave.h b/src/game_bd/bd_cave.h index d8f45591..483b54fe 100644 --- a/src/game_bd/bd_cave.h +++ b/src/game_bd/bd_cave.h @@ -394,6 +394,8 @@ typedef struct _gd_cave int level_magic_wall_time[5]; // magic wall 'on' state for each level (seconds) boolean magic_wall_stops_amoeba; // Turning on magic wall changes amoeba to diamonds. // Original BD: yes, constkit: no + boolean magic_wall_breakscan; // Currently this setting enabled will turn the amoeba to + // an enclosed state. To implement buggy BD1 behaviour. boolean magic_timer_zero_is_infinite; // magic wall timer 0 is interpreted as infinite boolean magic_timer_wait_for_hatching;// magic wall timer does not start before player's birth boolean magic_wall_sound; // magic wall has sound @@ -587,6 +589,7 @@ typedef struct _gd_cave int amoeba_2_max_count; // selected amoeba 2 threshold for this level GdAmoebaState amoeba_state; // state of amoeba 1 GdAmoebaState amoeba_2_state; // state of amoeba 2 + boolean convert_amoeba_this_frame; // To implement BD1 buggy amoeba+magic wall behaviour. int magic_wall_time; // magic wall 'on' state for seconds int slime_permeability; // true random slime int slime_permeability_c64; // Appearing in bd 2 diff --git a/src/game_bd/bd_cavedb.c b/src/game_bd/bd_cavedb.c index b54eff89..a00de067 100644 --- a/src/game_bd/bd_cavedb.c +++ b/src/game_bd/bd_cavedb.c @@ -550,6 +550,7 @@ const GdStructDescriptor gd_cave_properties[] = {"MagicWallProperties.zeroisinfinite", GD_TYPE_BOOLEAN, 0, N_("Milling time 0 is infinite"), CAVE_OFFSET(magic_timer_zero_is_infinite), 1, N_("This determines if the magic wall timer 0 is interpreted as infinite.")}, {"MagicWallProperties.waitforhatching", GD_TYPE_BOOLEAN, 0, N_("Timer waits for hatching"), CAVE_OFFSET(magic_timer_wait_for_hatching), 1, N_("This determines if the magic wall timer starts before the player appearing. Magic can always be activated before that; but if this is set to true, the timer will not start.")}, {"MagicWallProperties.convertamoeba", GD_TYPE_BOOLEAN, 0, N_("Stops amoeba"), CAVE_OFFSET(magic_wall_stops_amoeba), 1, N_("When the magic wall is activated, it can convert amoeba into diamonds.")}, + {"MagicWallProperties.breakscan", GD_TYPE_BOOLEAN, 0, N_("BD1 amoeba bug"), CAVE_OFFSET(magic_wall_breakscan), 1, N_("This setting emulates the BD1 bug, where a stone or a diamond falling into a magic wall sometimes caused the active amoeba to convert into a diamond. The rule is: if all amoeba cells above or left to the point where the stone or the diamond falls into the magic wall are enclosed, the amoeba is converted. The timing implications of the bug are not emulated.")}, {"", GD_LABEL, 0, N_("Conversions")}, {"MagicWallProperties", GD_TYPE_ELEMENT, 0, N_("Diamond to"), CAVE_OFFSET(magic_diamond_to), 1, N_("As a special effect, magic walls can convert diamonds to any other element.")}, {"MagicWallProperties", GD_TYPE_ELEMENT, 0, N_("Stone to"), CAVE_OFFSET(magic_stone_to), 1, N_("As a special effect, magic walls can convert stones to any other element.")}, diff --git a/src/game_bd/bd_caveengine.c b/src/game_bd/bd_caveengine.c index 46c97e57..e221ca77 100644 --- a/src/game_bd/bd_caveengine.c +++ b/src/game_bd/bd_caveengine.c @@ -1371,6 +1371,9 @@ static boolean do_fall_try_magic(GdCave *cave, int x, int y, // active or non-active or anything, element falling in will always disappear store(cave, x, y, O_SPACE); + if (cave->magic_wall_breakscan && cave->amoeba_state == GD_AM_AWAKE) + cave->convert_amoeba_this_frame = TRUE; + return TRUE; } else @@ -1604,6 +1607,9 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, // score collected this frame cave->score = 0; + // to implement buggy bd1 amoeba+magic wall behaviour + cave->convert_amoeba_this_frame = FALSE; + // suicide only kills the active player // player_x, player_y was set by the previous iterate routine, or the cave setup. // we must check if there is a player or not - he may have exploded or something like that @@ -2847,6 +2853,13 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, // ============================================================================ case O_AMOEBA: + // emulating BD1 amoeba+magic wall bug + if (cave->convert_amoeba_this_frame && amoeba_found_enclosed) + { + store(cave, x, y, cave->amoeba_enclosed_effect); + break; + } + amoeba_count++; switch (cave->amoeba_state) { diff --git a/src/main.h b/src/main.h index 4472b912..13d92656 100644 --- a/src/main.h +++ b/src/main.h @@ -3665,6 +3665,7 @@ struct LevelInfo boolean bd_magic_wall_zero_infinite; // BD magic wall with timer of zero runs infinitely boolean bd_magic_wall_wait_hatching; // BD magic wall waits for player's birth boolean bd_magic_wall_stops_amoeba; // BD magic wall can stop amoeba and turn to diamonds + boolean bd_magic_wall_break_scan; // BD magic wall setting to implement buggy BD1 behaviour int bd_magic_wall_diamond_to; // BD magic wall turns diamonds to specified element int bd_magic_wall_rock_to; // BD magic wall turns rocks to specified element int bd_magic_wall_mega_rock_to; // BD magic wall turns mega rocks to specified element