added message request if local score tape not found
[rocksndiamonds.git] / src / tape.c
index 0a63b79578c0aee5f24dacbd32c1fe7348d1a4e4..5033507342b4f8029d893737555ce8ccf5972cab 100644 (file)
@@ -18,6 +18,8 @@
 #include "files.h"
 #include "network.h"
 #include "anim.h"
+#include "api.h"
+
 
 #define DEBUG_TAPE_WHEN_PLAYING                        FALSE
 
@@ -985,7 +987,7 @@ byte *TapePlayAction(void)
 
   if (tape.pause_before_end)  // stop some seconds before end of tape
   {
-    if (TapeTime > tape.length_seconds - TAPE_PAUSE_SECONDS_BEFORE_DEATH)
+    if (TapeTime > (int)tape.length_seconds - TAPE_PAUSE_SECONDS_BEFORE_DEATH)
     {
       TapeStopWarpForward();
       TapeTogglePause(TAPE_TOGGLE_MANUAL);
@@ -1088,6 +1090,27 @@ void TapeStop(void)
   }
 }
 
+static void TapeStopGameOrTape(boolean stop_game)
+{
+  if (score_info_tape_play || (!tape.playing && stop_game))
+    RequestQuitGame(FALSE);
+  else
+    TapeStop();
+}
+
+void TapeStopGame(void)
+{
+  if (game_status == GAME_MODE_MAIN)
+    return;
+
+  TapeStopGameOrTape(TRUE);
+}
+
+void TapeStopTape(void)
+{
+  TapeStopGameOrTape(FALSE);
+}
+
 unsigned int GetTapeLengthFrames(void)
 {
   unsigned int tape_length_frames = 0;
@@ -1244,6 +1267,69 @@ void TapeQuickLoad(void)
   }
 }
 
+static boolean checkRestartGame(char *message)
+{
+  if (game_status == GAME_MODE_MAIN)
+    return TRUE;
+
+  if (!hasStartedNetworkGame())
+    return FALSE;
+
+  if (level_editor_test_game)
+    return TRUE;
+
+  if (game.all_players_gone)
+    return TRUE;
+
+  if (!setup.ask_on_quit_game)
+    return TRUE;
+
+  if (Request(message, REQ_ASK | REQ_STAY_CLOSED))
+    return TRUE;
+
+  OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
+
+  return FALSE;
+}
+
+void TapeRestartGame(void)
+{
+  if (score_info_tape_play)
+  {
+    TapeStartGamePlaying();
+
+    return;
+  }
+
+  if (!checkRestartGame("Restart game?"))
+    return;
+
+  StartGameActions(network.enabled, setup.autorecord, level.random_seed);
+}
+
+void TapeReplayAndPauseBeforeEnd(void)
+{
+  if (score_info_tape_play)
+    return;
+
+  if (TAPE_IS_EMPTY(tape) && !tape.recording)
+  {
+    Request("No tape for this level!", REQ_CONFIRM);
+
+    return;
+  }
+
+  if (!checkRestartGame("Replay game and pause before end?"))
+    return;
+
+  TapeStop();
+  TapeStartGamePlaying();
+  TapeStartWarpForward(AUTOPLAY_MODE_WARP_NO_DISPLAY);
+
+  tape.pause_before_end = TRUE;
+  tape.quick_resume = TRUE;
+}
+
 boolean hasSolutionTape(void)
 {
   boolean tape_file_exists = fileExists(getSolutionTapeFilename(level_nr));
@@ -1292,6 +1378,88 @@ boolean PlaySolutionTape(void)
   return TRUE;
 }
 
+static boolean PlayScoreTape_WaitForDownload(void)
+{
+  unsigned int download_delay = 0;
+  unsigned int download_delay_value = 10000;
+
+  ResetDelayCounter(&download_delay);
+
+  // wait for score tape to be successfully downloaded (and fail on timeout)
+  while (!server_scores.tape_downloaded)
+  {
+    if (DelayReached(&download_delay, download_delay_value))
+      return FALSE;
+
+    UPDATE_BUSY_STATE_NOT_LOADING();
+
+    Delay(20);
+  }
+
+  return TRUE;
+}
+
+boolean PlayScoreTape(int entry_nr)
+{
+  struct ScoreEntry *entry = &scores.entry[entry_nr];
+  char *tape_filename = getScoreTapeFilename(entry->tape_basename, level_nr);
+  boolean download_tape = (!fileExists(tape_filename));
+
+  if (download_tape && entry->id == -1)
+  {
+    FadeSkipNextFadeIn();
+
+    Request("Cannot find score tape!", REQ_CONFIRM);
+
+    return FALSE;
+  }
+
+  server_scores.tape_downloaded = FALSE;
+
+  if (download_tape)
+    ApiGetScoreTapeAsThread(level_nr, entry->id, entry->tape_basename);
+
+  SetGameStatus(GAME_MODE_PLAYING);
+
+  FadeOut(REDRAW_FIELD);
+
+  if (download_tape && !PlayScoreTape_WaitForDownload())
+  {
+    SetGameStatus(GAME_MODE_SCOREINFO);
+    ClearField();
+
+    Request("Cannot download score tape from score server!", REQ_CONFIRM);
+
+    return FALSE;
+  }
+
+  if (!TAPE_IS_STOPPED(tape))
+    TapeStop();
+
+  // if tape recorder already contains a tape, remove it without asking
+  TapeErase();
+
+  LoadScoreTape(entry->tape_basename, level_nr);
+
+  if (TAPE_IS_EMPTY(tape))
+  {
+    SetGameStatus(GAME_MODE_SCOREINFO);
+    ClearField();
+
+    Request("Cannot load score tape for this level!", REQ_CONFIRM);
+
+    return FALSE;
+  }
+
+  FadeSkipNextFadeOut();
+
+  TapeStartGamePlaying();
+
+  score_info_tape_play = TRUE;
+
+  return TRUE;
+}
+
 static boolean checkTapesFromSameLevel(struct TapeInfo *t1, struct TapeInfo *t2)
 {
   return (strEqual(t1->level_identifier, t2->level_identifier) &&
@@ -2340,7 +2508,7 @@ static void HandleTapeButtonsExt(int id)
       break;
 
     case TAPE_CTRL_ID_STOP:
-      TapeStop();
+      TapeStopTape();
 
       break;