X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=d835b19f8cb9b11be758fdfe42502cc754d138d6;hb=1856b32b9d7b3c80596362cf7a3dd8e032cd83fc;hp=83b0c1f3cb94a98767c21573f527dcdaac6ee1c2;hpb=7a5e1469c7df6a9f07717f5a9c0e7b8d9a796a2c;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 83b0c1f3..d835b19f 100644 --- a/src/game.c +++ b/src/game.c @@ -1840,13 +1840,13 @@ 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 = (element == EL_BDX_EMPTY ? EL_EMPTY : + element == EL_BDX_PLAYER ? EL_PLAYER_1 : + element == EL_BDX_INBOX ? EL_PLAYER_1 : + element == EL_BDX_SAND_1 ? EL_SAND : + element == EL_BDX_STEELWALL ? EL_STEELWALL : + element == EL_BDX_EXIT_CLOSED ? EL_EXIT_CLOSED : + element == EL_BDX_EXIT_OPEN ? EL_EXIT_OPEN : element); Tile[x][y] = element; @@ -2286,7 +2286,7 @@ static void UpdateGameControlValues(void) int time = (game.LevelSolved ? game.LevelSolved_CountingTime : level.game_engine_type == GAME_ENGINE_TYPE_BD ? - game_bd.time_played : + game_bd.time_left : level.game_engine_type == GAME_ENGINE_TYPE_EM ? game_em.lev->time : level.game_engine_type == GAME_ENGINE_TYPE_SP ? @@ -3676,6 +3676,9 @@ void InitGame(void) else { SetGameStatus(GAME_MODE_PLAYING); + + // do not cover screen before fading out when starting from main menu + game_bd.cover_screen = FALSE; } if (level_editor_test_game) @@ -3974,8 +3977,6 @@ void InitGame(void) game.explosions_delayed = TRUE; - game.envelope_active = FALSE; - // special case: set custom artwork setting to initial value game.use_masked_elements = game.use_masked_elements_initial; @@ -4622,6 +4623,8 @@ void InitGame(void) game.restart_level = FALSE; game.request_active = FALSE; + game.envelope_active = FALSE; + game.any_door_active = FALSE; if (level.game_engine_type == GAME_ENGINE_TYPE_MM) InitGameActions_MM(); @@ -4859,9 +4862,10 @@ void InitAmoebaNr(int x, int y) static void LevelSolved_SetFinalGameValues(void) { - game.time_final = (level.game_engine_type == GAME_ENGINE_TYPE_BD ? game_bd.time_played : + game.time_final = (level.game_engine_type == GAME_ENGINE_TYPE_BD ? game_bd.time_left : game.no_level_time_limit ? TimePlayed : TimeLeft); - game.score_time_final = (level.use_step_counter ? TimePlayed : + game.score_time_final = (level.game_engine_type == GAME_ENGINE_TYPE_BD ? game_bd.frames_played : + level.use_step_counter ? TimePlayed : TimePlayed * FRAMES_PER_SECOND + TimeFrames); game.score_final = (level.game_engine_type == GAME_ENGINE_TYPE_BD ? game_bd.score : @@ -4906,7 +4910,7 @@ static void LevelSolved(void) LevelSolved_SetFinalGameValues(); } -static void AdvanceToNextLevel(void) +static boolean AdvanceToNextLevel(void) { if (setup.increment_levels && level_nr < leveldir_current->last_level && @@ -4924,7 +4928,11 @@ static void AdvanceToNextLevel(void) SaveLevelSetup_SeriesInfo(); } + + return TRUE; } + + return FALSE; } void GameWon(void) @@ -5157,8 +5165,30 @@ void GameEnd(void) // used instead of "level_nr" (needed for network games) int last_level_nr = levelset.level_nr; boolean tape_saved = FALSE; + boolean game_over = checkGameFailed(); + + // 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) + + // do not handle game end if game over and automatically asking for game restart + if (game_over && setup.ask_on_game_over) + { + // (this is a special case: player pressed "return" key or fire button shortly before + // automatically asking to restart the game, so skip asking and restart right away) + + CloseDoor(DOOR_CLOSE_1); + + StartGameActions(network.enabled, setup.autorecord, level.random_seed); + + return; + } - game.LevelSolved_GameEnd = TRUE; + // do not handle game end if request dialog is already active + if (checkRequestActive()) + return; + + if (game.LevelSolved) + game.LevelSolved_GameEnd = TRUE; if (game.LevelSolved_SaveTape && !score_info_tape_play) { @@ -5185,7 +5215,7 @@ void GameEnd(void) return; } - if (!game.LevelSolved_SaveScore) + if (!game.GamePlayed || (!game.LevelSolved_SaveScore && !level.bd_intermission)) { SetGameStatus(GAME_MODE_MAIN); @@ -5202,12 +5232,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); // increment and load next level (if possible and not configured otherwise) AdvanceToNextLevel(); - 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); @@ -11805,6 +11836,9 @@ static void CheckLevelTime(void) // if last second running, wait for native engine time to exactly reach zero if (getTimeLeft_BD() == 1 && TimeLeft == 1) TimeFrames = frames_per_second - 1; + + // needed to store final time after solving game (before counting down remaining time) + SetTimeFrames_BD(TimePlayed * FRAMES_PER_SECOND + TimeFrames); } if (TimeFrames >= frames_per_second) @@ -15757,10 +15791,10 @@ static int getSoundEffect_BD(int element_bd, int sample) case GD_S_DIAMOND_FALLING_8: nr = (sample == GD_S_DIAMOND_FALLING_RANDOM ? GetSimpleRandom(8) : sample - GD_S_DIAMOND_FALLING_1); - sound_effect = SND_BD_DIAMOND_FALLING_RANDOM_1 + nr; + sound_effect = SND_BDX_DIAMOND_FALLING_RANDOM_1 + nr; if (getSoundInfoEntryFilename(sound_effect) == NULL) - sound_effect = SND_BD_DIAMOND_FALLING; + sound_effect = SND_BDX_DIAMOND_FALLING; break; case GD_S_DIAMOND_IMPACT_RANDOM: @@ -15774,10 +15808,10 @@ static int getSoundEffect_BD(int element_bd, int sample) case GD_S_DIAMOND_IMPACT_8: nr = (sample == GD_S_DIAMOND_IMPACT_RANDOM ? GetSimpleRandom(8) : sample - GD_S_DIAMOND_IMPACT_1); - sound_effect = SND_BD_DIAMOND_IMPACT_RANDOM_1 + nr; + sound_effect = SND_BDX_DIAMOND_IMPACT_RANDOM_1 + nr; if (getSoundInfoEntryFilename(sound_effect) == NULL) - sound_effect = SND_BD_DIAMOND_IMPACT; + sound_effect = SND_BDX_DIAMOND_IMPACT; break; case GD_S_FLYING_DIAMOND_FALLING_RANDOM: @@ -15791,10 +15825,10 @@ static int getSoundEffect_BD(int element_bd, int sample) case GD_S_FLYING_DIAMOND_FALLING_8: nr = (sample == GD_S_FLYING_DIAMOND_FALLING_RANDOM ? GetSimpleRandom(8) : sample - GD_S_FLYING_DIAMOND_FALLING_1); - sound_effect = SND_BD_FLYING_DIAMOND_FALLING_RANDOM_1 + nr; + sound_effect = SND_BDX_FLYING_DIAMOND_FALLING_RANDOM_1 + nr; if (getSoundInfoEntryFilename(sound_effect) == NULL) - sound_effect = SND_BD_FLYING_DIAMOND_FALLING; + sound_effect = SND_BDX_FLYING_DIAMOND_FALLING; break; case GD_S_FLYING_DIAMOND_IMPACT_RANDOM: @@ -15808,10 +15842,10 @@ static int getSoundEffect_BD(int element_bd, int sample) case GD_S_FLYING_DIAMOND_IMPACT_8: nr = (sample == GD_S_FLYING_DIAMOND_IMPACT_RANDOM ? GetSimpleRandom(8) : sample - GD_S_FLYING_DIAMOND_IMPACT_1); - sound_effect = SND_BD_FLYING_DIAMOND_IMPACT_RANDOM_1 + nr; + sound_effect = SND_BDX_FLYING_DIAMOND_IMPACT_RANDOM_1 + nr; if (getSoundInfoEntryFilename(sound_effect) == NULL) - sound_effect = SND_BD_FLYING_DIAMOND_IMPACT; + sound_effect = SND_BDX_FLYING_DIAMOND_IMPACT; break; case GD_S_TIMEOUT_0: @@ -15837,7 +15871,7 @@ static int getSoundEffect_BD(int element_bd, int sample) break; case GD_S_AMOEBA_MAGIC: - sound_effect = SND_BD_AMOEBA_OTHER; + sound_effect = SND_BDX_AMOEBA_1_OTHER; break; case GD_S_FINISHED: @@ -15854,7 +15888,7 @@ static int getSoundEffect_BD(int element_bd, int sample) void PlayLevelSound_BD(int xx, int yy, int element_bd, int sample) { - int element = (element_bd > -1 ? map_element_BD_to_RND(element_bd) : 0); + int element = (element_bd > -1 ? map_element_BD_to_RND_game(element_bd) : 0); int sound_effect = getSoundEffect_BD(element, sample); int sound_action = getSoundAction_BD(sample); boolean is_loop_sound = IS_LOOP_SOUND(sound_effect); @@ -15878,7 +15912,7 @@ void PlayLevelSound_BD(int xx, int yy, int element_bd, int sample) void StopSound_BD(int element_bd, int sample) { - int element = (element_bd > -1 ? map_element_BD_to_RND(element_bd) : 0); + int element = (element_bd > -1 ? map_element_BD_to_RND_game(element_bd) : 0); int sound_effect = getSoundEffect_BD(element, sample); if (sound_effect != SND_UNDEFINED) @@ -15887,7 +15921,7 @@ void StopSound_BD(int element_bd, int sample) boolean isSoundPlaying_BD(int element_bd, int sample) { - int element = (element_bd > -1 ? map_element_BD_to_RND(element_bd) : 0); + int element = (element_bd > -1 ? map_element_BD_to_RND_game(element_bd) : 0); int sound_effect = getSoundEffect_BD(element, sample); if (sound_effect != SND_UNDEFINED) @@ -16280,7 +16314,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); @@ -16324,7 +16368,7 @@ boolean CheckRestartGame(void) } // do not ask to play again if request dialog is already active - if (game.request_active) + if (checkRequestActive()) return FALSE; // do not ask to play again if request dialog already handled @@ -16393,6 +16437,11 @@ boolean checkGameEnded(void) return (checkGameSolved() || checkGameFailed()); } +boolean checkRequestActive(void) +{ + return (game.request_active || game.envelope_active || game.any_door_active); +} + // ---------------------------------------------------------------------------- // random generator functions