RND(element_info[e].push_delay_random))
#define GET_NEW_MOVE_DELAY(e) ( (element_info[e].move_delay_fixed) + \
RND(element_info[e].move_delay_random))
+#define GET_MAX_MOVE_DELAY(e) ( (element_info[e].move_delay_fixed) + \
+ (element_info[e].move_delay_random))
#define ELEMENT_CAN_ENTER_FIELD_GENERIC(e, x, y, condition) \
(IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \
case EL_PIG:
case EL_DRAGON:
- MovDir[x][y] = 1 << RND(4);
+ GfxDir[x][y] = MovDir[x][y] = 1 << RND(4);
break;
#if 0
/* dynamically adjust player properties according to game engine version */
game.initial_move_delay =
- (game.engine_version <= VERSION_IDENT(2,0,1) ? INITIAL_MOVE_DELAY_ON :
+ (game.engine_version <= VERSION_IDENT(2,0,1,0) ? INITIAL_MOVE_DELAY_ON :
INITIAL_MOVE_DELAY_OFF);
/* dynamically adjust player properties according to level information */
game.initial_move_delay_value =
(level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
+ /* ---------- initialize player's initial push delay --------------------- */
+
+ /* dynamically adjust player properties according to game engine version */
+ game.initial_push_delay_value =
+ (game.engine_version < VERSION_IDENT(3,0,7,1) ? 5 : -1);
+
/* ---------- initialize changing elements ------------------------------- */
/* initialize changing elements information */
{
if (!IS_CUSTOM_ELEMENT(i))
{
- element_info[i].push_delay_fixed = 2;
- element_info[i].push_delay_random = 8;
+ element_info[i].push_delay_fixed = game.default_push_delay_fixed;
+ element_info[i].push_delay_random = game.default_push_delay_random;
}
}
player->move_delay_value = game.initial_move_delay_value;
player->push_delay = 0;
- player->push_delay_value = 5;
+ player->push_delay_value = game.initial_push_delay_value;
player->last_jx = player->last_jy = 0;
player->jx = player->jy = 0;
ExplodeField[x][y] = EX_NO_EXPLOSION;
GfxFrame[x][y] = 0;
- GfxAction[x][y] = ACTION_DEFAULT;
GfxRandom[x][y] = INIT_GFX_RANDOM();
GfxElement[x][y] = EL_UNDEFINED;
+ GfxAction[x][y] = ACTION_DEFAULT;
+ GfxDir[x][y] = MV_NO_MOVING;
}
}
}
break;
}
+
+ GfxDir[x][y] = MovDir[x][y];
}
void InitAmoebaNr(int x, int y)
{
GfxFrame[x][y] = 0;
GfxAction[x][y] = ACTION_DEFAULT;
+ GfxDir[x][y] = MovDir[x][y];
}
void InitMovingField(int x, int y, int direction)
ResetGfxAnimation(x, y);
MovDir[newx][newy] = MovDir[x][y] = direction;
+ GfxDir[x][y] = direction;
if (Feld[newx][newy] == EL_EMPTY)
Feld[newx][newy] = EL_BLOCKED;
GfxAction[x][y] = ACTION_MOVING;
GfxFrame[newx][newy] = GfxFrame[x][y];
- GfxAction[newx][newy] = GfxAction[x][y];
GfxRandom[newx][newy] = GfxRandom[x][y];
+ GfxAction[newx][newy] = GfxAction[x][y];
+ GfxDir[newx][newy] = GfxDir[x][y];
}
void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
GfxElement[x][y] = EL_UNDEFINED;
GfxAction[x][y] = ACTION_DEFAULT;
+ GfxDir[x][y] = MV_NO_MOVING;
}
void RemoveMovingField(int x, int y)
#if 0
/* --- This is only really needed (and now handled) in "Impact()". --- */
/* do not explode moving elements that left the explode field in time */
- if (game.engine_version >= RELEASE_IDENT(2,2,0,7) &&
+ if (game.engine_version >= VERSION_IDENT(2,2,0,7) &&
center_element == EL_EMPTY && (mode == EX_NORMAL || mode == EX_CENTER))
return;
#endif
#else
if ((IS_INDESTRUCTIBLE(element) &&
- (game.engine_version < VERSION_IDENT(2,2,0) ||
+ (game.engine_version < VERSION_IDENT(2,2,0,0) ||
(!IS_WALKABLE_OVER(element) && !IS_WALKABLE_UNDER(element)))) ||
element == EL_FLAMES)
continue;
RemoveField(x, y);
#else
MovDir[x][y] = MovPos[x][y] = 0;
+ GfxDir[x][y] = MovDir[x][y];
AmoebaNr[x][y] = 0;
#endif
#endif
Back[x][y] = 0;
MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
+ GfxDir[x][y] = MV_NO_MOVING;
ChangeDelay[x][y] = 0;
ChangePage[x][y] = -1;
MovPos[x][y + 1] <= TILEY / 2));
/* do not smash moving elements that left the smashed field in time */
- if (game.engine_version >= RELEASE_IDENT(2,2,0,7) && IS_MOVING(x, y + 1) &&
+ if (game.engine_version >= VERSION_IDENT(2,2,0,7) && IS_MOVING(x, y + 1) &&
ABS(MovPos[x][y + 1] + getElementMoveStepsize(x, y + 1)) >= TILEX)
object_hit = FALSE;
PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT);
}
-void TurnRound(int x, int y)
+inline static void TurnRoundExt(int x, int y)
{
static struct
{
}
}
+static void TurnRound(int x, int y)
+{
+ int direction = MovDir[x][y];
+
+#if 0
+ GfxDir[x][y] = MovDir[x][y];
+#endif
+
+ TurnRoundExt(x, y);
+
+#if 1
+ GfxDir[x][y] = MovDir[x][y];
+#endif
+
+ if (direction != MovDir[x][y])
+ GfxFrame[x][y] = 0;
+
+#if 1
+ if (MovDelay[x][y])
+ GfxAction[x][y] = ACTION_TURNING_FROM_LEFT + MV_DIR_BIT(direction);
+#else
+ if (MovDelay[x][y])
+ GfxAction[x][y] = ACTION_WAITING;
+#endif
+}
+
static boolean JustBeingPushed(int x, int y)
{
int i;
void StartMoving(int x, int y)
{
- boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0));
+ boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0,0));
boolean started_moving = FALSE; /* some elements can fall _and_ move */
int element = Feld[x][y];
if (Stop[x][y])
return;
+#if 1
+ if (MovDelay[x][y] == 0)
+ GfxAction[x][y] = ACTION_DEFAULT;
+#else
/* !!! this should be handled more generic (not only for mole) !!! */
if (element != EL_MOLE && GfxAction[x][y] != ACTION_DIGGING)
GfxAction[x][y] = ACTION_DEFAULT;
+#endif
if (CAN_FALL(element) && y < lev_fieldy - 1)
{
#endif
}
#if 1
- else if ((game.engine_version < RELEASE_IDENT(2,2,0,7) &&
+ else if ((game.engine_version < VERSION_IDENT(2,2,0,7) &&
CAN_SMASH(element) && WasJustMoving[x][y] && !Pushed[x][y + 1] &&
(Feld[x][y + 1] == EL_BLOCKED)) ||
- (game.engine_version >= VERSION_IDENT(3,0,7) &&
+ (game.engine_version >= VERSION_IDENT(3,0,7,0) &&
CAN_SMASH(element) && WasJustFalling[x][y] &&
(Feld[x][y + 1] == EL_BLOCKED || IS_PLAYER(x, y + 1))))
#else
#if 1
- else if (game.engine_version < RELEASE_IDENT(2,2,0,7) &&
+ else if (game.engine_version < VERSION_IDENT(2,2,0,7) &&
CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED &&
WasJustMoving[x][y] && !Pushed[x][y + 1])
#else
/* !!! PLACE THIS SOMEWHERE AFTER "TurnRound()" !!! */
ResetGfxAnimation(x, y);
#endif
+
+#if 0
+ if (GfxAction[x][y] != ACTION_WAITING)
+ printf("::: %d: %d != ACTION_WAITING\n", element, GfxAction[x][y]);
+
GfxAction[x][y] = ACTION_WAITING;
+#endif
}
if (element == EL_ROBOT ||
return;
}
+#if 0
/* special case of "moving" animation of waiting elements (FIX THIS !!!);
for all other elements GfxAction will be set by InitMovingField() */
if (element == EL_BD_BUTTERFLY || element == EL_BD_FIREFLY)
GfxAction[x][y] = ACTION_MOVING;
+#endif
}
/* now make next step */
if (DigField(local_player, newx, newy, 0, 0, DF_DIG) == MF_MOVING)
DrawLevelField(newx, newy);
else
- MovDir[x][y] = MV_NO_MOVING;
+ GfxDir[x][y] = MovDir[x][y] = MV_NO_MOVING;
}
else if (!IS_FREE(newx, newy))
{
/* copy animation control values to new field */
GfxFrame[newx][newy] = GfxFrame[x][y];
- GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */
GfxRandom[newx][newy] = GfxRandom[x][y]; /* keep same random value */
+ GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */
+ GfxDir[newx][newy] = GfxDir[x][y]; /* keep element direction */
Pushed[x][y] = Pushed[newx][newy] = FALSE;
if (!CAN_MOVE(element) ||
(CAN_FALL(element) && direction == MV_DOWN))
- MovDir[newx][newy] = 0;
+ GfxDir[x][y] = MovDir[newx][newy] = 0;
#endif
#endif
{
TestIfBadThingTouchesHero(newx, newy);
TestIfBadThingTouchesFriend(newx, newy);
- TestIfBadThingTouchesOtherBadThing(newx, newy);
+
+ if (!IS_CUSTOM_ELEMENT(element))
+ TestIfBadThingTouchesOtherBadThing(newx, newy);
}
else if (element == EL_PENGUIN)
TestIfFriendTouchesBadThing(newx, newy);
if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
{
- int graphic = el_dir2img(Feld[x][y], MovDir[x][y]);
+ int graphic = el_dir2img(Feld[x][y], GfxDir[x][y]);
int frame = getGraphicAnimationFrame(graphic, 17 - MovDelay[x][y]);
DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
Feld[x][y] = Store[x][y];
Store[x][y] = 0;
- MovDir[x][y] = MV_NO_MOVING;
+ GfxDir[x][y] = MovDir[x][y] = MV_NO_MOVING;
DrawLevelField(x, y);
}
}
{
Feld[ax][ay-1] = EL_EXPANDABLE_WALL_GROWING;
Store[ax][ay-1] = element;
- MovDir[ax][ay-1] = MV_UP;
+ GfxDir[ax][ay-1] = MovDir[ax][ay-1] = MV_UP;
if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay-1)))
DrawGraphic(SCREENX(ax), SCREENY(ay - 1),
IMG_EXPANDABLE_WALL_GROWING_UP, 0);
{
Feld[ax][ay+1] = EL_EXPANDABLE_WALL_GROWING;
Store[ax][ay+1] = element;
- MovDir[ax][ay+1] = MV_DOWN;
+ GfxDir[ax][ay+1] = MovDir[ax][ay+1] = MV_DOWN;
if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay+1)))
DrawGraphic(SCREENX(ax), SCREENY(ay + 1),
IMG_EXPANDABLE_WALL_GROWING_DOWN, 0);
{
Feld[ax-1][ay] = EL_EXPANDABLE_WALL_GROWING;
Store[ax-1][ay] = element;
- MovDir[ax-1][ay] = MV_LEFT;
+ GfxDir[ax-1][ay] = MovDir[ax-1][ay] = MV_LEFT;
if (IN_SCR_FIELD(SCREENX(ax-1), SCREENY(ay)))
DrawGraphic(SCREENX(ax - 1), SCREENY(ay),
IMG_EXPANDABLE_WALL_GROWING_LEFT, 0);
{
Feld[ax+1][ay] = EL_EXPANDABLE_WALL_GROWING;
Store[ax+1][ay] = element;
- MovDir[ax+1][ay] = MV_RIGHT;
+ GfxDir[ax+1][ay] = MovDir[ax+1][ay] = MV_RIGHT;
if (IN_SCR_FIELD(SCREENX(ax+1), SCREENY(ay)))
DrawGraphic(SCREENX(ax + 1), SCREENY(ay),
IMG_EXPANDABLE_WALL_GROWING_RIGHT, 0);
if (ChangeDelay[x][y] != 0) /* continue element change */
{
- int graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+ int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
if (IS_ANIMATED(graphic))
DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
struct ElementChangeInfo *change = &element_info[element].change_page[j];
if (change->can_change &&
+#if 1
+ change->events & CH_EVENT_BIT(trigger_event) &&
+#endif
change->sides & trigger_side &&
change->trigger_element == trigger_element)
{
+#if 0
+ if (!(change->events & CH_EVENT_BIT(trigger_event)))
+ printf("::: !!! %d triggers %d: using wrong page %d [event %d]\n",
+ trigger_element-EL_CUSTOM_START+1, i+1, j, trigger_event);
+#endif
+
change_element = TRUE;
page = j;
return CheckElementSideChange(x, y, element, CH_SIDE_ANY, trigger_event, -1);
}
+#if 1
+static byte PlayerActions(struct PlayerInfo *player, byte player_action)
+{
+#if 0
+ static byte stored_player_action[MAX_PLAYERS];
+ static int num_stored_actions = 0;
+#endif
+ boolean moved = FALSE, snapped = FALSE, dropped = FALSE;
+ int left = player_action & JOY_LEFT;
+ int right = player_action & JOY_RIGHT;
+ int up = player_action & JOY_UP;
+ int down = player_action & JOY_DOWN;
+ int button1 = player_action & JOY_BUTTON_1;
+ int button2 = player_action & JOY_BUTTON_2;
+ int dx = (left ? -1 : right ? 1 : 0);
+ int dy = (up ? -1 : down ? 1 : 0);
+
+#if 0
+ stored_player_action[player->index_nr] = 0;
+ num_stored_actions++;
+#endif
+
+#if 0
+ printf("::: player %d [%d]\n", player->index_nr, FrameCounter);
+#endif
+
+ if (!player->active || tape.pausing)
+ return 0;
+
+ if (player_action)
+ {
+#if 0
+ printf("::: player %d acts [%d]\n", player->index_nr, FrameCounter);
+#endif
+
+ if (button1)
+ snapped = SnapField(player, dx, dy);
+ else
+ {
+ if (button2)
+ dropped = DropElement(player);
+
+ moved = MovePlayer(player, dx, dy);
+ }
+
+ if (tape.single_step && tape.recording && !tape.pausing)
+ {
+ if (button1 || (dropped && !moved))
+ {
+ TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
+ SnapField(player, 0, 0); /* stop snapping */
+ }
+ }
+
+#if 1
+ return player_action;
+#else
+ stored_player_action[player->index_nr] = player_action;
+#endif
+ }
+ else
+ {
+#if 0
+ printf("::: player %d waits [%d]\n", player->index_nr, FrameCounter);
+#endif
+
+ /* no actions for this player (no input at player's configured device) */
+
+ DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
+ SnapField(player, 0, 0);
+ CheckGravityMovement(player);
+
+ if (player->MovPos == 0)
+ InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir);
+
+ if (player->MovPos == 0) /* needed for tape.playing */
+ player->is_moving = FALSE;
+
+ return 0;
+ }
+
+#if 0
+ if (tape.recording && num_stored_actions >= MAX_PLAYERS)
+ {
+ printf("::: player %d recorded [%d]\n", player->index_nr, FrameCounter);
+
+ TapeRecordAction(stored_player_action);
+ num_stored_actions = 0;
+ }
+#endif
+}
+
+#else
+
static void PlayerActions(struct PlayerInfo *player, byte player_action)
{
static byte stored_player_action[MAX_PLAYERS];
stored_player_action[player->index_nr] = 0;
num_stored_actions++;
+ printf("::: player %d [%d]\n", player->index_nr, FrameCounter);
+
if (!player->active || tape.pausing)
return;
if (player_action)
{
+ printf("::: player %d acts [%d]\n", player->index_nr, FrameCounter);
+
if (button1)
snapped = SnapField(player, dx, dy);
else
}
else
{
+ printf("::: player %d waits [%d]\n", player->index_nr, FrameCounter);
+
/* no actions for this player (no input at player's configured device) */
DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
if (tape.recording && num_stored_actions >= MAX_PLAYERS)
{
+ printf("::: player %d recorded [%d]\n", player->index_nr, FrameCounter);
+
TapeRecordAction(stored_player_action);
num_stored_actions = 0;
}
}
+#endif
void GameActions()
{
int i, x, y, element, graphic;
byte *recorded_player_action;
byte summarized_player_action = 0;
+#if 1
+ byte tape_action[MAX_PLAYERS];
+#endif
if (game_status != GAME_MODE_PLAYING)
return;
if (!options.network && !setup.team_mode)
local_player->effective_action = summarized_player_action;
- for (i=0; i<MAX_PLAYERS; i++)
+ for (i=0; i < MAX_PLAYERS; i++)
{
int actual_player_action = stored_player[i].effective_action;
if (recorded_player_action)
actual_player_action = recorded_player_action[i];
- PlayerActions(&stored_player[i], actual_player_action);
+ tape_action[i] = PlayerActions(&stored_player[i], actual_player_action);
+
ScrollPlayer(&stored_player[i], SCROLL_GO_ON);
}
+#if 1
+ if (tape.recording)
+ TapeRecordAction(tape_action);
+#endif
+
network_player_action_received = FALSE;
ScrollScreen(NULL, SCROLL_GO_ON);
#endif
#if 1
- if (game.engine_version < RELEASE_IDENT(2,2,0,7))
+ if (game.engine_version < VERSION_IDENT(2,2,0,7))
{
for (i=0; i<MAX_PLAYERS; i++)
{
{
element = Feld[x][y];
#if 1
- graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+ graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
#else
graphic = el2img(element);
#endif
#if 1
/* this may take place after moving, so 'element' may have changed */
+#if 0
if (IS_CHANGING(x, y))
+#else
+ if (IS_CHANGING(x, y) &&
+ (game.engine_version < VERSION_IDENT(3,0,7,1) || !Stop[x][y]))
+#endif
{
#if 0
ChangeElement(x, y, ChangePage[x][y] != -1 ? ChangePage[x][y] :
#endif
element = Feld[x][y];
- graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+ graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
}
#endif
StartMoving(x, y);
#if 1
- graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+ graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
#if 0
if (element == EL_MOLE)
printf("::: %d, %d, %d [%d]\n",
{
DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+#if 0
+ if (element == EL_BUG)
+ printf("::: %d, %d\n", graphic, GfxFrame[x][y]);
+#endif
+
#if 0
if (element == EL_MOLE)
printf("::: %d, %d\n", graphic, GfxFrame[x][y]);
player->is_moving = FALSE;
}
- if (game.engine_version < VERSION_IDENT(3,0,7))
+ if (game.engine_version < VERSION_IDENT(3,0,7,0))
{
TestIfHeroTouchesBadThing(jx, jy);
TestIfPlayerTouchesCustomElement(jx, jy);
player->LevelSolved = player->GameOver = TRUE;
}
- if (game.engine_version >= VERSION_IDENT(3,0,7))
+ if (game.engine_version >= VERSION_IDENT(3,0,7,0))
{
TestIfHeroTouchesBadThing(jx, jy);
TestIfPlayerTouchesCustomElement(jx, jy);
if (IS_PLAYER(x, y))
{
- if (game.engine_version < VERSION_IDENT(3,0,7))
+ if (game.engine_version < VERSION_IDENT(3,0,7,0))
border_element = Feld[xx][yy]; /* may be moving! */
else if (!IS_MOVING(xx, yy) && !IS_BLOCKED(xx, yy))
border_element = Feld[xx][yy];
}
else if (IS_PLAYER(xx, yy))
{
- if (game.engine_version >= VERSION_IDENT(3,0,7))
+ if (game.engine_version >= VERSION_IDENT(3,0,7,0))
{
struct PlayerInfo *player = PLAYERINFO(xx, yy);
if (!IN_LEV_FIELD(xx, yy))
continue;
- if (game.engine_version < VERSION_IDENT(3,0,7))
+ if (game.engine_version < VERSION_IDENT(3,0,7,0))
border_element = Feld[xx][yy]; /* may be moving! */
else if (!IS_MOVING(xx, yy) && !IS_BLOCKED(xx, yy))
border_element = Feld[xx][yy];
if (bad_element == EL_ROBOT && player->is_moving)
continue; /* robot does not kill player if he is moving */
- if (game.engine_version >= VERSION_IDENT(3,0,7))
+ if (game.engine_version >= VERSION_IDENT(3,0,7,0))
{
if (player->MovPos != 0 && !(player->MovDir & touch_dir[i]))
continue; /* center and border element do not touch */
CH_SIDE_BOTTOM, /* moving up */
CH_SIDE_TOP, /* moving down */
};
- boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0));
+ boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0,0));
int jx = player->jx, jy = player->jy;
int dx = x - jx, dy = y - jy;
int nextx = x + dx, nexty = y + dy;
if (IS_TUBE(Feld[jx][jy]) || IS_TUBE(Back[jx][jy]))
#else
if (IS_TUBE(Feld[jx][jy]) ||
- (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0)))
+ (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0,0)))
#endif
{
int i = 0;
element = Feld[x][y];
if (mode == DF_SNAP && !IS_SNAPPABLE(element) &&
- game.engine_version >= VERSION_IDENT(2,2,0))
+ game.engine_version >= VERSION_IDENT(2,2,0,0))
return MF_NO_ACTION;
switch (element)
!(element == EL_SPRING && use_spring_bug))
return MF_NO_ACTION;
+#if 1
+ if (CAN_MOVE(element) && GET_MAX_MOVE_DELAY(element) == 0 &&
+ ((move_direction & MV_VERTICAL &&
+ ((element_info[element].move_pattern & MV_LEFT &&
+ IN_LEV_FIELD(x - 1, y) && IS_FREE(x - 1, y)) ||
+ (element_info[element].move_pattern & MV_RIGHT &&
+ IN_LEV_FIELD(x + 1, y) && IS_FREE(x + 1, y)))) ||
+ (move_direction & MV_HORIZONTAL &&
+ ((element_info[element].move_pattern & MV_UP &&
+ IN_LEV_FIELD(x, y - 1) && IS_FREE(x, y - 1)) ||
+ (element_info[element].move_pattern & MV_DOWN &&
+ IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1))))))
+ return MF_NO_ACTION;
+#endif
+
#if 1
/* do not push elements already moving away faster than player */
if (CAN_MOVE(element) && MovDir[x][y] == move_direction &&
if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING)
return MF_NO_ACTION;
#endif
+
+#if 1
+ if (game.engine_version >= VERSION_IDENT(3,0,7,1))
+ {
+ if (player->push_delay_value == -1)
+ player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+ }
+ else if (game.engine_version >= VERSION_IDENT(2,2,0,7))
+ {
+ if (!player->is_pushing)
+ player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+ }
+
+ /*
+ if (game.engine_version >= VERSION_IDENT(2,2,0,7) &&
+ (game.engine_version < VERSION_IDENT(3,0,7,1) ||
+ !player_is_pushing))
+ player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+ */
+#else
if (!player->is_pushing &&
- game.engine_version >= RELEASE_IDENT(2,2,0,7))
+ game.engine_version >= VERSION_IDENT(2,2,0,7))
player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+#endif
+
+#if 0
+ printf("::: push delay: %ld [%d, %d] [%d]\n",
+ player->push_delay_value, FrameCounter, game.engine_version,
+ player->is_pushing);
+#endif
player->is_pushing = TRUE;
if (!FrameReached(&player->push_delay, player->push_delay_value) &&
!(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
element != EL_SPRING && element != EL_BALLOON)
+ {
+ /* make sure that there is no move delay before next try to push */
+ if (game.engine_version >= VERSION_IDENT(3,0,7,1))
+ player->move_delay = INITIAL_MOVE_DELAY_OFF;
+
return MF_NO_ACTION;
+ }
+
+#if 0
+ printf("::: NOW PUSHING... [%d]\n", FrameCounter);
+#endif
if (IS_SB_ELEMENT(element))
{
Pushed[x][y] = TRUE;
Pushed[nextx][nexty] = TRUE;
- if (game.engine_version < RELEASE_IDENT(2,2,0,7))
+ if (game.engine_version < VERSION_IDENT(2,2,0,7))
player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+ else
+ player->push_delay_value = -1; /* get new value later */
CheckTriggeredElementSideChange(x, y, element, dig_side,
CE_OTHER_GETS_PUSHED);
dy == -1 ? MV_UP :
dy == +1 ? MV_DOWN : MV_NO_MOVING);
- if (player->MovPos && game.engine_version >= VERSION_IDENT(2,2,0))
+ if (player->MovPos && game.engine_version >= VERSION_IDENT(2,2,0,0))
return FALSE;
if (!player->active || !IN_LEV_FIELD(x, y))