improved smooth movement animation for BD engine (complete rewrite)
[rocksndiamonds.git] / src / game_bd / bd_caveengine.c
index 6d0e3fcd2c13614bfa7ad887f9d2c05f1fad1cda..9df249eba1fba020e9ef53063c92c0aed0b8dbe7 100644 (file)
@@ -543,6 +543,9 @@ static inline boolean is_space_dir(const GdCave *cave, const int x, const int y,
 
 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;
+
   // raw values without range correction
   int raw_x = x + gd_dx[dir];
   int raw_y = y + gd_dy[dir];
@@ -552,7 +555,18 @@ static inline void store_dir_buffer(GdCave *cave, const int x, const int y, cons
   int new_y = gety(cave, raw_x, raw_y);
   int new_dir = (dir > GD_MV_TWICE ? dir - GD_MV_TWICE : dir);
 
-  game_bd.game->dir_buffer[new_y][new_x] = new_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;
 }
 
 // store an element at the given position
@@ -1570,6 +1584,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)
@@ -1835,15 +1852,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;