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;
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 ?
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)
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;
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();
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 :
LevelSolved_SetFinalGameValues();
}
-static void AdvanceToNextLevel(void)
+static boolean AdvanceToNextLevel(void)
{
if (setup.increment_levels &&
level_nr < leveldir_current->last_level &&
SaveLevelSetup_SeriesInfo();
}
+
+ return TRUE;
}
+
+ return FALSE;
}
void GameWon(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)
{
return;
}
- if (!game.LevelSolved_SaveScore)
+ if (!game.GamePlayed || (!game.LevelSolved_SaveScore && !level.bd_intermission))
{
SetGameStatus(GAME_MODE_MAIN);
}
// 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);
// 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)
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:
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:
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:
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:
break;
case GD_S_AMOEBA_MAGIC:
- sound_effect = SND_BD_AMOEBA_OTHER;
+ sound_effect = SND_BDX_AMOEBA_1_OTHER;
break;
case GD_S_FINISHED:
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);
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)
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)
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);
}
// 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
return (checkGameSolved() || checkGameFailed());
}
+boolean checkRequestActive(void)
+{
+ return (game.request_active || game.envelope_active || game.any_door_active);
+}
+
// ----------------------------------------------------------------------------
// random generator functions