From 30a44d38db21ee165a8b135183d1e1ed21afa29d Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 24 Sep 2024 02:06:26 +0200 Subject: [PATCH] changed BD engine to use two-step directions with smooth movement --- src/game_bd/bd_caveengine.c | 35 +++++++++-------------------------- src/game_bd/bd_graphics.c | 8 ++++++++ 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/game_bd/bd_caveengine.c b/src/game_bd/bd_caveengine.c index 69c98678..080046e6 100644 --- a/src/game_bd/bd_caveengine.c +++ b/src/game_bd/bd_caveengine.c @@ -645,30 +645,11 @@ static inline boolean is_like_dirt(const GdCave *cave, const int x, const int y, // store from/to directions in special buffers for smooth movement animations static inline void store_dir_buffer(GdCave *cave, const int x, const int y, const GdDirection dir) { - int old_x = x; - int old_y = y; + int new_x = getx(cave, x + gd_dx[dir], y + gd_dy[dir]); + int new_y = gety(cave, x + gd_dx[dir], y + gd_dy[dir]); - // raw values without range correction - int raw_x = x + gd_dx[dir]; - int raw_y = y + gd_dy[dir]; - - // final values with range correction - int new_x = getx(cave, raw_x, raw_y); - int new_y = gety(cave, raw_x, raw_y); - int new_dir = (dir > GD_MV_TWICE ? dir - GD_MV_TWICE : dir); - - // if tile is moving two steps at once, correct old position - if (dir > GD_MV_TWICE) - { - raw_x = x + gd_dx[new_dir]; - raw_y = y + gd_dy[new_dir]; - - old_x = getx(cave, raw_x, raw_y); - old_y = gety(cave, raw_x, raw_y); - } - - game_bd.game->dir_buffer_from[old_y][old_x] = new_dir; - game_bd.game->dir_buffer_to[new_y][new_x] = new_dir; + game_bd.game->dir_buffer_from[y][x] = dir; + game_bd.game->dir_buffer_to[new_y][new_x] = dir; } // Store an element at a given position; lava absorbs everything. @@ -1241,6 +1222,8 @@ static boolean do_teleporter(GdCave *cave, int px, int py, GdDirection player_mo static boolean do_push(GdCave *cave, int x, int y, GdDirection player_move, boolean player_fire) { GdElement what = get_dir(cave, x, y, player_move); + int what_x = getx(cave, x + gd_dx[player_move], y + gd_dy[player_move]); + int what_y = gety(cave, x + gd_dx[player_move], y + gd_dy[player_move]); // gravity for falling wall, bladder, ... GdDirection grav_compat = (cave->gravity_affects_all ? cave->gravity : GD_MV_DOWN); @@ -1310,9 +1293,9 @@ static boolean do_push(GdCave *cave, int x, int y, GdDirection player_move, bool // if pushed a stone, it "bounces". all other elements are simply pushed. if (what == O_STONE) - store_dir(cave, x, y, twice[player_move], cave->stone_bouncing_effect); + store_dir(cave, what_x, what_y, player_move, cave->stone_bouncing_effect); else - store_dir(cave, x, y, twice[player_move], what); + store_dir(cave, what_x, what_y, player_move, what); result = TRUE; } @@ -1437,7 +1420,7 @@ static boolean do_push(GdCave *cave, int x, int y, GdDirection player_move, bool if (is_like_space(cave, x, y, twice[player_move])) { // yes, so push. - store_dir(cave, x, y, twice[player_move], O_BOX); + store_dir(cave, what_x, what_y, player_move, O_BOX); result = TRUE; gd_sound_play(cave, GD_S_BOX_PUSHING, what, x, y); } diff --git a/src/game_bd/bd_graphics.c b/src/game_bd/bd_graphics.c index 52f270db..5f1c01d8 100644 --- a/src/game_bd/bd_graphics.c +++ b/src/game_bd/bd_graphics.c @@ -679,6 +679,7 @@ static void gd_drawcave_tile(Bitmap *dest, GdGame *game, int x, int y, boolean d boolean is_moving = (is_moving_from || is_moving_to); boolean is_diagonal_movement_from = (dx_from != 0 && dy_from != 0); boolean is_diagonal_movement_to = (dx_to != 0 && dy_to != 0); + boolean is_double_movement = (dir_from > GD_MV_TWICE); boolean use_smooth_movements = use_bd_smooth_movements(); // if element is moving away from this tile, determine element that is moving @@ -691,6 +692,13 @@ static void gd_drawcave_tile(Bitmap *dest, GdGame *game, int x, int y, boolean d tile_from = game->element_buffer[new_y][new_x]; draw_from = game->drawing_buffer[new_y][new_x]; + if (is_double_movement) + { + // for magic wall or slime, use source tile instead of target tile + tile_from = tile_last; + draw_from = draw_last; + } + // handle special case of player running into enemy/explosion from top or left side if (el_player(tile_last) && !el_player(tile) && el_destroying(tile_from)) tile_from = tile_last; -- 2.34.1