+ return can_move;
+
+ StorePlayer[jx][jy] = 0;
+ player->last_jx = jx;
+ player->last_jy = jy;
+ jx = player->jx = new_jx;
+ jy = player->jy = new_jy;
+ StorePlayer[jx][jy] = player->element_nr;
+
+ player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * 7*TILEX/8;
+
+ ScrollFigure(player, SCROLL_INIT);
+
+ return MF_MOVING;
+}
+
+boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
+{
+ int jx = player->jx, jy = player->jy;
+ int old_jx = jx, old_jy = jy;
+ int moved = MF_NO_ACTION;
+
+ if (player->gone || (!dx && !dy))
+ return FALSE;
+
+ if (!FrameReached(&player->move_delay, MoveSpeed) && !tape.playing)
+ return FALSE;
+
+ if (player->MovPos)
+ {
+ /* should only happen if pre-1.2 tape recordings are played */
+ /* this is only for backward compatibility */
+
+#if DEBUG
+ printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.2 LEVEL TAPES.\n");
+#endif
+
+ while (player->MovPos)
+ {
+ ScrollFigure(player, SCROLL_GO_ON);
+ ScrollScreen(NULL, SCROLL_GO_ON);
+ FrameCounter++;
+ DrawAllPlayers();
+ BackToFront();
+ }
+ }
+
+ if (player->last_move_dir & (MV_LEFT | MV_RIGHT))
+ {
+ if (!(moved |= MoveFigureOneStep(player, 0, dy, dx, dy)))
+ moved |= MoveFigureOneStep(player, dx, 0, dx, dy);
+ }
+ else
+ {
+ if (!(moved |= MoveFigureOneStep(player, dx, 0, dx, dy)))
+ moved |= MoveFigureOneStep(player, 0, dy, dx, dy);
+ }
+
+ jx = player->jx;
+ jy = player->jy;
+
+ if (moved & MF_MOVING && !ScreenMovPos &&
+ (player == local_player || !options.network))
+ {
+ int old_scroll_x = scroll_x, old_scroll_y = scroll_y;
+ int offset = (setup.scroll_delay ? 3 : 0);
+
+ if (!IN_VIS_FIELD(SCREENX(jx), SCREENY(jy)))
+ {
+ /* actual player has left the screen -- scroll in that direction */
+ if (jx != old_jx) /* player has moved horizontally */
+ scroll_x += (jx - old_jx);
+ else /* player has moved vertically */
+ scroll_y += (jy - old_jy);
+ }
+ else
+ {
+ if (jx != old_jx) /* player has moved horizontally */
+ {
+ if ((player->MovDir == MV_LEFT && scroll_x > jx-MIDPOSX+offset) ||
+ (player->MovDir == MV_RIGHT && scroll_x < jx-MIDPOSX-offset))
+ scroll_x = jx-MIDPOSX + (scroll_x < jx-MIDPOSX ? -offset : +offset);
+
+ /* don't scroll over playfield boundaries */
+ if (scroll_x < -1 || scroll_x > lev_fieldx - SCR_FIELDX + 1)
+ scroll_x = (scroll_x < -1 ? -1 : lev_fieldx - SCR_FIELDX + 1);
+
+ /* don't scroll more than one field at a time */
+ scroll_x = old_scroll_x + SIGN(scroll_x - old_scroll_x);
+
+ /* don't scroll against the player's moving direction */
+ if ((player->MovDir == MV_LEFT && scroll_x > old_scroll_x) ||
+ (player->MovDir == MV_RIGHT && scroll_x < old_scroll_x))
+ scroll_x = old_scroll_x;
+ }
+ else /* player has moved vertically */
+ {
+ if ((player->MovDir == MV_UP && scroll_y > jy-MIDPOSY+offset) ||
+ (player->MovDir == MV_DOWN && scroll_y < jy-MIDPOSY-offset))
+ scroll_y = jy-MIDPOSY + (scroll_y < jy-MIDPOSY ? -offset : +offset);
+
+ /* don't scroll over playfield boundaries */
+ if (scroll_y < -1 || scroll_y > lev_fieldy - SCR_FIELDY + 1)
+ scroll_y = (scroll_y < -1 ? -1 : lev_fieldy - SCR_FIELDY + 1);
+
+ /* don't scroll more than one field at a time */
+ scroll_y = old_scroll_y + SIGN(scroll_y - old_scroll_y);
+
+ /* don't scroll against the player's moving direction */
+ if ((player->MovDir == MV_UP && scroll_y > old_scroll_y) ||
+ (player->MovDir == MV_DOWN && scroll_y < old_scroll_y))
+ scroll_y = old_scroll_y;
+ }
+ }
+
+ if (scroll_x != old_scroll_x || scroll_y != old_scroll_y)
+ {
+ if (!options.network && !AllPlayersInVisibleScreen())
+ {
+ scroll_x = old_scroll_x;
+ scroll_y = old_scroll_y;
+ }
+ else
+ {
+ ScrollScreen(player, SCROLL_INIT);
+ ScrollLevel(old_scroll_x - scroll_x, old_scroll_y - scroll_y);
+ }
+ }
+ }
+
+ if (!(moved & MF_MOVING) && !player->Pushing)
+ player->Frame = 0;
+ else
+ player->Frame = (player->Frame + 1) % 4;
+
+ if (moved & MF_MOVING)
+ {
+ if (old_jx != jx && old_jy == jy)
+ player->MovDir = (old_jx < jx ? MV_RIGHT : MV_LEFT);
+ else if (old_jx == jx && old_jy != jy)
+ player->MovDir = (old_jy < jy ? MV_DOWN : MV_UP);