added separate game variable to check for time limit setup option
[rocksndiamonds.git] / src / game.c
index f7392fe400f49bdc4b3b47b8cae54a7c01b98851..e650f4d3a6c6d867fa9573eb1a67a65fdf3f6be1 100644 (file)
@@ -2239,7 +2239,7 @@ static void UpdateGameControlValues(void)
              game_sp.time_played :
              level.game_engine_type == GAME_ENGINE_TYPE_MM ?
              game_mm.energy_left :
-             game.no_time_limit ? TimePlayed : TimeLeft);
+             game.no_level_time_limit ? TimePlayed : TimeLeft);
   int score = (game.LevelSolved ?
               game.LevelSolved_CountingScore :
               level.game_engine_type == GAME_ENGINE_TYPE_EM ?
@@ -3818,7 +3818,8 @@ void InitGame(void)
 
   game.panel.active = TRUE;
 
-  game.no_time_limit = (level.time == 0);
+  game.no_level_time_limit = (level.time == 0);
+  game.time_limit = (setup.time_limit);
 
   game.yamyam_content_nr = 0;
   game.robot_wheel_active = FALSE;
@@ -4726,7 +4727,7 @@ void InitAmoebaNr(int x, int y)
 
 static void LevelSolved_SetFinalGameValues(void)
 {
-  game.time_final = (game.no_time_limit ? TimePlayed : TimeLeft);
+  game.time_final = (game.no_level_time_limit ? TimePlayed : TimeLeft);
   game.score_time_final = (level.use_step_counter ? TimePlayed :
                           TimePlayed * FRAMES_PER_SECOND + TimeFrames);
 
@@ -4835,7 +4836,7 @@ void GameWon(void)
        time_final = 0;
        time_frames = time_frames_left;
       }
-      else if (game.no_time_limit && TimePlayed < time_final_max)
+      else if (game.no_level_time_limit && TimePlayed < time_final_max)
       {
        time_final = time_final_max;
        time_frames = time_frames_final_max - time_frames_played;
@@ -4997,7 +4998,7 @@ void GameEnd(void)
 
   game.LevelSolved_GameEnd = TRUE;
 
-  if (game.LevelSolved_SaveTape)
+  if (game.LevelSolved_SaveTape && !score_info_tape_play)
   {
     // make sure that request dialog to save tape does not open door again
     if (!global.use_envelope_request)
@@ -5013,7 +5014,7 @@ void GameEnd(void)
   // if no tape is to be saved, close both doors simultaneously
   CloseDoor(DOOR_CLOSE_ALL);
 
-  if (level_editor_test_game)
+  if (level_editor_test_game || score_info_tape_play)
   {
     SetGameStatus(GAME_MODE_MAIN);
 
@@ -5050,6 +5051,9 @@ void GameEnd(void)
 
     if (setup.auto_play_next_level)
     {
+      scores.continue_playing = TRUE;
+      scores.next_level_nr = level_nr;
+
       LoadLevel(level_nr);
 
       SaveLevelSetup_SeriesInfo();
@@ -5062,9 +5066,7 @@ void GameEnd(void)
 
     DrawHallOfFame(last_level_nr);
   }
-  else if (setup.auto_play_next_level && setup.increment_levels &&
-          last_level_nr < leveldir_current->last_level &&
-          !network_playing)
+  else if (scores.continue_playing)
   {
     StartGameActions(network.enabled, setup.autorecord, level.random_seed);
   }
@@ -5151,7 +5153,8 @@ static int addScoreEntry(struct ScoreInfo *list, struct ScoreEntry *new_entry,
     }
   }
 
-  return -1;
+  // special case: new score is beyond the last high score list position
+  return MAX_SCORE_ENTRIES;
 }
 
 void NewHighScore(int level_nr, boolean tape_saved)
@@ -5169,6 +5172,19 @@ void NewHighScore(int level_nr, boolean tape_saved)
 
   scores.last_added = addScoreEntry(&scores, &new_entry, one_per_name);
 
+  if (scores.last_added >= MAX_SCORE_ENTRIES)
+  {
+    scores.last_added = MAX_SCORE_ENTRIES - 1;
+    scores.force_last_added = TRUE;
+
+    scores.entry[scores.last_added] = new_entry;
+
+    // store last added local score entry (before merging server scores)
+    scores.last_added_local = scores.last_added;
+
+    return;
+  }
+
   if (scores.last_added < 0)
     return;
 
@@ -10212,7 +10228,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
 
        DisplayGameControlValues();
 
-       if (!TimeLeft && setup.time_limit)
+       if (!TimeLeft && game.time_limit)
          for (i = 0; i < MAX_PLAYERS; i++)
            KillPlayer(&stored_player[i]);
       }
@@ -11622,18 +11638,18 @@ static void CheckLevelTime_StepCounter(void)
   {
     TimeLeft--;
 
-    if (TimeLeft <= 10 && setup.time_limit && !game.LevelSolved)
+    if (TimeLeft <= 10 && game.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 && !game.LevelSolved)
+    if (!TimeLeft && game.time_limit && !game.LevelSolved)
       for (i = 0; i < MAX_PLAYERS; i++)
        KillPlayer(&stored_player[i]);
   }
-  else if (game.no_time_limit && !game.all_players_gone)
+  else if (game.no_level_time_limit && !game.all_players_gone)
   {
     game_panel_controls[GAME_PANEL_TIME].value = TimePlayed;
 
@@ -11671,7 +11687,7 @@ static void CheckLevelTime(void)
       {
        TimeLeft--;
 
-       if (TimeLeft <= 10 && setup.time_limit)
+       if (TimeLeft <= 10 && game.time_limit)
          PlaySound(SND_GAME_RUNNING_OUT_OF_TIME);
 
        /* this does not make sense: game_panel_controls[GAME_PANEL_TIME].value
@@ -11679,7 +11695,7 @@ static void CheckLevelTime(void)
 
        game_panel_controls[GAME_PANEL_TIME].value = TimeLeft;
 
-       if (!TimeLeft && setup.time_limit)
+       if (!TimeLeft && game.time_limit)
        {
          if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
            game_em.lev->killed_out_of_time = TRUE;
@@ -11688,12 +11704,12 @@ static void CheckLevelTime(void)
              KillPlayer(&stored_player[i]);
        }
       }
-      else if (game.no_time_limit && !game.all_players_gone)
+      else if (game.no_level_time_limit && !game.all_players_gone)
       {
        game_panel_controls[GAME_PANEL_TIME].value = TimePlayed;
       }
 
-      game_em.lev->time = (game.no_time_limit ? TimePlayed : TimeLeft);
+      game_em.lev->time = (game.no_level_time_limit ? TimePlayed : TimeLeft);
     }
 
     if (tape.recording || tape.playing)
@@ -13238,9 +13254,6 @@ void ScrollPlayer(struct PlayerInfo *player, int mode)
       }
     }
 
-    player->last_jx = jx;
-    player->last_jy = jy;
-
     if (Tile[jx][jy] == EL_EXIT_OPEN ||
        Tile[jx][jy] == EL_EM_EXIT_OPEN ||
        Tile[jx][jy] == EL_EM_EXIT_OPENING ||
@@ -13258,6 +13271,9 @@ void ScrollPlayer(struct PlayerInfo *player, int mode)
        LevelSolved();
     }
 
+    player->last_jx = jx;
+    player->last_jy = jy;
+
     // this breaks one level: "machine", level 000
     {
       int move_direction = player->MovDir;
@@ -14867,7 +14883,7 @@ static int DigField(struct PlayerInfo *player,
       if (level.time > 0 || level.use_time_orb_bug)
       {
        TimeLeft += level.time_orb_time;
-       game.no_time_limit = FALSE;
+       game.no_level_time_limit = FALSE;
 
        game_panel_controls[GAME_PANEL_TIME].value = TimeLeft;
 
@@ -15677,9 +15693,10 @@ void RequestQuitGameExt(boolean skip_request, boolean quick_quit, char *message)
     {
       // prevent short reactivation of overlay buttons while closing door
       SetOverlayActive(FALSE);
+      UnmapGameButtons();
 
       // door may still be open due to skipped or envelope style request
-      CloseDoor(DOOR_CLOSE_1);
+      CloseDoor(score_info_tape_play ? DOOR_CLOSE_ALL : DOOR_CLOSE_1);
     }
 
     if (network.enabled)
@@ -15712,7 +15729,7 @@ void RequestQuitGame(boolean escape_key_pressed)
   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);
+                         quick_quit || score_info_tape_play);
 
   RequestQuitGameExt(skip_request, quick_quit,
                     "Do you really want to quit the game?");
@@ -16284,6 +16301,10 @@ void CreateGameButtons(void)
     int y = (is_touch_button ? pos->y : GDI_ACTIVE_POS(pos->y));
     int id = i;
 
+    // do not use touch buttons if overlay touch buttons are disabled
+    if (is_touch_button && !setup.touch.overlay_buttons)
+      continue;
+
     if (gfx->bitmap == NULL)
     {
       game_gadget[id] = NULL;