}
game_panel_controls[GAME_PANEL_SCORE].value = score;
- game_panel_controls[GAME_PANEL_HIGHSCORE].value = highscore[0].Score;
+ game_panel_controls[GAME_PANEL_HIGHSCORE].value = scores.entry[0].score;
game_panel_controls[GAME_PANEL_TIME].value = time;
game.switchgate_pos = 0;
game.wind_direction = level.wind_direction_initial;
+ game.time_final = 0;
+ game.score_time_final = 0;
+
game.score = 0;
game.score_final = 0;
game.LevelSolved = TRUE;
game.GameOver = TRUE;
-
- game.score_final = (level.game_engine_type == GAME_ENGINE_TYPE_EM ?
- game_em.lev->score :
- level.game_engine_type == GAME_ENGINE_TYPE_MM ?
- game_mm.score :
- game.score);
- game.health_final = (level.game_engine_type == GAME_ENGINE_TYPE_MM ?
- MM_HEALTH(game_mm.laser_overload_value) :
- game.health);
-
- game.LevelSolved_CountingTime = (game.no_time_limit ? TimePlayed : TimeLeft);
- game.LevelSolved_CountingScore = game.score_final;
- game.LevelSolved_CountingHealth = game.health_final;
}
void GameWon(void)
if (local_player->active && local_player->MovPos)
return;
+ game.time_final = (game.no_time_limit ? TimePlayed : TimeLeft);
+ game.score_time_final = (level.use_step_counter ? TimePlayed :
+ TimePlayed * FRAMES_PER_SECOND + TimeFrames);
+
+ game.score_final = (level.game_engine_type == GAME_ENGINE_TYPE_EM ?
+ game_em.lev->score :
+ level.game_engine_type == GAME_ENGINE_TYPE_MM ?
+ game_mm.score :
+ game.score);
+
+ game.health_final = (level.game_engine_type == GAME_ENGINE_TYPE_MM ?
+ MM_HEALTH(game_mm.laser_overload_value) :
+ game.health);
+
+ game.LevelSolved_CountingTime = game.time_final;
+ game.LevelSolved_CountingScore = game.score_final;
+ game.LevelSolved_CountingHealth = game.health_final;
+
game.LevelSolved_GameWon = TRUE;
game.LevelSolved_SaveTape = tape.recording;
game.LevelSolved_SaveScore = !tape.playing;
game_over_delay_2 = FRAMES_PER_SECOND / 2; // delay before counting health
game_over_delay_3 = FRAMES_PER_SECOND; // delay before ending the game
- time = time_final = (game.no_time_limit ? TimePlayed : TimeLeft);
+ time = time_final = game.time_final;
score = score_final = game.score_final;
health = health_final = game.health_final;
if (time_score > 0)
{
+ int time_final_max = 999;
+ int time_frames_final_max = time_final_max * FRAMES_PER_SECOND;
int time_frames = 0;
+ int time_frames_left = TimeLeft * FRAMES_PER_SECOND - TimeFrames;
+ int time_frames_played = TimePlayed * FRAMES_PER_SECOND + TimeFrames;
if (TimeLeft > 0)
{
time_final = 0;
- time_frames = TimeLeft * FRAMES_PER_SECOND - TimeFrames;
+ time_frames = time_frames_left;
}
- else if (game.no_time_limit && TimePlayed < 999)
+ else if (game.no_time_limit && TimePlayed < time_final_max)
{
- time_final = 999;
- time_frames = (999 - TimePlayed) * FRAMES_PER_SECOND - TimeFrames;
+ time_final = time_final_max;
+ time_frames = time_frames_final_max - time_frames_played;
}
score_final += time_score * time_frames / FRAMES_PER_SECOND + 0.5;
CloseDoor(DOOR_CLOSE_1);
SaveTapeChecked_LevelSolved(tape.level_nr); // ask to save tape
+
+ // set unique basename for score tape (also saved in high score table)
+ strcpy(tape.score_tape_basename, getScoreTapeBasename(setup.player_name));
}
// if no tape is to be saved, close both doors simultaneously
LoadScore(level_nr);
if (strEqual(setup.player_name, EMPTY_PLAYER_NAME) ||
- game.score_final < highscore[MAX_SCORE_ENTRIES - 1].Score)
+ game.score_final < scores.entry[MAX_SCORE_ENTRIES - 1].score)
return -1;
for (k = 0; k < MAX_SCORE_ENTRIES; k++)
{
- if (game.score_final > highscore[k].Score)
+ struct ScoreEntry *entry = &scores.entry[k];
+ boolean score_is_better = (game.score_final > entry->score);
+ boolean score_is_equal = (game.score_final == entry->score);
+ boolean time_is_better = (game.score_time_final < entry->time);
+ boolean time_is_equal = (game.score_time_final == entry->time);
+ boolean better_by_score = (score_is_better ||
+ (score_is_equal && time_is_better));
+ boolean better_by_time = (time_is_better ||
+ (time_is_equal && score_is_better));
+ boolean is_better = (level.rate_time_over_score ? better_by_time :
+ better_by_score);
+ boolean entry_is_empty = (entry->score == 0 &&
+ entry->time == 0);
+
+ if (is_better || entry_is_empty)
{
// player has made it to the hall of fame
if (one_score_entry_per_name)
{
for (l = k; l < MAX_SCORE_ENTRIES; l++)
- if (strEqual(setup.player_name, highscore[l].Name))
+ if (strEqual(setup.player_name, scores.entry[l].name))
m = l;
if (m == k) // player's new highscore overwrites his old one
for (l = m; l > k; l--)
{
- strcpy(highscore[l].Name, highscore[l - 1].Name);
- highscore[l].Score = highscore[l - 1].Score;
+ strcpy(scores.entry[l].name, scores.entry[l - 1].name);
+ scores.entry[l].score = scores.entry[l - 1].score;
+ scores.entry[l].time = scores.entry[l - 1].time;
}
}
put_into_list:
- strncpy(highscore[k].Name, setup.player_name, MAX_PLAYER_NAME_LEN);
- highscore[k].Name[MAX_PLAYER_NAME_LEN] = '\0';
- highscore[k].Score = game.score_final;
+ strcpy(entry->tape_basename, tape.score_tape_basename);
+ strncpy(entry->name, setup.player_name, MAX_PLAYER_NAME_LEN);
+ entry->name[MAX_PLAYER_NAME_LEN] = '\0';
+ entry->score = game.score_final;
+ entry->time = game.score_time_final;
position = k;
break;
}
else if (one_score_entry_per_name &&
- !strncmp(setup.player_name, highscore[k].Name,
- MAX_PLAYER_NAME_LEN))
+ !strncmp(setup.player_name, entry->name, MAX_PLAYER_NAME_LEN))
break; // player already there with a higher score
}
- if (position >= 0)
+ if (position >= 0)
+ {
+ SaveScoreTape(level_nr);
SaveScore(level_nr);
+ }
return position;
}
RemovePlayer(player);
}
- if (!game.LevelSolved && level.use_step_counter)
+ if (level.use_step_counter)
{
int i;
{
TimeLeft--;
- if (TimeLeft <= 10 && setup.time_limit)
+ if (TimeLeft <= 10 && setup.time_limit && !game.LevelSolved)
PlaySound(SND_GAME_RUNNING_OUT_OF_TIME);
game_panel_controls[GAME_PANEL_TIME].value = TimeLeft;
DisplayGameControlValues();
- if (!TimeLeft && setup.time_limit)
+ if (!TimeLeft && setup.time_limit && !game.LevelSolved)
for (i = 0; i < MAX_PLAYERS; i++)
KillPlayer(&stored_player[i]);
}
{
if (skip_request || Request(message, REQ_ASK | REQ_STAY_CLOSED))
{
- // closing door required in case of envelope style request dialogs
- if (!skip_request)
+ if (!quick_quit)
{
// prevent short reactivation of overlay buttons while closing door
SetOverlayActive(FALSE);
+ // door may still be open due to skipped or envelope style request
CloseDoor(DOOR_CLOSE_1);
}
}
}
-void RequestQuitGame(boolean ask_if_really_quit)
+void RequestQuitGame(boolean escape_key_pressed)
{
- boolean quick_quit = (!ask_if_really_quit || level_editor_test_game);
- boolean skip_request = game.all_players_gone || quick_quit;
+ boolean ask_on_escape = (setup.ask_on_escape && setup.ask_on_quit_game);
+ boolean quick_quit = ((escape_key_pressed && !ask_on_escape) ||
+ level_editor_test_game);
+ boolean skip_request = (game.all_players_gone || !setup.ask_on_quit_game ||
+ quick_quit);
RequestQuitGameExt(skip_request, quick_quit,
"Do you really want to quit the game?");
if (tape.playing)
TapeStop();
else
- RequestQuitGame(TRUE);
+ RequestQuitGame(FALSE);
break;