X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=9127a1b6a5be48bc22c593b6ff728b8a02269192;hb=4ed68b54ed9bed72d87eac4dd7b117fc4b8022d6;hp=3a9a773661e15b791d594d1ea7d7e48c17a67989;hpb=93be8597e0d42202c1c862a31950ed1d22d7f59a;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 3a9a7736..9127a1b6 100644 --- a/src/game.c +++ b/src/game.c @@ -1835,6 +1835,29 @@ static void InitPlayerField(int x, int y, int element, boolean init_game) } } +static void InitFieldForEngine_RND(int x, int y) +{ + int element = Tile[x][y]; + + // convert BD engine elements to corresponding R'n'D engine elements + element = (element == EL_BD_EMPTY ? EL_EMPTY : + element == EL_BD_PLAYER ? EL_PLAYER_1 : + element == EL_BD_INBOX ? EL_PLAYER_1 : + element == EL_BD_SAND ? EL_SAND : + element == EL_BD_STEELWALL ? EL_STEELWALL : + element == EL_BD_EXIT_CLOSED ? EL_EXIT_CLOSED : + element == EL_BD_EXIT_OPEN ? EL_EXIT_OPEN : + element); + + Tile[x][y] = element; +} + +static void InitFieldForEngine(int x, int y) +{ + if (level.game_engine_type == GAME_ENGINE_TYPE_RND) + InitFieldForEngine_RND(x, y); +} + static void InitField(int x, int y, boolean init_game) { int element = Tile[x][y]; @@ -4007,6 +4030,8 @@ void InitGame(void) SCAN_PLAYFIELD(x, y) { + InitFieldForEngine(x, y); + if (emulate_bd && !IS_BD_ELEMENT(Tile[x][y])) emulate_bd = FALSE; if (emulate_sp && !IS_SP_ELEMENT(Tile[x][y])) @@ -4881,6 +4906,31 @@ static void LevelSolved(void) LevelSolved_SetFinalGameValues(); } +static boolean AdvanceToNextLevel(void) +{ + if (setup.increment_levels && + level_nr < leveldir_current->last_level && + !network_playing) + { + level_nr++; // advance to next level + TapeErase(); // start with empty tape + + if (setup.auto_play_next_level) + { + scores.continue_playing = TRUE; + scores.next_level_nr = level_nr; + + LoadLevel(level_nr); + + SaveLevelSetup_SeriesInfo(); + } + + return TRUE; + } + + return FALSE; +} + void GameWon(void) { static int time_count_steps; @@ -5112,7 +5162,11 @@ void GameEnd(void) int last_level_nr = levelset.level_nr; boolean tape_saved = FALSE; - game.LevelSolved_GameEnd = TRUE; + // Important note: This function is not only called after "GameWon()", but also after + // "game over" (if automatically asking for restarting the game is disabled in setup) + + if (game.LevelSolved) + game.LevelSolved_GameEnd = TRUE; if (game.LevelSolved_SaveTape && !score_info_tape_play) { @@ -5139,7 +5193,7 @@ void GameEnd(void) return; } - if (!game.LevelSolved_SaveScore) + if (!game.GamePlayed || (!game.LevelSolved_SaveScore && !level.bd_intermission)) { SetGameStatus(GAME_MODE_MAIN); @@ -5156,27 +5210,13 @@ void GameEnd(void) } // save score and score tape before potentially erasing tape below - NewHighScore(last_level_nr, tape_saved); + if (game.LevelSolved_SaveScore) + NewHighScore(last_level_nr, tape_saved); - if (setup.increment_levels && - level_nr < leveldir_current->last_level && - !network_playing) - { - level_nr++; // advance to next level - TapeErase(); // start with empty tape + // increment and load next level (if possible and not configured otherwise) + AdvanceToNextLevel(); - if (setup.auto_play_next_level) - { - scores.continue_playing = TRUE; - scores.next_level_nr = level_nr; - - LoadLevel(level_nr); - - SaveLevelSetup_SeriesInfo(); - } - } - - if (scores.last_added >= 0 && setup.show_scores_after_game) + if (game.LevelSolved_SaveScore && scores.last_added >= 0 && setup.show_scores_after_game) { SetGameStatus(GAME_MODE_SCORES); @@ -16249,7 +16289,17 @@ static void RequestRestartGame(void) int request_mode = (has_started_game ? REQ_ASK : REQ_CONFIRM); int door_state = DOOR_CLOSE_1; - if (Request(message, request_mode | REQ_STAY_OPEN) && has_started_game) + boolean restart_wanted = (Request(message, request_mode | REQ_STAY_OPEN) && has_started_game); + + // if no restart wanted, continue with next level for BD style intermission levels + if (!restart_wanted && !level_editor_test_game && level.bd_intermission) + { + boolean success = AdvanceToNextLevel(); + + restart_wanted = (success && setup.auto_play_next_level); + } + + if (restart_wanted) { CloseDoor(door_state);