void DrawLevelElementAnimation(int x, int y, int element)
{
#if 1
- int graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+ int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
#else
if (!IN_LEV_FIELD(x, y) || !IN_SCR_FIELD(sx, sy))
return;
- graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+ graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
return;
DrawLevelFieldCrumbledSand(x, y);
}
+static int getPlayerAction(struct PlayerInfo *player, int move_dir)
+{
+ int action = (player->is_pushing ? ACTION_PUSHING :
+ player->is_digging ? ACTION_DIGGING :
+ player->is_collecting ? ACTION_COLLECTING :
+ player->is_moving ? ACTION_MOVING :
+ player->is_snapping ? ACTION_SNAPPING :
+ player->is_sleeping ? ACTION_SLEEPING :
+ player->is_bored ? ACTION_BORING :
+ player->is_waiting ? ACTION_WAITING : ACTION_DEFAULT);
+
+ if (player->is_sleeping)
+ {
+ if (player->num_special_action_sleeping > 0)
+ {
+ if (player->anim_delay_counter == 0 && player->post_delay_counter == 0)
+ {
+ int last_special_action = player->special_action_sleeping;
+ int num_special_action = player->num_special_action_sleeping;
+ int special_action =
+ (last_special_action == ACTION_DEFAULT ? ACTION_SLEEPING_1 :
+ last_special_action == ACTION_SLEEPING ? ACTION_SLEEPING :
+ last_special_action < ACTION_SLEEPING_1 + num_special_action - 1 ?
+ last_special_action + 1 : ACTION_SLEEPING);
+ int special_graphic =
+ el_act_dir2img(player->element_nr, special_action, move_dir);
+
+ player->anim_delay_counter =
+ graphic_info[special_graphic].anim_delay_fixed +
+ SimpleRND(graphic_info[special_graphic].anim_delay_random);
+ player->post_delay_counter =
+ graphic_info[special_graphic].post_delay_fixed +
+ SimpleRND(graphic_info[special_graphic].post_delay_random);
+
+ player->special_action_sleeping = special_action;
+ }
+
+ if (player->anim_delay_counter > 0)
+ {
+ action = player->special_action_sleeping;
+ player->anim_delay_counter--;
+ }
+ else if (player->post_delay_counter > 0)
+ {
+ player->post_delay_counter--;
+ }
+ }
+ }
+ else if (player->is_bored)
+ {
+ if (player->num_special_action_bored > 0)
+ {
+ if (player->anim_delay_counter == 0 && player->post_delay_counter == 0)
+ {
+ int special_action =
+ ACTION_BORING_1 + SimpleRND(player->num_special_action_bored);
+ int special_graphic =
+ el_act_dir2img(player->element_nr, special_action, move_dir);
+
+ player->anim_delay_counter =
+ graphic_info[special_graphic].anim_delay_fixed +
+ SimpleRND(graphic_info[special_graphic].anim_delay_random);
+ player->post_delay_counter =
+ graphic_info[special_graphic].post_delay_fixed +
+ SimpleRND(graphic_info[special_graphic].post_delay_random);
+
+ player->special_action_bored = special_action;
+ }
+
+ if (player->anim_delay_counter > 0)
+ {
+ action = player->special_action_bored;
+ player->anim_delay_counter--;
+ }
+ else if (player->post_delay_counter > 0)
+ {
+ player->post_delay_counter--;
+ }
+ }
+ }
+
+ return action;
+}
+
+static int getPlayerGraphic(struct PlayerInfo *player, int move_dir)
+{
+ if (player->use_murphy_graphic)
+ {
+ /* this works only because currently only one player can be "murphy" ... */
+ static int last_horizontal_dir = MV_LEFT;
+ int graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir);
+
+ if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
+ last_horizontal_dir = move_dir;
+
+ if (graphic == IMG_SP_MURPHY) /* undefined => use special graphic */
+ {
+ int direction = (player->is_snapping ? move_dir : last_horizontal_dir);
+
+ graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction);
+ }
+
+ return graphic;
+ }
+ else
+ return el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
+}
+
+static boolean equalGraphics(int graphic1, int graphic2)
+{
+ struct GraphicInfo *g1 = &graphic_info[graphic1];
+ struct GraphicInfo *g2 = &graphic_info[graphic2];
+
+ return (g1->bitmap == g2->bitmap &&
+ g1->src_x == g2->src_x &&
+ g1->src_y == g2->src_y &&
+ g1->anim_frames == g2->anim_frames &&
+ g1->anim_delay == g2->anim_delay &&
+ g1->anim_mode == g2->anim_mode);
+}
+
void DrawAllPlayers()
{
int i;
int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
int graphic;
int action = ACTION_DEFAULT;
+ int last_player_graphic = getPlayerGraphic(player, move_dir);
+ int last_player_frame = player->Frame;
int frame = 0;
if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
if (element == EL_EXPLOSION)
return;
- action = (player->is_pushing ? ACTION_PUSHING :
+#if 1
+
+ action = getPlayerAction(player, move_dir);
+
+#else
+
+ action = (player->is_pushing ? ACTION_PUSHING :
player->is_digging ? ACTION_DIGGING :
player->is_collecting ? ACTION_COLLECTING :
player->is_moving ? ACTION_MOVING :
- player->is_snapping ? ACTION_SNAPPING : ACTION_DEFAULT);
+ player->is_snapping ? ACTION_SNAPPING :
+ player->is_sleeping ? ACTION_SLEEPING :
+ player->is_bored ? ACTION_BORING :
+ player->is_waiting ? ACTION_WAITING : ACTION_DEFAULT);
+
+ if (player->is_bored && player->num_special_action_bored > 0)
+ {
+ if (player->anim_delay_counter == 0 && player->post_delay_counter == 0)
+ {
+ int graphic_waiting;
+
+ action = ACTION_BORING_1 + SimpleRND(player->num_special_action_bored);
+ special_graphic = el_act_dir2img(EL_SP_MURPHY, action, move_dir);
+
+ player->anim_delay_counter =
+ graphic_info[special_graphic].anim_delay_fixed +
+ SimpleRND(graphic_info[special_graphic].anim_delay_random);
+ player->post_delay_counter =
+ graphic_info[special_graphic].post_delay_fixed +
+ SimpleRND(graphic_info[special_graphic].post_delay_random);
+ player->special_action_bored = action;
+ }
+
+ if (player->anim_delay_counter > 0)
+ {
+ action = player->special_action_bored;
+ player->anim_delay_counter--;
+ }
+
+ if (player->post_delay_counter > 0)
+ {
+ player->post_delay_counter--;
+ }
+ }
+#endif
#if 0
printf("::: '%s'\n", element_action_info[action].suffix);
/* draw player himself */
/* ----------------------------------------------------------------------- */
+#if 1
+
+ graphic = getPlayerGraphic(player, move_dir);
+
+ /* in the case of changed player action or direction, prevent the current
+ animation frame from being restarted for identical animations */
+ if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
+ player->Frame = last_player_frame;
+
+#else
+
if (player->use_murphy_graphic)
{
static int last_horizontal_dir = MV_LEFT;
else
graphic = el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
+#endif
+
frame = getGraphicAnimationFrame(graphic, player->Frame);
if (player->GfxPos)
{
int element = MovingOrBlocked2Element(next_jx, next_jy);
int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
+#if 1
+ int frame = getGraphicAnimationFrame(graphic, player->StepFrame);
+#else
int frame = getGraphicAnimationFrame(graphic, player->Frame);
+#endif
DrawGraphicShifted(px, py, sxx, syy, graphic, frame,
NO_CUTTING, NO_MASKING);
{
SetRandomAnimationValue(lx, ly);
- graphic = el_act_dir2img(element, GfxAction[lx][ly], MovDir[lx][ly]);
+ graphic = el_act_dir2img(element, GfxAction[lx][ly], GfxDir[lx][ly]);
frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
}
else /* border element */