added using masked drawing for player on walkable tiles in BD engine
authorHolger Schemel <holger.schemel@virtion.de>
Sat, 25 May 2024 23:49:22 +0000 (01:49 +0200)
committerHolger Schemel <holger.schemel@virtion.de>
Sat, 25 May 2024 23:54:10 +0000 (01:54 +0200)
src/game_bd/bd_cave.h
src/game_bd/bd_cavedb.c
src/game_bd/bd_graphics.c

index 1a85776a68a4e17333308881e7c8807d1fe144c3..3dede416f53f3dc8e5702baa67447e9057595568 100644 (file)
@@ -121,6 +121,7 @@ enum _element_property
   E_P_MOVED_BY_CONVEYOR_TOP,    // can be moved by conveyor belt
   E_P_MOVED_BY_CONVEYOR_BOTTOM, // can be moved UNDER the conveyor belt
 
+  E_P_WALKABLE,                 // can be walked
   E_P_DIGGABLE,                 // can be digged
   E_P_COLLECTIBLE,              // can be collected
   E_P_PUSHABLE,                 // can be pushed
@@ -160,6 +161,7 @@ enum _element_property
 #define P_MOVED_BY_CONVEYOR_TOP                (1 << E_P_MOVED_BY_CONVEYOR_TOP)
 #define P_MOVED_BY_CONVEYOR_BOTTOM     (1 << E_P_MOVED_BY_CONVEYOR_BOTTOM)
 
+#define P_WALKABLE                     (1 << E_P_WALKABLE)
 #define P_DIGGABLE                     (1 << E_P_DIGGABLE)
 #define P_COLLECTIBLE                  (1 << E_P_COLLECTIBLE)
 #define P_PUSHABLE                     (1 << E_P_PUSHABLE)
index 45da297ee1ca8376262cc6a971db70cf5ab1c09b..e3290c78fb6bfc9aacc96968970941c209d3d02b 100644 (file)
@@ -118,7 +118,7 @@ enum _generated_cells_indexes
 */
 GdElements gd_elements[] =
 {
-  { O_SPACE, N_("Space"), P_AMOEBA_CONSUMES, "SPACE", ' ', 0, 0, 0 },
+  { O_SPACE, N_("Space"), P_AMOEBA_CONSUMES | P_WALKABLE, "SPACE", ' ', 0, 0, 0 },
   { O_DIRT, N_("Dirt"), P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE, "DIRT", '.', 2, 2, 2 },
   { O_DIRT_SLOPED_UP_RIGHT, N_("Sloped dirt (up & right)"), P_DIRT | P_SLOPED_UP | P_SLOPED_RIGHT | P_AMOEBA_CONSUMES | P_DIGGABLE, "DIRTSLOPEDUPRIGHT", 0, 280, 280, 280 },
   { O_DIRT_SLOPED_UP_LEFT, N_("Sloped dirt (up & left)"), P_DIRT | P_SLOPED_UP | P_SLOPED_LEFT | P_AMOEBA_CONSUMES | P_DIGGABLE, "DIRTSLOPEDUPLEFT", 0, 281, 281, 281 },
@@ -196,7 +196,7 @@ GdElements gd_elements[] =
   { O_POT, N_("Pot"), 0, "POT", 0, 63, 63, 63 },
   { O_GRAVITY_SWITCH, N_("Gravity switch"), 0, "GRAVITY_SWITCH", 0, 274, 274, 274 },
   { O_PNEUMATIC_HAMMER, N_("Pneumatic hammer"), P_COLLECTIBLE, "PNEUMATIC_HAMMER", 0, 62, 62, 62 },
-  { O_TELEPORTER, N_("Teleporter"), 0, "TELEPORTER", 0, 61, 61, 61 },
+  { O_TELEPORTER, N_("Teleporter"), P_WALKABLE, "TELEPORTER", 0, 61, 61, 61 },
   { O_SKELETON, N_("Skeleton"), 0, "SKELETON", 0, 273, 273, 273 },
   { O_WATER, N_("Water"), 0, "WATER", 0, 96, -96, -96, 100 },    // has ckdelay
   { O_WATER_1, N_("Water (1)"), 0, "WATER1", 0, 96, -96, -96 },
index 4687ebfbe7e7d9f5aaedf26c25a25f080e67c80c..5da166f2f5bed8aaf28db0990fa03b181acf4782 100644 (file)
@@ -543,6 +543,12 @@ static inline boolean el_player(const int element)
   return (gd_elements[element & O_MASK].properties & P_PLAYER) != 0;
 }
 
+// returns true if the element is walkable
+static inline boolean el_walkable(const int element)
+{
+  return (gd_elements[element & O_MASK].properties & P_WALKABLE) != 0;
+}
+
 // returns true if the element is diggable
 static inline boolean el_diggable(const int element)
 {
@@ -690,6 +696,7 @@ static void gd_drawcave_tile(Bitmap *dest, GdGame *game, int x, int y, boolean d
   int old_x = cave->getx(cave, x + dx, y + dy);
   int old_y = cave->gety(cave, x + dx, y + dy);
   int tile_from = game->element_buffer[old_y][old_x] & ~SKIPPED;   // should never be skipped
+  int tile_last = game->last_element_buffer[y][x] & ~SKIPPED;
   struct GraphicInfo_BD *g_from = &graphic_info_bd_object[tile_from][frame];
   Bitmap *tile_bitmap_from = gd_get_tile_bitmap(g_from->bitmap);
   boolean old_is_player = el_player(tile_from);
@@ -726,6 +733,11 @@ static void gd_drawcave_tile(Bitmap *dest, GdGame *game, int x, int y, boolean d
   int itercycle = MIN(MAX(0, game->itermax - game->itercycle - 1), game->itermax);
   int shift = cell_size * itercycle / game->itermax;
 
+  // when drawing player over walkable elements, always use masked drawing
+  // (does not use masking if moving from walkable to diggable tiles etc.)
+  if (el_player(tile) && el_walkable(tile_from) && el_walkable(tile_last))
+    blit_bitmap = BlitBitmapMasked;
+
   blit_bitmap(tile_bitmap, dest, g->src_x, g->src_y, cell_size, cell_size,
              sx + dx * shift, sy + dy * shift);