added support for digging (crumbled) sand for BD graphics engine
authorHolger Schemel <holger.schemel@virtion.de>
Wed, 11 Dec 2024 20:10:00 +0000 (21:10 +0100)
committerHolger Schemel <holger.schemel@virtion.de>
Wed, 11 Dec 2024 12:10:50 +0000 (13:10 +0100)
src/game_bd/bd_cavedb.c
src/game_bd/bd_elements.h
src/game_bd/bd_graphics.c
src/tools.c

index f59408895e4f7fa8843a80ce5ad3e9ec33aa3265..6be9724ffe45a56d8d8aae202a3396ec2dd37eed 100644 (file)
@@ -134,6 +134,46 @@ GdElementProperty gd_element_properties[] =
     P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE,
     "DIRT_CRUMBLED", 0, 2, 2, 2
   },
+  {
+    O_DIRT_DIGGING_LEFT, O_DIRT_DIGGING_LEFT, N_("Dirt (digging left)"),
+    P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE,
+    "DIRT_DIGGING_LEFT", 0, 2, 2, 2
+  },
+  {
+    O_DIRT_DIGGING_RIGHT, O_DIRT_DIGGING_RIGHT, N_("Dirt (digging right)"),
+    P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE,
+    "DIRT_DIGGING_RIGHT", 0, 2, 2, 2
+  },
+  {
+    O_DIRT_DIGGING_UP, O_DIRT_DIGGING_UP, N_("Dirt (digging up)"),
+    P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE,
+    "DIRT_DIGGING_UP", 0, 2, 2, 2
+  },
+  {
+    O_DIRT_DIGGING_DOWN, O_DIRT_DIGGING_DOWN, N_("Dirt (digging down)"),
+    P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE,
+    "DIRT_DIGGING_", 0, 2, 2, 2
+  },
+  {
+    O_DIRT_DIGGING_LEFT_CRUMBLED, O_DIRT_DIGGING_LEFT_CRUMBLED, N_("Dirt (digging left, crumbled)"),
+    P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE,
+    "DIRT_DIGGING_LEFT_CRUMBLED", 0, 2, 2, 2
+  },
+  {
+    O_DIRT_DIGGING_RIGHT_CRUMBLED, O_DIRT_DIGGING_RIGHT_CRUMBLED, N_("Dirt (digging right, crumbled)"),
+    P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE,
+    "DIRT_DIGGING_RIGHT_CRUMBLED", 0, 2, 2, 2
+  },
+  {
+    O_DIRT_DIGGING_UP_CRUMBLED, O_DIRT_DIGGING_UP_CRUMBLED, N_("Dirt (digging up, crumbled)"),
+    P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE,
+    "DIRT_DIGGING_UP_CRUMBLED", 0, 2, 2, 2
+  },
+  {
+    O_DIRT_DIGGING_DOWN_CRUMBLED, O_DIRT_DIGGING_DOWN_CRUMBLED, N_("Dirt (digging down, crumbled)"),
+    P_AMOEBA_CONSUMES | P_VISUAL_EFFECT | P_DIRT | P_DIGGABLE,
+    "DIRT_DIGGING_DOWN_CRUMBLED", 0, 2, 2, 2
+  },
   {
     O_DIRT_SLOPED_UP_RIGHT, O_DIRT_SLOPED_UP_RIGHT, N_("Sloped dirt (up & right)"),
     P_DIRT | P_SLOPED_UP | P_SLOPED_RIGHT | P_AMOEBA_CONSUMES | P_DIGGABLE,
index e5bb0dfd8420987666491cf7155bd6aa95cbcaf6..3d55082d4c14e024dfee7bbcc1851f7dcc441cb6 100644 (file)
@@ -27,6 +27,14 @@ typedef enum _element
   O_SPACE,
   O_DIRT,
   O_DIRT_CRUMBLED,
+  O_DIRT_DIGGING_LEFT,
+  O_DIRT_DIGGING_RIGHT,
+  O_DIRT_DIGGING_UP,
+  O_DIRT_DIGGING_DOWN,
+  O_DIRT_DIGGING_LEFT_CRUMBLED,
+  O_DIRT_DIGGING_RIGHT_CRUMBLED,
+  O_DIRT_DIGGING_UP_CRUMBLED,
+  O_DIRT_DIGGING_DOWN_CRUMBLED,
   O_DIRT_SLOPED_UP_RIGHT,
   O_DIRT_SLOPED_UP_LEFT,
   O_DIRT_SLOPED_DOWN_LEFT,
index d7f41e2b5e7220c02fb0d5e38bf4d98528f70876..906dd04e34d321a3a550f93cdd8c6e6649d31ed7 100644 (file)
@@ -551,8 +551,20 @@ static void gd_drawcave_crumbled(Bitmap *dest, GdGame *game, int x, int y, boole
   int sy = y * cell_size - scroll_y;
   int frame = game->animcycle;
   int border_size = cell_size / 8;
-  struct GraphicInfo_BD *gfx = &graphic_info_bd_object[O_DIRT][frame];
-  struct GraphicInfo_BD *crm = &graphic_info_bd_object[O_DIRT_CRUMBLED][frame];
+  int dir_to = game->dir_buffer_to[y][x];
+  boolean is_moving_to = (dir_to != GD_MV_STILL);
+  int tile_gfx = (!is_moving_to ? O_DIRT :
+                  dir_to == GD_MV_LEFT  ? O_DIRT_DIGGING_LEFT  :
+                  dir_to == GD_MV_RIGHT ? O_DIRT_DIGGING_RIGHT :
+                  dir_to == GD_MV_UP    ? O_DIRT_DIGGING_UP    :
+                  dir_to == GD_MV_DOWN  ? O_DIRT_DIGGING_DOWN  : O_DIRT);
+  int tile_crm = (!is_moving_to ? O_DIRT_CRUMBLED :
+                  dir_to == GD_MV_LEFT  ? O_DIRT_DIGGING_LEFT_CRUMBLED  :
+                  dir_to == GD_MV_RIGHT ? O_DIRT_DIGGING_RIGHT_CRUMBLED :
+                  dir_to == GD_MV_UP    ? O_DIRT_DIGGING_UP_CRUMBLED    :
+                  dir_to == GD_MV_DOWN  ? O_DIRT_DIGGING_DOWN_CRUMBLED  : O_DIRT_CRUMBLED);
+  struct GraphicInfo_BD *gfx = &graphic_info_bd_object[tile_gfx][frame];
+  struct GraphicInfo_BD *crm = &graphic_info_bd_object[tile_crm][frame];
   int dirs[] = { GD_MV_UP, GD_MV_LEFT, GD_MV_RIGHT, GD_MV_DOWN };
   int i;
 
@@ -575,12 +587,13 @@ static void gd_drawcave_crumbled(Bitmap *dest, GdGame *game, int x, int y, boole
     int yoffset = (dy > 0 ? cell_size - border_size : 0);
     int xsize = (dx == 0 ? cell_size : border_size);
     int ysize = (dy == 0 ? cell_size : border_size);
-    int dir_to = game->dir_buffer_to[yy][xx];
-    boolean is_moving_to = (dir_to != GD_MV_STILL);
 
-    // do not crumble sand that is just being digged away
+    dir_to = game->dir_buffer_to[yy][xx];
+    is_moving_to = (dir_to != GD_MV_STILL);
+
+    // do not crumble border if next to sand that is just being digged away
     if (tile_last == O_DIRT && is_moving_to)
-      continue;
+      tile = O_DIRT;
 
     if (tile == O_DIRT)
       blit_bitmap(gfx->bitmap, dest, gfx->src_x + xoffset, gfx->src_y + yoffset,
@@ -620,6 +633,9 @@ static void gd_drawcave_tile(Bitmap *dest, GdGame *game, int x, int y, boolean d
   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();
+  struct GraphicInfo_BD *gfx = &graphic_info_bd_object[O_DIRT][0];
+  struct GraphicInfo_BD *crm = &graphic_info_bd_object[O_DIRT_CRUMBLED][0];
+  boolean draw_crumbled = (gfx->graphic != crm->graphic);
 
   // if element is moving away from this tile, determine element that is moving
   if (is_moving_from)
@@ -724,7 +740,7 @@ static void gd_drawcave_tile(Bitmap *dest, GdGame *game, int x, int y, boolean d
   {
     struct GraphicInfo_BD *g = &graphic_info_bd_object[draw][frame];
 
-    if (draw == O_DIRT)
+    if (draw_crumbled && draw == O_DIRT)
       gd_drawcave_crumbled(dest, game, x, y, draw_masked);
     else
       blit_bitmap(g->bitmap, dest, g->src_x, g->src_y, cell_size, cell_size, sx, sy);
@@ -743,7 +759,16 @@ static void gd_drawcave_tile(Bitmap *dest, GdGame *game, int x, int y, boolean d
     int draw_back = (!is_moving_to ? draw : digging_tile ? draw_last : O_SPACE);
     struct GraphicInfo_BD *g = &graphic_info_bd_object[draw_back][frame];
 
-    blit_bitmap(g->bitmap, dest, g->src_x, g->src_y, cell_size, cell_size, sx, sy);
+    if (draw_crumbled && draw_last == O_DIRT)
+    {
+      gd_drawcave_crumbled(dest, game, x, y, draw_masked);
+
+      blit_bitmap = BlitBitmapMasked;
+    }
+    else
+    {
+      blit_bitmap(g->bitmap, dest, g->src_x, g->src_y, cell_size, cell_size, sx, sy);
+    }
   }
 
   // get shifted position between cave fields the game element is moving from/to
index becf115229158ee0e7e3e696d52df77548319f8e..0382598e58eee61fa6995c2cf198407e26750cd4 100644 (file)
@@ -6132,6 +6132,42 @@ bd_object_mapping_list[] =
     O_DIRT,                                    TRUE,
     EL_BDX_SAND,                               -1, -1
   },
+  {
+    O_DIRT_CRUMBLED,                           FALSE,
+    EL_BDX_SAND,                               -1, -1
+  },
+  {
+    O_DIRT_DIGGING_LEFT,                       FALSE,
+    EL_BDX_SAND,                               ACTION_DIGGING, MV_BIT_LEFT
+  },
+  {
+    O_DIRT_DIGGING_RIGHT,                      FALSE,
+    EL_BDX_SAND,                               ACTION_DIGGING, MV_BIT_RIGHT
+  },
+  {
+    O_DIRT_DIGGING_UP,                         FALSE,
+    EL_BDX_SAND,                               ACTION_DIGGING, MV_BIT_UP
+  },
+  {
+    O_DIRT_DIGGING_DOWN,                       FALSE,
+    EL_BDX_SAND,                               ACTION_DIGGING, MV_BIT_DOWN
+  },
+  {
+    O_DIRT_DIGGING_LEFT_CRUMBLED,              FALSE,
+    EL_BDX_SAND,                               ACTION_DIGGING, MV_BIT_LEFT
+  },
+  {
+    O_DIRT_DIGGING_RIGHT_CRUMBLED,             FALSE,
+    EL_BDX_SAND,                               ACTION_DIGGING, MV_BIT_RIGHT
+  },
+  {
+    O_DIRT_DIGGING_UP_CRUMBLED,                        FALSE,
+    EL_BDX_SAND,                               ACTION_DIGGING, MV_BIT_UP
+  },
+  {
+    O_DIRT_DIGGING_DOWN_CRUMBLED,              FALSE,
+    EL_BDX_SAND,                               ACTION_DIGGING, MV_BIT_DOWN
+  },
   {
     O_DIRT_SLOPED_UP_RIGHT,                    TRUE,
     EL_BDX_SAND_SLOPED_UP_RIGHT,               -1, -1
@@ -11124,7 +11160,14 @@ void InitGraphicInfo_BD(void)
     {
       int effective_element = element;
       int effective_action = action;
-      int graphic = (direction == MV_NONE ?
+      int graphic = (i == O_DIRT_CRUMBLED ?
+                     graphic = el_act2crm(effective_element, effective_action) :
+                     i == O_DIRT_DIGGING_LEFT_CRUMBLED  ||
+                     i == O_DIRT_DIGGING_RIGHT_CRUMBLED ||
+                     i == O_DIRT_DIGGING_UP_CRUMBLED    ||
+                     i == O_DIRT_DIGGING_DOWN_CRUMBLED ?
+                     graphic = el_act_dir2crm(effective_element, effective_action, direction) :
+                     direction == MV_NONE ?
                      el_act2img(effective_element, effective_action) :
                      el_act_dir2img(effective_element, effective_action, direction));
       struct GraphicInfo *g = &graphic_info[graphic];
@@ -11144,6 +11187,14 @@ void InitGraphicInfo_BD(void)
                        BD_GFX_RANGE(O_NITRO_EXPL_1, 4, e)    ? BD_GFX_FRAME(O_NITRO_EXPL_1, e) :
                        BD_GFX_RANGE(O_AMOEBA_2_EXPL_1, 4, e) ? BD_GFX_FRAME(O_AMOEBA_2_EXPL_1, e):
                        e == O_INBOX_OPEN || e == O_OUTBOX_OPEN ? j :
+                       e == O_DIRT_DIGGING_LEFT           ||
+                       e == O_DIRT_DIGGING_RIGHT          ||
+                       e == O_DIRT_DIGGING_UP             ||
+                       e == O_DIRT_DIGGING_DOWN           ||
+                       e == O_DIRT_DIGGING_LEFT_CRUMBLED  ||
+                       e == O_DIRT_DIGGING_RIGHT_CRUMBLED ||
+                       e == O_DIRT_DIGGING_UP_CRUMBLED    ||
+                       e == O_DIRT_DIGGING_DOWN_CRUMBLED ? j * 2 % 8:
                        j * 2);
       int frame = getAnimationFrame(g->anim_frames,
                                    g->anim_delay,
@@ -11151,10 +11202,6 @@ void InitGraphicInfo_BD(void)
                                    g->anim_start_frame,
                                    sync_frame);
 
-      // add special definitions for crumbled sand
-      if (i == O_DIRT_CRUMBLED)
-        graphic = el_act2crm(EL_BDX_SAND, ACTION_DEFAULT);
-
       getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, FALSE);
 
       g_bd->bitmap = src_bitmap;