X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_bd%2Fbd_caveengine.c;h=5b2bfcdfcd1292268083f70c45a5fa64fd235469;hb=8fdd23c078934ae797980a824fd145903c84cae7;hp=e95236ce6b73c8a5994635adf1d08ee76fc82ebf;hpb=ee1d57d74c4e4037fafb677953f8363489a263d0;p=rocksndiamonds.git diff --git a/src/game_bd/bd_caveengine.c b/src/game_bd/bd_caveengine.c index e95236ce..5b2bfcdf 100644 --- a/src/game_bd/bd_caveengine.c +++ b/src/game_bd/bd_caveengine.c @@ -126,9 +126,19 @@ void gd_cave_set_seconds_sound(GdCave *cave) } } +// returns true if the element can fall +static inline boolean el_can_fall(const int element) +{ + return (gd_elements[element & O_MASK].properties & P_CAN_FALL) != 0; +} + // play diamond or stone sound of given element. static void play_sound_of_element(GdCave *cave, GdElement element, int x, int y) { + // check if sound should be skipped for falling elements (and only be played on impact) + if (el_can_fall(element) && !use_bd_falling_sounds()) + return; + // stone and diamond fall sounds. switch (element) { @@ -449,7 +459,7 @@ static inline boolean rotates_ccw (const GdCave *cave, const int x, const int y) } // returns true if the element is a player -static inline boolean is_player(const GdCave *cave, const int x, const int y) +boolean is_player(const GdCave *cave, const int x, const int y) { return (gd_elements[get(cave, x, y) & O_MASK].properties & P_PLAYER) != 0; } @@ -467,6 +477,13 @@ static inline boolean can_be_hammered_dir(const GdCave *cave, const int x, const return (gd_elements[get_dir(cave, x, y, dir) & O_MASK].properties & P_CAN_BE_HAMMERED) != 0; } +// returns true if the element can be pushed +boolean can_be_pushed_dir(const GdCave *cave, const int x, const int y, + const GdDirection dir) +{ + return (gd_elements[get_dir(cave, x, y, dir) & O_MASK].properties & P_PUSHABLE) != 0; +} + // returns true if the element is explodable and explodes to space, for example the player static inline boolean is_first_stage_of_explosion(const GdCave *cave, const int x, const int y) { @@ -1371,6 +1388,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 @@ -1550,6 +1570,9 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, gd_cave_clear_sounds(cave); + game_bd.player_moving = FALSE; + game_bd.player_snapping = FALSE; + // if diagonal movements not allowed, // horizontal movements have precedence. [BROADRIBB] if (!cave->diagonal_movements) @@ -1604,6 +1627,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 @@ -1812,15 +1838,25 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, // if snapping anything and we have snapping explosions set. // but these is not true for pushing. if (remains == O_SPACE && player_fire && !push) + { remains = cave->snap_element; + game_bd.player_snapping = TRUE; + } + if (remains != O_SPACE || player_fire) + { // if any other element than space, player cannot move. // also if pressing fire, will not move. store_dir(cave, x, y, player_move, remains); + } else + { // if space remains there, the player moves. move(cave, x, y, player_move, O_PLAYER); + + game_bd.player_moving = TRUE; + } } } break; @@ -2847,6 +2883,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) { @@ -3603,7 +3646,7 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, { if ((amoeba_count > 0 && cave->amoeba_state == GD_AM_AWAKE) || (amoeba_2_count > 0 && cave->amoeba_2_state == GD_AM_AWAKE)) - play_sound_of_element(cave, O_AMOEBA, x, y); + play_sound_of_element(cave, O_AMOEBA, -1, -1); } // pneumatic hammer sound - overrides everything. @@ -3713,7 +3756,8 @@ void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, // magic wall; if active&wait or not wait for hatching if (cave->magic_wall_state == GD_MW_ACTIVE && - (cave->hatched || !cave->magic_timer_wait_for_hatching)) + (cave->hatched || !cave->magic_timer_wait_for_hatching) && + !(cave->magic_wall_time == 0 && cave->magic_timer_zero_is_infinite)) { cave->magic_wall_time -= cave->speed; if (cave->magic_wall_time < 0)