+
+ if (IS_WALKABLE(element))
+ {
+ PlaySoundLevelElementAction(x, y, player->element_nr, ACTION_MOVING);
+ break;
+ }
+ else if (IS_DIGGABLE(element))
+ {
+ RemoveField(x, y);
+
+ if (mode != DF_SNAP)
+ {
+ GfxElement[x][y] =
+ (CAN_BE_CRUMBLED(element) ? EL_SAND : GFX_ELEMENT(element));
+ player->is_digging = TRUE;
+ }
+
+ PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING);
+
+ break;
+ }
+ else if (IS_COLLECTIBLE(element))
+ {
+ RemoveField(x, y);
+
+ if (mode != DF_SNAP)
+ {
+ GfxElement[x][y] = element;
+ player->is_collecting = TRUE;
+ }
+
+ RaiseScoreElement(element);
+
+ PlaySoundLevelElementAction(x, y, element, ACTION_COLLECTING);
+
+ CheckTriggeredElementChange(element, CE_OTHER_COLLECTING);
+
+ break;
+ }
+ else if (IS_PUSHABLE(element))
+ {
+ if (mode == DF_SNAP && element != EL_BD_ROCK)
+ return MF_NO_ACTION;
+
+ if (CAN_FALL(element) && dy)
+ return MF_NO_ACTION;
+
+ if (CAN_FALL(element) && IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1) &&
+ !(element == EL_SPRING && use_spring_bug))
+ return MF_NO_ACTION;
+
+ if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING)
+ return MF_NO_ACTION;
+
+ if (!player->Pushing &&
+ game.engine_version >= RELEASE_IDENT(2,2,0,7))
+ player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+
+ player->Pushing = TRUE;
+
+ if (!(IN_LEV_FIELD(x + dx, y + dy) &&
+ (IS_FREE(x + dx, y + dy) ||
+ (Feld[x + dx][y + dy] == EL_SOKOBAN_FIELD_EMPTY &&
+ IS_SB_ELEMENT(element)))))
+ return MF_NO_ACTION;
+
+ if (!checkDiagonalPushing(player, x, y, real_dx, real_dy))
+ return MF_NO_ACTION;
+
+ if (player->push_delay == 0) /* new pushing; restart delay */
+ player->push_delay = FrameCounter;
+
+ if (!FrameReached(&player->push_delay, player->push_delay_value) &&
+ !(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
+ element != EL_SPRING && element != EL_BALLOON)
+ return MF_NO_ACTION;
+
+ if (IS_SB_ELEMENT(element))
+ {
+ if (element == EL_SOKOBAN_FIELD_FULL)
+ {
+ Back[x][y] = EL_SOKOBAN_FIELD_EMPTY;
+ local_player->sokobanfields_still_needed++;
+ }
+
+ if (Feld[x + dx][y + dy] == EL_SOKOBAN_FIELD_EMPTY)
+ {
+ Back[x + dx][y + dy] = EL_SOKOBAN_FIELD_EMPTY;
+ local_player->sokobanfields_still_needed--;
+ }
+
+ Feld[x][y] = EL_SOKOBAN_OBJECT;
+
+ if (Back[x][y] == Back[x + dx][y + dy])
+ PlaySoundLevelAction(x, y, ACTION_PUSHING);
+ else if (Back[x][y] != 0)
+ PlaySoundLevelElementAction(x, y, EL_SOKOBAN_FIELD_FULL,
+ ACTION_EMPTYING);
+ else
+ PlaySoundLevelElementAction(x + dx, y + dy, EL_SOKOBAN_FIELD_EMPTY,
+ ACTION_FILLING);
+
+ if (local_player->sokobanfields_still_needed == 0 &&
+ game.emulation == EMU_SOKOBAN)
+ {
+ player->LevelSolved = player->GameOver = TRUE;
+ PlaySoundLevel(x, y, SND_GAME_SOKOBAN_SOLVING);
+ }
+ }
+ else
+ PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
+
+ InitMovingField(x, y, move_direction);
+
+ if (mode == DF_SNAP)
+ ContinueMoving(x, y);
+ else
+ MovPos[x][y] = (dx != 0 ? dx : dy);
+
+ Pushed[x][y] = TRUE;
+ Pushed[x + dx][y + dy] = TRUE;
+
+ if (game.engine_version < RELEASE_IDENT(2,2,0,7))
+ player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+
+ CheckTriggeredElementChange(element, CE_OTHER_PUSHING);
+ CheckPlayerElementChange(x, y, element, CE_PUSHED_BY_PLAYER);
+
+ break;
+ }
+ else
+ {
+ CheckPlayerElementChange(x, y, element, CE_PRESSED_BY_PLAYER);
+ }
+