static void ScrollPlayer(struct PlayerInfo *, int);
static void ScrollScreen(struct PlayerInfo *, int);
+int DigField(struct PlayerInfo *, int, int, int, int, int, int, int);
+
static void InitBeltMovement(void);
static void CloseAllOpenTimegates(void);
static void CheckGravityMovement(struct PlayerInfo *);
{ EL_UNDEFINED, 0 },
};
+struct
+{
+ int element;
+ int direction;
+}
+tube_access[] =
+{
+ { EL_TUBE_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT },
+ { EL_TUBE_VERTICAL_LEFT, MV_LEFT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERTICAL_RIGHT, MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZONTAL_UP, MV_LEFT | MV_RIGHT | MV_UP },
+ { EL_TUBE_HORIZONTAL_DOWN, MV_LEFT | MV_RIGHT | MV_DOWN },
+ { EL_TUBE_LEFT_UP, MV_LEFT | MV_UP },
+ { EL_TUBE_LEFT_DOWN, MV_LEFT | MV_DOWN },
+ { EL_TUBE_RIGHT_UP, MV_RIGHT | MV_UP },
+ { EL_TUBE_RIGHT_DOWN, MV_RIGHT | MV_DOWN },
+
+ { EL_UNDEFINED, 0 }
+};
+
static unsigned long trigger_events[MAX_NUM_ELEMENTS];
#define IS_AUTO_CHANGING(e) (element_info[e].change_events & \
for (i = 0; collect_count_list[i].element != EL_UNDEFINED; i++)
element_info[collect_count_list[i].element].collect_count =
collect_count_list[i].count;
+
+ /* ---------- initialize access direction -------------------------------- */
+
+ /* initialize access direction values to default */
+ for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+ if (!IS_CUSTOM_ELEMENT(i))
+ element_info[i].access_direction = MV_ALL_DIRECTIONS;
+
+ /* set access direction value for certain elements from pre-defined list */
+ for (i = 0; tube_access[i].element != EL_UNDEFINED; i++)
+ element_info[tube_access[i].element].access_direction =
+ tube_access[i].direction;
}
player->inventory_size = 0;
- DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
+ DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH);
SnapField(player, 0, 0);
player->LevelSolved = FALSE;
KillHeroUnlessExplosionProtected(x, y);
border_explosion = TRUE;
+#if 0
if (phase == last_phase)
printf("::: IS_PLAYER\n");
+#endif
}
else if (CAN_EXPLODE_BY_EXPLOSION(border_element))
{
Bang(x, y);
border_explosion = TRUE;
+#if 0
if (phase == last_phase)
printf("::: CAN_EXPLODE_BY_EXPLOSION\n");
+#endif
}
else if (border_element == EL_AMOEBA_TO_DIAMOND)
{
Store2[x][y] = 0;
border_explosion = TRUE;
+#if 0
if (phase == last_phase)
printf("::: EL_AMOEBA_TO_DIAMOND [%d, %d] [%d]\n",
element_info[border_element].explosion_delay,
element_info[border_element].ignition_delay,
phase);
+#endif
}
#if 1
/* special values for move stepsize for spring and things on conveyor belt */
if (horiz_move)
{
-#if 1
+#if 0
if (element == EL_SPRING)
step = sign * MOVE_STEPSIZE_NORMAL * 2;
else if (CAN_FALL(element) && !CAN_MOVE(element) &&
started_moving = TRUE;
}
}
-#if 1
+#if 0
else if (IS_BELT_ACTIVE(Feld[x][y + 1]) && !CAN_MOVE(element))
#else
else if (IS_BELT_ACTIVE(Feld[x][y + 1]))
if ((belt_dir == MV_LEFT && left_is_free) ||
(belt_dir == MV_RIGHT && right_is_free))
{
+#if 1
+ int nextx = (belt_dir == MV_LEFT ? x - 1 : x + 1);
+#endif
+
InitMovingField(x, y, belt_dir);
started_moving = TRUE;
+#if 1
+ Pushed[x][y] = TRUE;
+ Pushed[nextx][y] = TRUE;
+#endif
+
GfxAction[x][y] = ACTION_DEFAULT;
}
+ else
+ {
+ MovDir[x][y] = 0; /* if element was moving, stop it */
+ }
}
}
}
else if (IS_FOOD_PENGUIN(Feld[newx][newy]))
{
- if (DigField(local_player, newx, newy, 0, 0, DF_DIG) == MF_MOVING)
+ if (DigField(local_player, x, y, newx, newy, 0,0, DF_DIG) == MF_MOVING)
DrawLevelField(newx, newy);
else
GfxDir[x][y] = MovDir[x][y] = MV_NO_MOVING;
#if 0
int nextx = newx + dx, nexty = newy + dy;
#endif
+#if 1
+ boolean pushed = (Pushed[x][y] && IS_PLAYER(x, y));
+ boolean pushed_by_conveyor = (Pushed[x][y] && !IS_PLAYER(x, y));
+#else
boolean pushed = Pushed[x][y];
+#endif
MovPos[x][y] += getElementMoveStepsize(x, y);
+#if 0
+ if (pushed && IS_PLAYER(x, y))
+ {
+ /* special case: moving object pushed by player */
+ MovPos[x][y] = SIGN(MovPos[x][y]) * (TILEX - ABS(PLAYERINFO(x,y)->MovPos));
+ }
+#else
if (pushed) /* special case: moving object pushed by player */
MovPos[x][y] = SIGN(MovPos[x][y]) * (TILEX - ABS(PLAYERINFO(x,y)->MovPos));
+#endif
if (ABS(MovPos[x][y]) < TILEX)
{
!(element_info[element].move_pattern & direction))
TurnRound(newx, newy);
+#if 1
+ /* prevent elements on conveyor belt from moving on in last direction */
+ if (pushed_by_conveyor && CAN_FALL(element) &&
+ direction & MV_HORIZONTAL)
+ MovDir[newx][newy] = 0;
+#endif
+
if (!pushed) /* special case: moving object pushed by player */
{
WasJustMoving[newx][newy] = 3;
/* no actions for this player (no input at player's configured device) */
- DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
+ DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH);
SnapField(player, 0, 0);
CheckGravityMovement(player);
/* no actions for this player (no input at player's configured device) */
- DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
+ DigField(player, 0, 0, 0, 0, 0, 0, DF_NO_PUSH);
SnapField(player, 0, 0);
CheckGravityMovement(player);
canEnterSupaplexPort(new_jx, new_jy, dx, dy))));
/* !!! extend EL_SAND to anything diggable !!! */
+ boolean player_is_standing_on_valid_field =
+ (IS_WALKABLE_INSIDE(Feld[jx][jy]) ||
+ (IS_WALKABLE(Feld[jx][jy]) &&
+ !(element_info[Feld[jx][jy]].access_direction & MV_DOWN)));
+
if (field_under_player_is_free &&
- !player_is_moving_to_valid_field &&
- !IS_WALKABLE_INSIDE(Feld[jx][jy]))
+ !player_is_standing_on_valid_field &&
+ !player_is_moving_to_valid_field)
player->programmed_action = MV_DOWN;
}
}
return MF_MOVING;
}
- can_move = DigField(player, new_jx, new_jy, real_dx, real_dy, DF_DIG);
+ can_move = DigField(player, jx, jy, new_jx, new_jy, real_dx,real_dy, DF_DIG);
if (can_move != MF_MOVING)
return can_move;
*/
int DigField(struct PlayerInfo *player,
- int x, int y, int real_dx, int real_dy, int mode)
+ int oldx, int oldy, int x, int y,
+ int real_dx, int real_dy, int mode)
{
static int change_sides[4] =
{
CH_SIDE_TOP, /* moving down */
};
boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0,0));
- int jx = player->jx, jy = player->jy;
+ int jx = oldx, jy = oldy;
int dx = x - jx, dy = y - jy;
int nextx = x + dx, nexty = y + dy;
int move_direction = (dx == -1 ? MV_LEFT :
dy == +1 ? MV_DOWN : MV_NO_MOVING);
int opposite_direction = MV_DIR_OPPOSITE(move_direction);
int dig_side = change_sides[MV_DIR_BIT(move_direction)];
+ int old_element = Feld[jx][jy];
int element;
if (player->MovPos == 0)
if (IS_MOVING(x, y) || IS_PLAYER(x, y))
return MF_NO_ACTION;
+#if 0
+
#if 0
if (IS_TUBE(Feld[jx][jy]) || IS_TUBE(Back[jx][jy]))
#else
return MF_NO_ACTION; /* tube has no opening in this direction */
}
- if (IS_CUSTOM_ELEMENT(Feld[jx][jy]) && IS_WALKABLE(Feld[jx][jy]) &&
- !(element_info[Feld[jx][jy]].access_direction & move_direction))
+#else
+
+ if (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0,0))
+ old_element = Back[jx][jy];
+
+#endif
+
+ if (IS_WALKABLE(old_element) &&
+ !(element_info[old_element].access_direction & move_direction))
return MF_NO_ACTION; /* field has no opening in this direction */
element = Feld[x][y];
PlayLevelSound(x, y, SND_CLASS_SP_PORT_PASSING);
break;
+#if 0
case EL_TUBE_ANY:
case EL_TUBE_VERTICAL:
case EL_TUBE_HORIZONTAL:
PlayLevelSound(x, y, SND_CLASS_TUBE_WALKING);
}
break;
+#endif
default:
{
int sound_action = ACTION_WALKING;
- if (IS_CUSTOM_ELEMENT(element) &&
- !(element_info[element].access_direction & opposite_direction))
+ if (!(element_info[element].access_direction & opposite_direction))
return MF_NO_ACTION; /* field not accessible from this direction */
if (element >= EL_GATE_1 && element <= EL_GATE_4)
player->is_dropping = FALSE;
- if (DigField(player, x, y, 0, 0, DF_SNAP) == MF_NO_ACTION)
+ if (DigField(player, jx, jy, x, y, 0, 0, DF_SNAP) == MF_NO_ACTION)
return FALSE;
player->is_snapping = TRUE;