From da7ffa495fc3f68280a1a970e5be429ec79911fb Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 30 Jun 2024 15:06:59 +0200 Subject: [PATCH 01/16] added BD graphics definitions for cracking nut --- src/conf_gfx.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/conf_gfx.c b/src/conf_gfx.c index e452f3bd..5d28a11b 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -853,8 +853,16 @@ struct ConfigInfo image_config[] = { "bdx_trapped_diamond.ypos", "6" }, { "bdx_trapped_diamond.frames", "1" }, - { "bdx_nut", UNDEFINED_FILENAME }, - { "bdx_nut.clone_from", "nut" }, + { "bdx_nut", "RocksBD.png" }, + { "bdx_nut.xpos", "0" }, + { "bdx_nut.ypos", "13" }, + { "bdx_nut.frames", "1" }, + { "bdx_nut.breaking", "RocksBD.png" }, + { "bdx_nut.breaking.xpos", "0" }, + { "bdx_nut.breaking.ypos", "13" }, + { "bdx_nut.breaking.frames", "4" }, + { "bdx_nut.breaking.delay", "8" }, + { "bdx_nut.breaking.anim_mode", "linear" }, { "bdx_nut.falling.EDITOR", "RocksBD2.png" }, { "bdx_nut.falling.EDITOR.xpos", "5" }, { "bdx_nut.falling.EDITOR.ypos", "2" }, -- 2.34.1 From e0f109524b99fba154b810ee385c153cf827a771 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 30 Jun 2024 15:11:01 +0200 Subject: [PATCH 02/16] added BD graphics definitions for chasing rock --- src/conf_gfx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 5d28a11b..0ead706d 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -1096,8 +1096,10 @@ struct ConfigInfo image_config[] = { "bdx_waiting_rock.EDITOR.xpos", "4" }, { "bdx_waiting_rock.EDITOR.ypos", "2" }, - { "bdx_chasing_rock", UNDEFINED_FILENAME }, - { "bdx_chasing_rock.clone_from", "bdx_rock" }, + { "bdx_chasing_rock", "RocksBD.png" }, + { "bdx_chasing_rock.xpos", "0" }, + { "bdx_chasing_rock.ypos", "4" }, + { "bdx_chasing_rock.frames", "1" }, { "bdx_ghost", "RocksBD.png" }, { "bdx_ghost.xpos", "0" }, -- 2.34.1 From 9b6032c77dce1efc1f5efa285c9a4321f6f5e9f3 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 30 Jun 2024 16:39:18 +0200 Subject: [PATCH 03/16] added some safety checks to string functions --- src/libgame/misc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libgame/misc.c b/src/libgame/misc.c index ed4bd5d6..6b4acba8 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -1222,6 +1222,9 @@ char *getStringCopyNStatic(const char *s, int n) char *getStringToUpper(const char *s) { + if (s == NULL) + return NULL; + char *s_copy = checked_malloc(strlen(s) + 1); char *s_ptr = s_copy; @@ -1234,6 +1237,9 @@ char *getStringToUpper(const char *s) char *getStringToLower(const char *s) { + if (s == NULL) + return NULL; + char *s_copy = checked_malloc(strlen(s) + 1); char *s_ptr = s_copy; -- 2.34.1 From 88524b2ff8ec59a925cab0d34fbebb401091d512 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 30 Jun 2024 16:40:19 +0200 Subject: [PATCH 04/16] added mapping (scanned) BD run-time elements to normal BD elements --- src/game_bd/bd_cave.c | 2 +- src/game_bd/bd_caveengine.c | 4 ++-- src/tools.c | 6 ++++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/game_bd/bd_cave.c b/src/game_bd/bd_cave.c index 6e474620..0adabeb8 100644 --- a/src/game_bd/bd_cave.c +++ b/src/game_bd/bd_cave.c @@ -1665,7 +1665,7 @@ void gd_cave_adler_checksum_more(GdCave *cave, unsigned int *a, unsigned int *b) for (y = 0; y < cave->h; y++) for (x = 0; x < cave->w; x++) { - *a += gd_elements[cave->map[y][x]].character; + *a += gd_elements[cave->map[y][x] & O_MASK].character; *b += *a; *a %= 65521; diff --git a/src/game_bd/bd_caveengine.c b/src/game_bd/bd_caveengine.c index 888c73d3..0f9eecc7 100644 --- a/src/game_bd/bd_caveengine.c +++ b/src/game_bd/bd_caveengine.c @@ -1713,7 +1713,7 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, } // add the ckdelay correction value for every element seen. - cave->ckdelay += gd_elements[get(cave, x, y)].ckdelay; + cave->ckdelay += gd_elements[get(cave, x, y) & O_MASK].ckdelay; switch (get(cave, x, y)) { @@ -3975,7 +3975,7 @@ void set_initial_cave_speed(GdCave *cave) for (x = 0; x < cave->w; x++) { // add the ckdelay correction value for every element seen. - cave->ckdelay += gd_elements[get(cave, x, y)].ckdelay; + cave->ckdelay += gd_elements[get(cave, x, y) & O_MASK].ckdelay; } } diff --git a/src/tools.c b/src/tools.c index d56532d1..17cd794a 100644 --- a/src/tools.c +++ b/src/tools.c @@ -7686,6 +7686,9 @@ int map_element_BD_to_RND_cave(int element_bd) mapping_initialized = TRUE; } + // always map (scanned) run-time elements to normal elements + element_bd &= O_MASK; + if (element_bd < 0 || element_bd >= O_MAX_ALL) { Warn("invalid BD element %d", element_bd); @@ -7716,6 +7719,9 @@ int map_element_BD_to_RND_game(int element_bd) mapping_initialized = TRUE; } + // always map (scanned) run-time elements to normal elements + element_bd &= O_MASK; + if (element_bd < 0 || element_bd >= O_MAX_ALL) { Warn("invalid BD element %d", element_bd); -- 2.34.1 From 95665b24feb6470c882364d4c77095d018de86a9 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 30 Jun 2024 17:01:59 +0200 Subject: [PATCH 05/16] added reading (more) scanned BD elements from BDCFF files --- src/game_bd/bd_cave.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/game_bd/bd_cave.c b/src/game_bd/bd_cave.c index 0adabeb8..7c958619 100644 --- a/src/game_bd/bd_cave.c +++ b/src/game_bd/bd_cave.c @@ -278,20 +278,23 @@ void gd_cave_init(void) for (i = 0; i < O_MAX; i++) { - char *key; + char *key_1 = getStringToUpper(gd_elements[i].filename); - key = getStringToUpper(gd_elements[i].filename); + if (hashtable_exists(name_to_element, key_1)) // hash value may be 0 + Warn("Name %s already used for element %x", key_1, i); - if (hashtable_exists(name_to_element, key)) // hash value may be 0 - Warn("Name %s already used for element %x", key, i); + hashtable_insert(name_to_element, key_1, INT_TO_PTR(i)); + // ^^^ do not free "key_1", as hash table needs it during the whole time! - hashtable_insert(name_to_element, key, INT_TO_PTR(i)); - // ^^^ do not free "key", as hash table needs it during the whole time! + char *key_2 = getStringCat2("SCANNED_", key_1); // new string - key = getStringCat2("SCANNED_", key); // new string + hashtable_insert(name_to_element, key_2, INT_TO_PTR(i)); + // once again, do not free "key_2" ^^^ - hashtable_insert(name_to_element, key, INT_TO_PTR(i)); - // once again, do not free "key" ^^^ + char *key_3 = getStringCat2("SCANN_", key_1); // new string + + hashtable_insert(name_to_element, key_3, INT_TO_PTR(i)); + // once again, do not free "key_3" ^^^ } // for compatibility with tim stridmann's memorydump->bdcff converter... .... ... -- 2.34.1 From a027f851efb6f152594af57d465484ee697ae0fb Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 1 Jul 2024 10:17:37 +0200 Subject: [PATCH 06/16] fixed bug causing BD engine hanging in wrap-around scrolling edge case --- src/game_bd/bd_graphics.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/game_bd/bd_graphics.c b/src/game_bd/bd_graphics.c index c509ec57..793987e2 100644 --- a/src/game_bd/bd_graphics.c +++ b/src/game_bd/bd_graphics.c @@ -334,6 +334,11 @@ boolean gd_scroll(GdGame *game, boolean exact_scroll, boolean immediate) scroll_speed_last = -1; // check if active player is visible at the moment. + // but only if scrolling happened at all! + if (!changed) + return FALSE; + + // check if active player is outside drawing area. if yes, we should wait for scrolling. return player_out_of_window(game, player_x, player_y); } -- 2.34.1 From b62cb2a81128fb57f929f6342fa9b31156bb9605 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 1 Jul 2024 22:18:34 +0200 Subject: [PATCH 07/16] added BD file format specific hacks (like diagonal movement) --- src/game_bd/bd_c64import.c | 109 ++++++++++++++++++++++++++++++++++++- src/game_bd/bd_c64import.h | 12 ++++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/src/game_bd/bd_c64import.c b/src/game_bd/bd_c64import.c index b3e0310b..c89fdd02 100644 --- a/src/game_bd/bd_c64import.c +++ b/src/game_bd/bd_c64import.c @@ -573,6 +573,29 @@ GdEngine gd_cave_get_engine_from_string(const char *param) // // ============================================================================ +/* + * Checksum function for cave import routines. + * Used to recognize caves which need some hacks added, + * besides normal importing. + * @param data The input array of bytes + * @param length The size + * @return 16-bit checksum + */ + +static unsigned int checksum(const byte *data, int length) +{ + unsigned int a = 1, b = 0; + int i; + + for (i = 0; i < length; i++) + { + a = (a + data[i]) % 251; // the prime closest to (and less than) 256 + b = (b + a) % 251; + } + + return b * 256 + a; +} + /* take care of required diamonds values == 0 or > 100. in original bd, the counter was only two-digit. so bd3 cave f @@ -1983,6 +2006,46 @@ static int cave_copy_from_crdr_7(GdCave *cave, const byte *data, int remaining_b return 15 + 0x49 + index; } +// Deluxe Caves 3 hacks +static void deluxe_caves_3_add_specials(GdCave *cave, const int cavenum) +{ + cave->snap_element = O_EXPLODE_1; + cave->diagonal_movements = TRUE; + + switch (cavenum) + { + case 6: // cave f + cave->stone_bouncing_effect = O_BUTTER_1; + cave->diamond_falling_effect = O_EXPLODE_3; + break; + + case 7: // cave g + Warn("effects not supported"); + break; + + case 13: // cave l + Warn("effects not working perfectly"); + cave->stone_bouncing_effect = O_FIREFLY_1; + break; + + case 18: + cave->diamond_bouncing_effect = O_STONE; + break; + + default: + break; + } +} + +// Crazy Dream 7 hacks +static void crazy_dream_7_add_specials(GdCave *cave) +{ + if (strEqual(cave->name, "Crazy maze")) + cave->skeletons_needed_for_pot = 0; +} + +// This function adds some hardcoded elements to a Crazy Dream 9 cave. +// Crazy Dream 9 had some caves and random fills, which were not encoded in the cave data. static void crazy_dream_9_add_specials(GdCave *cave, const byte *buf, const int length) { byte checksum; @@ -2061,6 +2124,23 @@ static void crazy_dream_9_add_specials(GdCave *cave, const byte *buf, const int } } +// Masters Boulder hacks +static void masters_boulder_add_hack(GdCave *cave, const int cavenum) +{ + int i; + + switch (cavenum) + { + case 1: // cave b + for (i = 0; i < 5; i++) + cave->level_hatching_delay_time[i] = 3; // secs + break; + + default: + break; + } +} + // crazy light contruction kit static int cave_copy_from_crli(GdCave *cave, const byte *data, int remaining_bytes) { @@ -2421,6 +2501,23 @@ List *gd_caveset_import_from_buffer (const byte *buf, size_t length) buf += 12; length = encodedlength; + // check for hacks. + GdImportHack hack = GD_HACK_NONE; + unsigned int cs = checksum(buf, length); + + if (format == GD_FORMAT_PLC && length == 10240 && cs == 0xbdec) + hack = GD_HACK_CRDR_1; + if (format == GD_FORMAT_CRLI && length == 9895 && cs == 0xbc4e) + hack = GD_HACK_CRDR_9; + if (format == GD_FORMAT_BD1 && length == 1634 && cs == 0xf725) + hack = GD_HACK_DC1; + if (format == GD_FORMAT_BD1 && length == 1452 && cs == 0xb4a6) + hack = GD_HACK_DC3; + if (format == GD_FORMAT_CRDR_7 && length == 3759 && cs == 0x16b5) + hack = GD_HACK_CRDR_7; + if (format == GD_FORMAT_BD1 && length == 1241 && cs == 0x926f) + hack = GD_HACK_MB; + bufp = 0; cavenum = 0; @@ -2457,6 +2554,10 @@ List *gd_caveset_import_from_buffer (const byte *buf, size_t length) case GD_FORMAT_BD1_ATARI: case GD_FORMAT_DC1: cavelength = cave_copy_from_bd1(newcave, buf + bufp, length - bufp, format); + if (cavelength != -1 && hack == GD_HACK_DC3) + deluxe_caves_3_add_specials(newcave, cavenum); + if (cavelength != -1 && hack == GD_HACK_MB) + masters_boulder_add_hack(newcave, cavenum); break; case GD_FORMAT_BD2: case GD_FORMAT_BD2_ATARI: @@ -2483,6 +2584,8 @@ List *gd_caveset_import_from_buffer (const byte *buf, size_t length) case GD_FORMAT_PLC: // peter liepa construction kit case GD_FORMAT_PLC_ATARI: // peter liepa construction kit, atari version cavelength = cave_copy_from_plck(newcave, buf + bufp, length - bufp, format); + if (cavelength != -1 && hack == GD_HACK_CRDR_1) + newcave->diagonal_movements = TRUE; break; case GD_FORMAT_DLB: @@ -2515,11 +2618,13 @@ List *gd_caveset_import_from_buffer (const byte *buf, size_t length) case GD_FORMAT_CRDR_7: cavelength = cave_copy_from_crdr_7 (newcave, buf + bufp, length - bufp); + if (cavelength != -1 && hack == GD_HACK_CRDR_7) + crazy_dream_7_add_specials(newcave); break; case GD_FORMAT_CRDR_9: cavelength = cave_copy_from_crli (newcave, buf + bufp, length - bufp); - if (cavelength != -1) + if (cavelength != -1 && hack == GD_HACK_CRDR_9) crazy_dream_9_add_specials(newcave, buf, cavelength); break; @@ -2554,6 +2659,7 @@ List *gd_caveset_import_from_buffer (const byte *buf, size_t length) // try to detect if plc caves are in standard layout. // that is, caveset looks like an original, (4 cave,1 intermission)+ if (format == GD_FORMAT_PLC) + { // if no selection table stored by any2gdash if ((buf[2 + 0x1f0] != buf[2 + 0x1f1] - 1) || (buf[2 + 0x1f0] != 0x19 && buf[2 + 0x1f0] != 0x0e)) @@ -2583,6 +2689,7 @@ List *gd_caveset_import_from_buffer (const byte *buf, size_t length) cave->selectable = (n % 5) == 0; } } + } // try to give some names for the caves cavenum = 1; diff --git a/src/game_bd/bd_c64import.h b/src/game_bd/bd_c64import.h index 979b4254..65f91e16 100644 --- a/src/game_bd/bd_c64import.h +++ b/src/game_bd/bd_c64import.h @@ -41,6 +41,18 @@ typedef enum _gd_cavefile_format GD_FORMAT_FIRSTB, // first boulder } GdCavefileFormat; +// import hacks +typedef enum _gd_import_hack +{ + GD_HACK_NONE, // no hack + GD_HACK_CRDR_1, // crazy dream 1 + GD_HACK_CRDR_7, // crazy dream 7 + GD_HACK_CRDR_9, // crazy dream 9 + GD_HACK_DC1, // deluxe caves 1 + GD_HACK_DC3, // deluxe caves 3 + GD_HACK_MB, // masters boulder +} GdImportHack; + // engines typedef enum _gd_engine { -- 2.34.1 From 7b732bba2d1002ef0eee32ddbae7cf7df5693b73 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 2 Jul 2024 17:15:23 +0200 Subject: [PATCH 08/16] fixed buggy smooth movement speed in BD engine after wrapping around --- src/game_bd/bd_gameplay.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/game_bd/bd_gameplay.c b/src/game_bd/bd_gameplay.c index 0baca4fd..b157bdf0 100644 --- a/src/game_bd/bd_gameplay.c +++ b/src/game_bd/bd_gameplay.c @@ -415,12 +415,15 @@ static GdGameState gd_game_main_int(GdGame *game, boolean allow_iterate, boolean // normally nothing happes. but if we iterate, this might change. return_state = GD_GAME_NOTHING; - // if allowing cave movements, add elapsed time to timer. and then we can check what to do. + // if allowing cave movements, ... if (allow_iterate) + { + // ... add elapsed time to timer. and then we can check what to do game->milliseconds_game += millisecs_elapsed; - // increment cycle (frame) counter for the current cave iteration - game->itercycle++; + // ... increment cycle (frame) counter for the current cave iteration + game->itercycle++; + } if (game->milliseconds_game >= cavespeed) { -- 2.34.1 From 0f5d0658893fc245a4a8be939d57506ba3713fc3 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 3 Jul 2024 00:05:05 +0200 Subject: [PATCH 09/16] fixed BD elements at wrap-around cave position killing player instantly --- src/game_bd/bd_caveengine.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/game_bd/bd_caveengine.c b/src/game_bd/bd_caveengine.c index 0f9eecc7..85d92411 100644 --- a/src/game_bd/bd_caveengine.c +++ b/src/game_bd/bd_caveengine.c @@ -132,6 +132,18 @@ static inline boolean el_can_fall(const int element) return (gd_elements[element & O_MASK].properties & P_CAN_FALL) != 0; } +// returns true if the element is diggable +static inline boolean el_diggable(const int element) +{ + return (gd_elements[element & O_MASK].properties & P_DIGGABLE) != 0; +} + +// returns true if the element can smash the player +static inline boolean el_can_smash_player(const int element) +{ + return (el_can_fall(element) && !el_diggable(element)); +} + // play diamond or stone sound of given element. static void play_sound_of_element(GdCave *cave, GdElement element, int x, int y) { @@ -610,6 +622,19 @@ static inline void store_dir_no_scanned(GdCave *cave, const int x, const int y, static inline void move(GdCave *cave, const int x, const int y, const GdDirection dir, const GdElement e) { + // falling/flying game elements at wrap-around cave position should not kill player instantly + if ((x + gd_dx[dir] == cave->w && dir == GD_MV_RIGHT) || + (y + gd_dy[dir] == cave->h && dir == GD_MV_DOWN)) + { + // cave width/height out of bounds, but due to wrap-around it's the first column/row again + if (el_can_smash_player(get(cave, x, y))) + { + store(cave, x, y, e); // change to falling element ... + + return; // ... but do not move element + } + } + store_dir(cave, x, y, dir, e); store(cave, x, y, O_SPACE); } -- 2.34.1 From bb08733e9e29036d8fda5f0865c0a207da466579 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 3 Jul 2024 10:39:21 +0200 Subject: [PATCH 10/16] added support for zero delay for gravitation switch in BD engine --- src/editor.c | 2 +- src/game_bd/bd_caveengine.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/editor.c b/src/editor.c index 77f8d328..539bce3b 100644 --- a/src/editor.c +++ b/src/editor.c @@ -12199,7 +12199,7 @@ static struct 0, 10 }, { EL_BDX_CREATURE_SWITCH, &level.bd_creatures_auto_turn_delay, TEXT_AUTO_TURN_DELAY }, { EL_BDX_GRAVITY_SWITCH, &level.bd_gravity_switch_delay, TEXT_GRAVITY_DELAY, - 1, 60 }, + 0, 60 }, { EL_EXTRA_TIME, &level.extra_time, TEXT_TIME_BONUS }, { EL_TIME_ORB_FULL, &level.time_orb_time, TEXT_TIME_BONUS }, { EL_GAME_OF_LIFE, &level.game_of_life[0], TEXT_GAME_OF_LIFE_1,0,8 }, diff --git a/src/game_bd/bd_caveengine.c b/src/game_bd/bd_caveengine.c index 85d92411..a5a18787 100644 --- a/src/game_bd/bd_caveengine.c +++ b/src/game_bd/bd_caveengine.c @@ -1855,8 +1855,9 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, player_move == GD_MV_DOWN)) { gd_sound_play(cave, GD_S_SWITCH_GRAVITY, what, x, y); + // (use 1 instead of 0 for immediate gravitation change) cave->gravity_will_change = - cave->gravity_change_time * cave->timing_factor; + MAX(1, cave->gravity_change_time * cave->timing_factor); cave->gravity_next_direction = player_move; cave->gravity_switch_active = FALSE; } @@ -1961,8 +1962,9 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, player_move == GD_MV_DOWN)) { gd_sound_play(cave, GD_S_SWITCH_GRAVITY, what, x, y); + // (use 1 instead of 0 for immediate gravitation change) cave->gravity_will_change = - cave->gravity_change_time * cave->timing_factor; + MAX(1, cave->gravity_change_time * cave->timing_factor); cave->gravity_next_direction = player_move; cave->gravity_switch_active = FALSE; } -- 2.34.1 From b872e0d9bcbf0177567268cfe7fc3001666e195c Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 3 Jul 2024 10:43:24 +0200 Subject: [PATCH 11/16] minor code formatting change --- src/game_bd/bd_caveengine.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/game_bd/bd_caveengine.c b/src/game_bd/bd_caveengine.c index a5a18787..4c3b7b0a 100644 --- a/src/game_bd/bd_caveengine.c +++ b/src/game_bd/bd_caveengine.c @@ -3812,7 +3812,9 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, if (cave->gravity_will_change == 0) { cave->gravity = cave->gravity_next_direction; - gd_sound_play(cave, GD_S_GRAVITY_CHANGING, O_GRAVITY_SWITCH, -1, -1); // takes precedence over amoeba and magic wall sound + + // takes precedence over amoeba and magic wall sound + gd_sound_play(cave, GD_S_GRAVITY_CHANGING, O_GRAVITY_SWITCH, -1, -1); } } -- 2.34.1 From 9ef4467775de65167c72f24455f5147db61a3def Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Wed, 3 Jul 2024 10:55:40 +0200 Subject: [PATCH 12/16] changed descriptions for BD style pot and gravity switch --- docs/elements/bdx_gravity_switch.txt | 5 +++-- docs/elements/bdx_pot.txt | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/elements/bdx_gravity_switch.txt b/docs/elements/bdx_gravity_switch.txt index 6e7d3076..bad7ed5e 100644 --- a/docs/elements/bdx_gravity_switch.txt +++ b/docs/elements/bdx_gravity_switch.txt @@ -1,3 +1,4 @@ -When this switch is active, you can use it to change the gravitation. -The direction from which you use it will determine the direction the +When this switch is active, you can push it to change the gravitation. +The direction into which you push it will determine the direction the gravitation will change to. +To activate the gravitation switch, the pot has to be stirred first. diff --git a/docs/elements/bdx_pot.txt b/docs/elements/bdx_pot.txt index a0239714..d85e6f9a 100644 --- a/docs/elements/bdx_pot.txt +++ b/docs/elements/bdx_pot.txt @@ -1,2 +1,3 @@ Stir the pot, and you will be able to use the gravitation switch. While you are stirring the pot, there is no gravitation at all. Press fire after using the pot. +Before using the pot, a certain number of skeletons have to be collected. -- 2.34.1 From 9d99cb83125febdeaad77efacfaedbf306db1aad Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Thu, 4 Jul 2024 20:54:08 +0200 Subject: [PATCH 13/16] changed descriptions for BD style diamond keys and trapped keys --- docs/elements/bdx_diamond_key.txt | 2 +- docs/elements/bdx_trapped_diamond.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/elements/bdx_diamond_key.txt b/docs/elements/bdx_diamond_key.txt index 61180d66..d48974d4 100644 --- a/docs/elements/bdx_diamond_key.txt +++ b/docs/elements/bdx_diamond_key.txt @@ -1 +1 @@ -If you get this key, all doors will convert into diamonds you can collect. +If you collect this key, all trapped diamonds will convert into diamonds. diff --git a/docs/elements/bdx_trapped_diamond.txt b/docs/elements/bdx_trapped_diamond.txt index 484c2cfd..4344730a 100644 --- a/docs/elements/bdx_trapped_diamond.txt +++ b/docs/elements/bdx_trapped_diamond.txt @@ -1 +1,2 @@ -This is an indestructible door with a diamond. +This is an indestructible door with a trapped diamond. +To free all trapped diamonds, collect a diamond key. -- 2.34.1 From 3a2a6c2d2c6b4595903bbfda536d3c9209dda61c Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Thu, 4 Jul 2024 20:54:44 +0200 Subject: [PATCH 14/16] changed element group names for BD style walls with key --- src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 973d0c90..16bc18f2 100644 --- a/src/main.c +++ b/src/main.c @@ -6549,17 +6549,17 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = }, { "bdx_wall_key_1", - "bdx_wall", + "bdx_wall_key", "Wall with key 1" }, { "bdx_wall_key_2", - "bdx_wall", + "bdx_wall_key", "Wall with key 2" }, { "bdx_wall_key_3", - "bdx_wall", + "bdx_wall_key", "Wall with key 3" }, { -- 2.34.1 From 7847575a543100bd9ba7a03cf4a7a5c60185fe14 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Thu, 4 Jul 2024 21:43:23 +0200 Subject: [PATCH 15/16] renamed bladder (spender) to (trapped) bubble in BD engine --- docs/elements/bdx_bladder.txt | 2 - docs/elements/bdx_bladder_spender.txt | 1 - docs/elements/bdx_bubble.txt | 2 + docs/elements/bdx_trapped_bubble.txt | 2 + src/conf_gfx.c | 22 +++++----- src/editor.c | 34 +++++++-------- src/files.c | 8 ++-- src/init.c | 2 +- src/main.c | 60 +++++++++++++-------------- src/main.h | 22 +++++----- src/tools.c | 36 ++++++++-------- 11 files changed, 96 insertions(+), 95 deletions(-) delete mode 100644 docs/elements/bdx_bladder.txt delete mode 100644 docs/elements/bdx_bladder_spender.txt create mode 100644 docs/elements/bdx_bubble.txt create mode 100644 docs/elements/bdx_trapped_bubble.txt diff --git a/docs/elements/bdx_bladder.txt b/docs/elements/bdx_bladder.txt deleted file mode 100644 index d4fc8349..00000000 --- a/docs/elements/bdx_bladder.txt +++ /dev/null @@ -1,2 +0,0 @@ -Bladders can be pushed around easily. They slowly climb up; if they touch a -voodoo doll, they convert into clocks. They can also pass slime. diff --git a/docs/elements/bdx_bladder_spender.txt b/docs/elements/bdx_bladder_spender.txt deleted file mode 100644 index 389a72c7..00000000 --- a/docs/elements/bdx_bladder_spender.txt +++ /dev/null @@ -1 +0,0 @@ -If there is space above it, the bladder spender turns to a bladder. diff --git a/docs/elements/bdx_bubble.txt b/docs/elements/bdx_bubble.txt new file mode 100644 index 00000000..20bab528 --- /dev/null +++ b/docs/elements/bdx_bubble.txt @@ -0,0 +1,2 @@ +Bubbles can be pushed around easily. They slowly move up; if they touch a +voodoo doll, they convert into clocks. They can also pass slime. diff --git a/docs/elements/bdx_trapped_bubble.txt b/docs/elements/bdx_trapped_bubble.txt new file mode 100644 index 00000000..34d8ae89 --- /dev/null +++ b/docs/elements/bdx_trapped_bubble.txt @@ -0,0 +1,2 @@ +If there is space above it, the trapped bubble turns into a bubble that can move +up and that can be pushed by the player. diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 0ead706d..2bc30921 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -867,17 +867,17 @@ struct ConfigInfo image_config[] = { "bdx_nut.falling.EDITOR.xpos", "5" }, { "bdx_nut.falling.EDITOR.ypos", "2" }, - { "bdx_bladder", "RocksBD.png" }, - { "bdx_bladder.xpos", "8" }, - { "bdx_bladder.ypos", "12" }, - { "bdx_bladder.frames", "4" }, - { "bdx_bladder.delay", "4" }, - { "bdx_bladder.anim_mode", "pingpong2" }, - - { "bdx_bladder_spender", "RocksBD.png" }, - { "bdx_bladder_spender.xpos", "11" }, - { "bdx_bladder_spender.ypos", "10" }, - { "bdx_bladder_spender.frames", "1" }, + { "bdx_bubble", "RocksBD.png" }, + { "bdx_bubble.xpos", "8" }, + { "bdx_bubble.ypos", "12" }, + { "bdx_bubble.frames", "4" }, + { "bdx_bubble.delay", "4" }, + { "bdx_bubble.anim_mode", "pingpong2" }, + + { "bdx_trapped_bubble", "RocksBD.png" }, + { "bdx_trapped_bubble.xpos", "11" }, + { "bdx_trapped_bubble.ypos", "10" }, + { "bdx_trapped_bubble.frames", "1" }, { "bdx_creature_switch", "RocksBD.png" }, { "bdx_creature_switch.xpos", "9" }, diff --git a/src/editor.c b/src/editor.c index 539bce3b..d2d020fa 100644 --- a/src/editor.c +++ b/src/editor.c @@ -640,7 +640,7 @@ enum GADGET_ID_BD_ACID_EATS_ELEMENT, GADGET_ID_BD_ACID_TURNS_TO_ELEMENT, GADGET_ID_BD_BITER_EATS_ELEMENT, - GADGET_ID_BD_BLADDER_CONVERTS_BY_ELEMENT, + GADGET_ID_BD_BUBBLE_CONVERTS_BY_ELEMENT, GADGET_ID_BD_NUT_CONTENT, GADGET_ID_BD_EXPANDING_WALL_LOOKS_LIKE, GADGET_ID_BD_SAND_LOOKS_LIKE, @@ -1354,7 +1354,7 @@ enum ED_DRAWING_ID_BD_ACID_EATS_ELEMENT, ED_DRAWING_ID_BD_ACID_TURNS_TO_ELEMENT, ED_DRAWING_ID_BD_BITER_EATS_ELEMENT, - ED_DRAWING_ID_BD_BLADDER_CONVERTS_BY_ELEMENT, + ED_DRAWING_ID_BD_BUBBLE_CONVERTS_BY_ELEMENT, ED_DRAWING_ID_BD_NUT_CONTENT, ED_DRAWING_ID_BD_EXPANDING_WALL_LOOKS_LIKE, ED_DRAWING_ID_BD_SAND_LOOKS_LIKE, @@ -5009,11 +5009,11 @@ static struct "Can eat:", NULL, NULL, NULL, "Eats this element when moving" }, { - ED_DRAWING_ID_BD_BLADDER_CONVERTS_BY_ELEMENT, + ED_DRAWING_ID_BD_BUBBLE_CONVERTS_BY_ELEMENT, ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(1), ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_BD_BLADDER_CONVERTS_BY_ELEMENT, GADGET_ID_NONE, - &level.bd_bladder_converts_by_element, 1, 1, + GADGET_ID_BD_BUBBLE_CONVERTS_BY_ELEMENT, GADGET_ID_NONE, + &level.bd_bubble_converts_by_element, 1, 1, "Turns to clock by touching:", NULL, NULL, NULL, "Turns to clock by touching element" }, { @@ -5600,8 +5600,8 @@ static int editor_el_boulderdash_native[] = EL_BDX_EXPANDABLE_STEELWALL_ANY, EL_BDX_CREATURE_SWITCH, - EL_BDX_BLADDER, - EL_BDX_BLADDER_SPENDER, + EL_BDX_BUBBLE, + EL_BDX_TRAPPED_BUBBLE, EL_BDX_REPLICATOR, EL_BDX_REPLICATOR_SWITCH, @@ -5685,15 +5685,15 @@ static int editor_el_boulderdash_effects[] = EL_BDX_EXIT_OPEN, EL_BDX_INVISIBLE_EXIT_OPEN, - EL_BDX_BLADDER_1, - EL_BDX_BLADDER_2, - EL_BDX_BLADDER_3, - EL_BDX_BLADDER_4, + EL_BDX_BUBBLE_1, + EL_BDX_BUBBLE_2, + EL_BDX_BUBBLE_3, + EL_BDX_BUBBLE_4, - EL_BDX_BLADDER_5, - EL_BDX_BLADDER_6, - EL_BDX_BLADDER_7, - EL_BDX_BLADDER_8, + EL_BDX_BUBBLE_5, + EL_BDX_BUBBLE_6, + EL_BDX_BUBBLE_7, + EL_BDX_BUBBLE_8, EL_BDX_SAND_2, EL_BDX_COW_ENCLOSED_1, @@ -12465,9 +12465,9 @@ static void DrawPropertiesConfig(void) { MapDrawingArea(ED_DRAWING_ID_BD_BITER_EATS_ELEMENT); } - else if (properties_element == EL_BDX_BLADDER) + else if (properties_element == EL_BDX_BUBBLE) { - MapDrawingArea(ED_DRAWING_ID_BD_BLADDER_CONVERTS_BY_ELEMENT); + MapDrawingArea(ED_DRAWING_ID_BD_BUBBLE_CONVERTS_BY_ELEMENT); } else if (properties_element == EL_YAMYAM || properties_element == EL_YAMYAM_LEFT || diff --git a/src/files.c b/src/files.c index e078e055..589c34dc 100644 --- a/src/files.c +++ b/src/files.c @@ -935,9 +935,9 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] = }, { - EL_BDX_BLADDER, -1, + EL_BDX_BUBBLE, -1, TYPE_ELEMENT, CONF_VALUE_16_BIT(1), - &li.bd_bladder_converts_by_element, EL_BDX_VOODOO_DOLL + &li.bd_bubble_converts_by_element, EL_BDX_VOODOO_DOLL }, { @@ -4387,7 +4387,7 @@ static void CopyNativeLevel_RND_to_BD(struct LevelInfo *level) 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->bladder_converts_by = LEVEL_TO_CAVE(level->bd_bubble_converts_by_element); cave->expanding_wall_changed = level->bd_change_expanding_wall; @@ -4560,7 +4560,7 @@ static void CopyNativeLevel_BD_to_RND(struct LevelInfo *level) 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_bubble_converts_by_element = CAVE_TO_LEVEL(cave->bladder_converts_by); level->bd_change_expanding_wall = cave->expanding_wall_changed; diff --git a/src/init.c b/src/init.c index e451d99e..a6666d5d 100644 --- a/src/init.c +++ b/src/init.c @@ -4314,7 +4314,7 @@ void InitElementPropertiesStatic(void) EL_BDX_BITER_UP, EL_BDX_BITER_LEFT, EL_BDX_BITER_DOWN, - EL_BDX_BLADDER, + EL_BDX_BUBBLE, EL_BDX_NUT, EL_EMC_MAGIC_BALL, EL_EMC_ANDROID, diff --git a/src/main.c b/src/main.c index 16bc18f2..0375a9c5 100644 --- a/src/main.c +++ b/src/main.c @@ -6718,14 +6718,14 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = "Amoeba 2" }, { - "bdx_bladder", - "bdx_bladder", - "Bladder" + "bdx_bubble", + "bdx_bubble", + "Bubble" }, { - "bdx_bladder_spender", - "bdx_bladder_spender", - "Bladder spender" + "bdx_trapped_bubble", + "bdx_trapped_bubble", + "Trapped bubble" }, { "bdx_creature_switch", @@ -7403,44 +7403,44 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = "Enclosed cow (7)" }, { - "bdx_bladder_1", - "bdx_bladder", - "Bladder (1)" + "bdx_bubble_1", + "bdx_bubble", + "Bubble (1)" }, { - "bdx_bladder_2", - "bdx_bladder", - "Bladder (2)" + "bdx_bubble_2", + "bdx_bubble", + "Bubble (2)" }, { - "bdx_bladder_3", - "bdx_bladder", - "Bladder (3)" + "bdx_bubble_3", + "bdx_bubble", + "Bubble (3)" }, { - "bdx_bladder_4", - "bdx_bladder", - "Bladder (4)" + "bdx_bubble_4", + "bdx_bubble", + "Bubble (4)" }, { - "bdx_bladder_5", - "bdx_bladder", - "Bladder (5)" + "bdx_bubble_5", + "bdx_bubble", + "Bubble (5)" }, { - "bdx_bladder_6", - "bdx_bladder", - "Bladder (6)" + "bdx_bubble_6", + "bdx_bubble", + "Bubble (6)" }, { - "bdx_bladder_7", - "bdx_bladder", - "Bladder (7)" + "bdx_bubble_7", + "bdx_bubble", + "Bubble (7)" }, { - "bdx_bladder_8", - "bdx_bladder", - "Bladder (8)" + "bdx_bubble_8", + "bdx_bubble", + "Bubble (8)" }, { "bdx_player.growing_1", diff --git a/src/main.h b/src/main.h index cc40d17e..0deb4de8 100644 --- a/src/main.h +++ b/src/main.h @@ -2134,8 +2134,8 @@ #define EL_BDX_NUT 1301 #define EL_BDX_AMOEBA_1 1302 #define EL_BDX_AMOEBA_2 1303 -#define EL_BDX_BLADDER 1304 -#define EL_BDX_BLADDER_SPENDER 1305 +#define EL_BDX_BUBBLE 1304 +#define EL_BDX_TRAPPED_BUBBLE 1305 #define EL_BDX_CREATURE_SWITCH 1306 #define EL_BDX_CREATURE_SWITCH_ACTIVE 1307 #define EL_BDX_BITER_SWITCH_1 1308 @@ -2274,14 +2274,14 @@ #define EL_BDX_COW_ENCLOSED_5 1438 #define EL_BDX_COW_ENCLOSED_6 1439 #define EL_BDX_COW_ENCLOSED_7 1440 -#define EL_BDX_BLADDER_1 1441 -#define EL_BDX_BLADDER_2 1442 -#define EL_BDX_BLADDER_3 1443 -#define EL_BDX_BLADDER_4 1444 -#define EL_BDX_BLADDER_5 1445 -#define EL_BDX_BLADDER_6 1446 -#define EL_BDX_BLADDER_7 1447 -#define EL_BDX_BLADDER_8 1448 +#define EL_BDX_BUBBLE_1 1441 +#define EL_BDX_BUBBLE_2 1442 +#define EL_BDX_BUBBLE_3 1443 +#define EL_BDX_BUBBLE_4 1444 +#define EL_BDX_BUBBLE_5 1445 +#define EL_BDX_BUBBLE_6 1446 +#define EL_BDX_BUBBLE_7 1447 +#define EL_BDX_BUBBLE_8 1448 #define EL_BDX_PLAYER_GROWING_1 1449 #define EL_BDX_PLAYER_GROWING_2 1450 #define EL_BDX_PLAYER_GROWING_3 1451 @@ -3753,7 +3753,7 @@ struct LevelInfo int bd_acid_turns_to_element; // BD acid target element after spreading int bd_biter_move_delay; // BD biter delay between movements (in BD frames) int bd_biter_eats_element; // BD biter eats this game element when moving - int bd_bladder_converts_by_element; // BD bladder converts to clock by touching this element + int bd_bubble_converts_by_element; // BD bubble converts to clock by touching this element boolean bd_change_expanding_wall; // BD expanding wall direction is changed if enabled boolean bd_replicators_active; // BD replicators start in active state if enabled int bd_replicator_create_delay; // BD replicator delay between replications (in BD frames) diff --git a/src/tools.c b/src/tools.c index 17cd794a..09933f1d 100644 --- a/src/tools.c +++ b/src/tools.c @@ -6354,7 +6354,7 @@ bd_object_mapping_list[] = }, { O_BLADDER_SPENDER, TRUE, - EL_BDX_BLADDER_SPENDER, -1, -1 + EL_BDX_TRAPPED_BUBBLE, -1, -1 }, { O_INBOX, TRUE, @@ -6762,71 +6762,71 @@ bd_object_mapping_list[] = }, { O_BLADDER, TRUE, - EL_BDX_BLADDER, -1, -1 + EL_BDX_BUBBLE, -1, -1 }, { O_BLADDER_1, TRUE, - EL_BDX_BLADDER_1, -1, -1 + EL_BDX_BUBBLE_1, -1, -1 }, { O_BLADDER_1, FALSE, - EL_BDX_BLADDER, -1, -1 + EL_BDX_BUBBLE, -1, -1 }, { O_BLADDER_2, TRUE, - EL_BDX_BLADDER_2, -1, -1 + EL_BDX_BUBBLE_2, -1, -1 }, { O_BLADDER_2, FALSE, - EL_BDX_BLADDER, -1, -1 + EL_BDX_BUBBLE, -1, -1 }, { O_BLADDER_3, TRUE, - EL_BDX_BLADDER_3, -1, -1 + EL_BDX_BUBBLE_3, -1, -1 }, { O_BLADDER_3, FALSE, - EL_BDX_BLADDER, -1, -1 + EL_BDX_BUBBLE, -1, -1 }, { O_BLADDER_4, TRUE, - EL_BDX_BLADDER_4, -1, -1 + EL_BDX_BUBBLE_4, -1, -1 }, { O_BLADDER_4, FALSE, - EL_BDX_BLADDER, -1, -1 + EL_BDX_BUBBLE, -1, -1 }, { O_BLADDER_5, TRUE, - EL_BDX_BLADDER_5, -1, -1 + EL_BDX_BUBBLE_5, -1, -1 }, { O_BLADDER_5, FALSE, - EL_BDX_BLADDER, -1, -1 + EL_BDX_BUBBLE, -1, -1 }, { O_BLADDER_6, TRUE, - EL_BDX_BLADDER_6, -1, -1 + EL_BDX_BUBBLE_6, -1, -1 }, { O_BLADDER_6, FALSE, - EL_BDX_BLADDER, -1, -1 + EL_BDX_BUBBLE, -1, -1 }, { O_BLADDER_7, TRUE, - EL_BDX_BLADDER_7, -1, -1 + EL_BDX_BUBBLE_7, -1, -1 }, { O_BLADDER_7, FALSE, - EL_BDX_BLADDER, -1, -1 + EL_BDX_BUBBLE, -1, -1 }, { O_BLADDER_8, TRUE, - EL_BDX_BLADDER_8, -1, -1 + EL_BDX_BUBBLE_8, -1, -1 }, { O_BLADDER_8, FALSE, - EL_BDX_BLADDER, -1, -1 + EL_BDX_BUBBLE, -1, -1 }, { O_WAITING_STONE, TRUE, -- 2.34.1 From f66d61910243380e6fc0d44a66fb1d7bbdf42156 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Fri, 5 Jul 2024 08:47:44 +0200 Subject: [PATCH 16/16] added pushable/movable properties for BD bubble (bladder) --- src/game_bd/bd_cavedb.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/game_bd/bd_cavedb.c b/src/game_bd/bd_cavedb.c index f788d9bd..9c3b02a3 100644 --- a/src/game_bd/bd_cavedb.c +++ b/src/game_bd/bd_cavedb.c @@ -240,15 +240,15 @@ GdElements gd_elements[] = { O_SWEET, N_("Sweet"), P_COLLECTIBLE, "SWEET", 0, 8, 8, 8 }, { O_VOODOO, N_("Voodoo doll"), P_BLOWS_UP_FLIES, "DUMMY", 'F', 7, 7, 7 }, { O_SLIME, N_("Slime"), 0, "SLIME", 's', 200, -200, -200, 211 }, // has ckdelay - { O_BLADDER, N_("Bladder"), 0, "BLADDER", 0, 176, -176, -176, 267 }, // has ckdelay - { O_BLADDER_1, N_("Bladder (1)"), 0, "BLADDERd1", 0, 176, -176, -176 }, - { O_BLADDER_2, N_("Bladder (2)"), 0, "BLADDERd2", 0, 176, -176, -176 }, - { O_BLADDER_3, N_("Bladder (3)"), 0, "BLADDERd3", 0, 176, -176, -176 }, - { O_BLADDER_4, N_("Bladder (4)"), 0, "BLADDERd4", 0, 176, -176, -176 }, - { O_BLADDER_5, N_("Bladder (5)"), 0, "BLADDERd5", 0, 176, -176, -176 }, - { O_BLADDER_6, N_("Bladder (6)"), 0, "BLADDERd6", 0, 176, -176, -176 }, - { O_BLADDER_7, N_("Bladder (7)"), 0, "BLADDERd7", 0, 176, -176, -176 }, - { O_BLADDER_8, N_("Bladder (8)"), 0, "BLADDERd8", 0, 176, -176, -176 }, + { O_BLADDER, N_("Bladder"), P_PUSHABLE | P_CAN_MOVE, "BLADDER", 0, 176, -176, -176, 267 }, // has ckdelay + { O_BLADDER_1, N_("Bladder (1)"), P_PUSHABLE | P_CAN_MOVE, "BLADDERd1", 0, 176, -176, -176 }, + { O_BLADDER_2, N_("Bladder (2)"), P_PUSHABLE | P_CAN_MOVE, "BLADDERd2", 0, 176, -176, -176 }, + { O_BLADDER_3, N_("Bladder (3)"), P_PUSHABLE | P_CAN_MOVE, "BLADDERd3", 0, 176, -176, -176 }, + { O_BLADDER_4, N_("Bladder (4)"), P_PUSHABLE | P_CAN_MOVE, "BLADDERd4", 0, 176, -176, -176 }, + { O_BLADDER_5, N_("Bladder (5)"), P_PUSHABLE | P_CAN_MOVE, "BLADDERd5", 0, 176, -176, -176 }, + { O_BLADDER_6, N_("Bladder (6)"), P_PUSHABLE | P_CAN_MOVE, "BLADDERd6", 0, 176, -176, -176 }, + { O_BLADDER_7, N_("Bladder (7)"), P_PUSHABLE | P_CAN_MOVE, "BLADDERd7", 0, 176, -176, -176 }, + { O_BLADDER_8, N_("Bladder (8)"), P_PUSHABLE | P_CAN_MOVE, "BLADDERd8", 0, 176, -176, -176 }, { O_WAITING_STONE, N_("Waiting stone"), P_SLOPED | P_PUSHABLE, "WAITINGBOULDER", 0, i_waiting_stone, i_waiting_stone, 1, 176 }, // has ckdelay { O_CHASING_STONE, N_("Chasing stone"), P_SLOPED | P_CAN_MOVE | P_PUSHABLE, "CHASINGBOULDER", 0, 17, 17, 17, 269 }, // has ckdelay -- 2.34.1