#define USE_NEW_SPRING_BUMPER (USE_NEW_STUFF * 1)
#define USE_STOP_CHANGED_ELEMENTS (USE_NEW_STUFF * 1)
#define USE_ELEMENT_TOUCHING_BUGFIX (USE_NEW_STUFF * 1)
+#define USE_NEW_CONTINUOUS_SNAPPING (USE_NEW_STUFF * 1)
#define USE_QUICKSAND_IMPACT_BUGFIX (USE_NEW_STUFF * 0)
#define DX_TIME2 (DX + XX_TIME2)
#define DY_TIME (DY + YY_TIME)
+/* values for delayed check of falling and moving elements and for collision */
+#define CHECK_DELAY_MOVING 3
+#define CHECK_DELAY_FALLING 3
+#define CHECK_DELAY_COLLISION 2
+
/* values for initial player move delay (initial delay counter value) */
#define INITIAL_MOVE_DELAY_OFF -1
#define INITIAL_MOVE_DELAY_ON 0
else
{
stored_player[0].use_murphy = TRUE;
+
+ if (!level.use_artwork_element[0])
+ stored_player[0].artwork_element = EL_SP_MURPHY;
}
Feld[x][y] = EL_PLAYER_1;
game.envelope_active = FALSE;
- game.centered_to_player = game.centered_to_player_next = 0; /* player_1 */
+ game.centered_player_nr = game.centered_player_nr_next = -1; /* focus all */
for (i = 0; i < NUM_BELTS; i++)
{
if (tape.playing)
{
- /* when playing a tape, eliminate all players which do not participate */
+ /* when playing a tape, eliminate all players who do not participate */
for (i = 0; i < MAX_PLAYERS; i++)
{
}
else
{
- int scroll_xx = -999, scroll_yy = -999;
+ int scroll_xx = (player->jx < SBX_Left + MIDPOSX ? SBX_Left :
+ player->jx > SBX_Right + MIDPOSX ? SBX_Right :
+ player->jx - MIDPOSX);
+
+ int scroll_yy = (player->jy < SBY_Upper + MIDPOSY ? SBY_Upper :
+ player->jy > SBY_Lower + MIDPOSY ? SBY_Lower :
+ player->jy - MIDPOSY);
ScrollScreen(NULL, SCROLL_GO_ON); /* scroll last frame to full tile */
- while (scroll_xx != scroll_x || scroll_yy != scroll_y)
+ while (scroll_x != scroll_xx || scroll_y != scroll_yy)
{
int dx = 0, dy = 0;
int fx = FX, fy = FY;
- scroll_xx = (player->jx < SBX_Left + MIDPOSX ? SBX_Left :
- player->jx > SBX_Right + MIDPOSX ? SBX_Right :
- player->jx - MIDPOSX);
-
- scroll_yy = (player->jy < SBY_Upper + MIDPOSY ? SBY_Upper :
- player->jy > SBY_Lower + MIDPOSY ? SBY_Lower :
- player->jy - MIDPOSY);
-
dx = (scroll_xx < scroll_x ? +1 : scroll_xx > scroll_x ? -1 : 0);
dy = (scroll_yy < scroll_y ? +1 : scroll_yy > scroll_y ? -1 : 0);
InitField(jx, jy, FALSE);
}
+#if 1
+ /* only visually relocate centered player */
+ if (player->index_nr == game.centered_player_nr)
+ DrawRelocatePlayer(player, level.instant_relocation);
+#else
if (player == local_player) /* only visually relocate local player */
DrawRelocatePlayer(player, level.instant_relocation);
+#endif
TestIfPlayerTouchesBadThing(jx, jy);
TestIfPlayerTouchesCustomElement(jx, jy);
Feld[x][y] = EL_EXPLOSION;
GfxElement[x][y] = artwork_element;
+#if 0
+ printf(":: setting gfx(%d,%d) to %d ['%s']\n",
+ x, y, artwork_element, EL_NAME(artwork_element));
+#endif
+
ExplodePhase[x][y] = 1;
ExplodeDelay[x][y] = last_phase;
#endif
#if 1
+#if 1
+ /* this can happen if the player leaves an explosion just in time */
+ if (GfxElement[x][y] == EL_UNDEFINED)
+ GfxElement[x][y] = EL_EMPTY;
+#else
if (GfxElement[x][y] == EL_UNDEFINED)
{
printf("\n\n");
GfxElement[x][y] = EL_EMPTY;
}
+#endif
+
#endif
border_element = Store2[x][y];
int nextx = newx + dx, nexty = newy + dy;
boolean check_collision_again = IN_LEV_FIELD_AND_IS_FREE(nextx, nexty);
- WasJustMoving[newx][newy] = 3;
+ WasJustMoving[newx][newy] = CHECK_DELAY_MOVING;
if (CAN_FALL(element) && direction == MV_DOWN)
- WasJustFalling[newx][newy] = 3;
+ WasJustFalling[newx][newy] = CHECK_DELAY_FALLING;
if ((!CAN_FALL(element) || direction == MV_DOWN) && check_collision_again)
- CheckCollision[newx][newy] = 2;
+ CheckCollision[newx][newy] = CHECK_DELAY_COLLISION;
}
if (DONT_TOUCH(element)) /* object may be nasty to player or others */
if (ScreenMovPos == 0) /* screen currently aligned at tile position */
{
- if (game.centered_to_player != game.centered_to_player_next)
- {
- struct PlayerInfo *player = &stored_player[game.centered_to_player_next];
+ struct PlayerInfo *player;
+ int player_nr = game.centered_player_nr_next;
+ if (game.centered_player_nr_next == -1)
+ player_nr = local_player->index_nr;
+
+ player = &stored_player[player_nr];
+
+ if (!player->active)
+ game.centered_player_nr_next = game.centered_player_nr;
+
+ if (game.centered_player_nr != game.centered_player_nr_next)
+ {
DrawRelocatePlayer(player, setup.quick_switch);
- game.centered_to_player = game.centered_to_player_next;
+ game.centered_player_nr = game.centered_player_nr_next;
}
}
#endif
}
-#if 0
+#if 1
+ if (!options.network && game.centered_player_nr == -1 &&
+ !AllPlayersInSight(player, new_jx, new_jy))
+ return MP_NO_ACTION;
+#else
if (!options.network && !AllPlayersInSight(player, new_jx, new_jy))
return MP_NO_ACTION;
#endif
#if 1
if (moved & MP_MOVING && !ScreenMovPos &&
- player->index_nr == game.centered_to_player)
+ (player->index_nr == game.centered_player_nr ||
+ game.centered_player_nr == -1))
#else
if (moved & MP_MOVING && !ScreenMovPos &&
(player == local_player || !options.network))
if (scroll_x != old_scroll_x || scroll_y != old_scroll_y)
{
-#if 0
+#if 1
+ if (!options.network && game.centered_player_nr == -1 &&
+ !AllPlayersInVisibleScreen())
+ {
+ scroll_x = old_scroll_x;
+ scroll_y = old_scroll_y;
+ }
+ else
+#else
if (!options.network && !AllPlayersInVisibleScreen())
{
scroll_x = old_scroll_x;
dx == +1 ? MV_RIGHT :
dy == -1 ? MV_UP :
dy == +1 ? MV_DOWN : MV_NONE);
+ boolean can_continue_snapping = (level.continuous_snapping &&
+ WasJustFalling[x][y] < CHECK_DELAY_FALLING);
if (player->MovPos != 0 && game.engine_version >= VERSION_IDENT(2,2,0,0))
return FALSE;
return FALSE;
}
+#if USE_NEW_CONTINUOUS_SNAPPING
+ /* prevent snapping with already pressed snap key when not allowed */
+ if (player->is_snapping && !can_continue_snapping)
+ return FALSE;
+#else
if (player->is_snapping)
return FALSE;
+#endif
player->MovDir = snap_direction;
nexty = dropy + GET_DY_FROM_DIR(move_direction);
ChangeCount[dropx][dropy] = 0; /* allow at least one more change */
- CheckCollision[dropx][dropy] = 2;
+ CheckCollision[dropx][dropy] = CHECK_DELAY_COLLISION;
}
player->drop_delay = GET_NEW_DROP_DELAY(drop_element);