if a cell is changed, it is flagged with GD_REDRAW; the flag can be cleared
by the caller.
*/
-void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer,
+void gd_drawcave_game(const GdCave *cave,
+ int **element_buffer, int **last_element_buffer, int **gfx_buffer,
boolean bonus_life_flash, int animcycle, boolean hate_invisible_outbox)
{
static int player_blinking = 0;
else
draw = elemdrawing[actual];
+ // draw special graphics if player is pushing something
+ if ((cave->last_direction == GD_MV_LEFT || cave->last_direction == GD_MV_RIGHT) &&
+ is_player(cave, x, y) && can_be_pushed_dir(cave, x, y, cave->last_direction))
+ {
+ // special check needed when smooth game element movements selected in setup menu:
+ // last element must either be player (before pushing) or pushable element (while pushing)
+ // (extra check needed to prevent pushing animation when moving towards pushable element)
+ if (!use_bd_smooth_movements() || last_element_buffer[y][x] != O_SPACE)
+ {
+ if (cave->last_direction == GD_MV_LEFT)
+ map = O_PLAYER_PUSH_LEFT;
+ else
+ map = O_PLAYER_PUSH_RIGHT;
+
+ if (cave->last_direction == GD_MV_LEFT)
+ draw = elemdrawing[O_PLAYER_PUSH_LEFT];
+ else
+ draw = elemdrawing[O_PLAYER_PUSH_RIGHT];
+ }
+ }
+
// if negative, animated.
if (draw < 0)
draw = -draw + animcycle;
// these define the number of the cells in the png file
#define GD_NUM_OF_CELLS_X 8
-#define GD_NUM_OF_CELLS_Y 47
+#define GD_NUM_OF_CELLS_Y 51
// +80: placeholder for cells which are rendered by the game;
// for example diamond + arrow = falling diamond
// game playing helpers
#define GD_REDRAW (1 << 10)
-void gd_drawcave_game(const GdCave *cave, int **element_buffer, int **gfx_buffer,
+void gd_drawcave_game(const GdCave *cave,
+ int **element_buffer, int **last_element_buffer, int **gfx_buffer,
boolean bonus_life_flash, int animcycle, boolean hate_invisible_outbox);
// function to copy a GdString
{ O_PLAYER_TAP, NULL, P_PLAYER, NULL, 0, 216, -216, -216 },
{ O_PLAYER_BLINK, NULL, P_PLAYER, NULL, 0, 208, -208, -208 },
{ O_PLAYER_TAP_BLINK, NULL, P_PLAYER, NULL, 0, 224, -224, -224 },
+ { O_PLAYER_PUSH_LEFT, N_("Player, pushing left"), P_PLAYER, NULL, 0, 392, -392, -392 },
+ { O_PLAYER_PUSH_RIGHT, N_("Player, pushing right"), P_PLAYER, NULL, 0, 400, -400, -400 },
{ O_CREATURE_SWITCH_ON, NULL, 0, NULL, 0, 19, 19, 19 },
{ O_EXPANDING_WALL_SWITCH_HORIZ, NULL, 0, NULL, 0, 40, 40, 40 },
{ O_EXPANDING_WALL_SWITCH_VERT, NULL, 0, NULL, 0, 41, 41, 41 },
}
// 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;
}
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)
{
// the game itself
+boolean is_player(const GdCave *cave, const int x, const int y);
+boolean can_be_pushed_dir(const GdCave *cave, const int x, const int y, const GdDirection dir);
GdDirection gd_direction_from_keypress(boolean up, boolean down, boolean left, boolean right);
void gd_cave_iterate(GdCave *cave, GdDirection player_move, boolean player_fire, boolean suicide);
void set_initial_cave_speed(GdCave *cave);
O_PLAYER_TAP,
O_PLAYER_BLINK,
O_PLAYER_TAP_BLINK,
+ O_PLAYER_PUSH_LEFT,
+ O_PLAYER_PUSH_RIGHT,
O_CREATURE_SWITCH_ON,
O_EXPANDING_WALL_SWITCH_HORIZ,
O_EXPANDING_WALL_SWITCH_VERT,
// always render the cave to the gfx buffer;
// however it may do nothing if animcycle was not changed.
if (game->element_buffer && game->gfx_buffer)
- gd_drawcave_game(game->cave, game->element_buffer, game->gfx_buffer,
+ gd_drawcave_game(game->cave, game->element_buffer, game->last_element_buffer, game->gfx_buffer,
game->bonus_life_flash != 0, game->animcycle, gd_no_invisible_outbox);
game->state_counter = counter_next;
O_PLAYER_TAP_BLINK, FALSE,
EL_BD_PLAYER, ACTION_BORING_3, -1
},
+ {
+ O_PLAYER_PUSH_LEFT, FALSE,
+ EL_BD_PLAYER, ACTION_PUSHING, MV_BIT_LEFT
+ },
+ {
+ O_PLAYER_PUSH_RIGHT, FALSE,
+ EL_BD_PLAYER, ACTION_PUSHING, MV_BIT_RIGHT
+ },
{
O_CREATURE_SWITCH_ON, FALSE,
EL_BD_CREATURE_SWITCH_ACTIVE, -1, -1