#define USE_GFX_RESET_ONLY_WHEN_MOVING (USE_NEW_STUFF * 1)
#define USE_GFX_RESET_PLAYER_ARTWORK (USE_NEW_STUFF * 1)
+#define USE_FIX_KILLED_BY_NON_WALKABLE (USE_NEW_STUFF * 1)
+
/* for DigField() */
#define DF_NO_PUSH 0
player->drop_delay = 0;
player->drop_pressed_delay = 0;
- player->last_jx = player->last_jy = 0;
- player->jx = player->jy = 0;
+ player->last_jx = -1;
+ player->last_jy = -1;
+ player->jx = -1;
+ player->jy = -1;
player->shield_normal_time_left = 0;
player->shield_deadly_time_left = 0;
{ MV_LEFT, MV_RIGHT, MV_UP, MV_DOWN }
};
- switch(element)
+ switch (element)
{
case EL_BUG_RIGHT:
case EL_BUG_UP:
return position;
}
-inline static int getElementMoveStepsize(int x, int y)
+inline static int getElementMoveStepsizeExt(int x, int y, int direction)
{
int element = Feld[x][y];
- int direction = MovDir[x][y];
int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0);
int horiz_move = (dx != 0);
return step;
}
+inline static int getElementMoveStepsize(int x, int y)
+{
+ return getElementMoveStepsizeExt(x, y, MovDir[x][y]);
+}
+
void InitPlayerGfxAnimation(struct PlayerInfo *player, int action, int dir)
{
if (player->GfxAction != action || player->GfxDir != dir)
void InitMovingField(int x, int y, int direction)
{
int element = Feld[x][y];
- int move_stepsize = getElementMoveStepsize(x, y);
int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0);
int newx = x + dx;
int newy = y + dy;
- boolean is_moving = (move_stepsize != 0); /* moving or being moved */
+ boolean is_moving_before, is_moving_after;
+#if 0
boolean continues_moving = (WasJustMoving[x][y] && direction == MovDir[x][y]);
+#endif
+
+ /* check if element was/is moving or being moved before/after mode change */
+#if 1
+ is_moving_before = WasJustMoving[x][y];
+#else
+ is_moving_before = (getElementMoveStepsizeExt(x, y, MovDir[x][y]) != 0);
+#endif
+ is_moving_after = (getElementMoveStepsizeExt(x, y, direction) != 0);
- /* reset animation only for moving elements that change direction of moving
+ /* reset animation only for moving elements which change direction of moving
+ or which just started or stopped moving
(else CEs with property "can move" / "not moving" are reset each frame) */
#if USE_GFX_RESET_ONLY_WHEN_MOVING
- if (is_moving && !continues_moving)
+#if 1
+ if (is_moving_before != is_moving_after ||
+ direction != MovDir[x][y])
+ ResetGfxAnimation(x, y);
+#else
+ if ((is_moving_before || is_moving_after) && !continues_moving)
ResetGfxAnimation(x, y);
+#endif
#else
if (!continues_moving)
ResetGfxAnimation(x, y);
MovDir[x][y] = direction;
GfxDir[x][y] = direction;
- GfxAction[x][y] = (!is_moving ? ACTION_WAITING :
+
+#if USE_GFX_RESET_ONLY_WHEN_MOVING
+ GfxAction[x][y] = (!is_moving_after ? ACTION_WAITING :
direction == MV_DOWN && CAN_FALL(element) ?
ACTION_FALLING : ACTION_MOVING);
+#else
+ GfxAction[x][y] = (direction == MV_DOWN && CAN_FALL(element) ?
+ ACTION_FALLING : ACTION_MOVING);
+#endif
/* this is needed for CEs with property "can move" / "not moving" */
- if (is_moving)
+ if (is_moving_after)
{
if (Feld[newx][newy] == EL_EMPTY)
Feld[newx][newy] = EL_BLOCKED;
}
}
- switch(element)
+ switch (element)
{
case EL_BUG:
case EL_SPACESHIP:
/* ---------- execute action -------------------------------------------- */
- switch(action_type)
+ switch (action_type)
{
case CA_NO_ACTION:
{
#if USE_NEW_CUSTOM_VALUE
int last_ce_value = CustomValue[x][y];
#endif
+ boolean player_explosion_protected = PLAYER_EXPLOSION_PROTECTED(x, y);
boolean new_element_is_player = ELEM_IS_PLAYER(new_element);
boolean add_player_onto_element = (new_element_is_player &&
#if USE_CODE_THAT_BREAKS_SNAKE_BITE
/* check if element under the player changes from accessible to unaccessible
(needed for special case of dropping element which then changes) */
/* (must be checked after creating new element for walkable group elements) */
+#if USE_FIX_KILLED_BY_NON_WALKABLE
+ if (IS_PLAYER(x, y) && !player_explosion_protected &&
+ IS_ACCESSIBLE(old_element) && !IS_ACCESSIBLE(new_element))
+ {
+ Bang(x, y);
+
+ return;
+ }
+#else
if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) &&
IS_ACCESSIBLE(old_element) && !IS_ACCESSIBLE(new_element))
{
return;
}
+#endif
#endif
/* "ChangeCount" not set yet to allow "entered by player" change one time */
void RaiseScoreElement(int element)
{
- switch(element)
+ switch (element)
{
case EL_EMERALD:
case EL_BD_DIAMOND:
{
FreeEngineSnapshot(); /* free previous snapshot, if needed */
+ if (level_editor_test_game) /* do not save snapshots from editor */
+ return;
+
/* copy some special values to a structure better suited for the snapshot */
SaveEngineSnapshotValues_RND();