added asking before uploading scores and tapes for the first time
[rocksndiamonds.git] / src / game.c
index 0093ee4566fe45623d0efc09c56cad5224d14757..d4cc5ea8e0c5572bb737e62cb9202bdad128b344 100644 (file)
@@ -1106,7 +1106,7 @@ void ContinueMoving(int, int);
 void Bang(int, int);
 void InitMovDir(int, int);
 void InitAmoebaNr(int, int);
-void NewHighScore(int);
+void NewHighScore(int, boolean);
 
 void TestIfGoodThingHitsBadThing(int, int, int);
 void TestIfBadThingHitsGoodThing(int, int, int);
@@ -4717,6 +4717,19 @@ static void LevelSolved_SetFinalGameValues(void)
   game.LevelSolved_CountingHealth = game.health_final;
 }
 
+static void LevelSolved_DisplayFinalGameValues(int time, int score, int health)
+{
+  game.LevelSolved_CountingTime = time;
+  game.LevelSolved_CountingScore = score;
+  game.LevelSolved_CountingHealth = health;
+
+  game_panel_controls[GAME_PANEL_TIME].value = time;
+  game_panel_controls[GAME_PANEL_SCORE].value = score;
+  game_panel_controls[GAME_PANEL_HEALTH].value = health;
+
+  DisplayGameControlValues();
+}
+
 static void LevelSolved(void)
 {
   if (level.game_engine_type == GAME_ENGINE_TYPE_RND &&
@@ -4777,6 +4790,10 @@ void GameWon(void)
     score = score_final = game.score_final;
     health = health_final = game.health_final;
 
+    // update game panel values before (delayed) counting of score (if any)
+    LevelSolved_DisplayFinalGameValues(time, score, health);
+
+    // if level has time score defined, calculate new final game values
     if (time_score > 0)
     {
       int time_final_max = 999;
@@ -4810,18 +4827,13 @@ void GameWon(void)
       game.health_final = health_final;
     }
 
+    // if not counting score after game, immediately update game panel values
     if (level_editor_test_game || !setup.count_score_after_game)
     {
       time = time_final;
       score = score_final;
 
-      game.LevelSolved_CountingTime = time;
-      game.LevelSolved_CountingScore = score;
-
-      game_panel_controls[GAME_PANEL_TIME].value = time;
-      game_panel_controls[GAME_PANEL_SCORE].value = score;
-
-      DisplayGameControlValues();
+      LevelSolved_DisplayFinalGameValues(time, score, health);
     }
 
     if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
@@ -4898,13 +4910,7 @@ void GameWon(void)
       if (time == time_final)
        score = score_final;
 
-      game.LevelSolved_CountingTime = time;
-      game.LevelSolved_CountingScore = score;
-
-      game_panel_controls[GAME_PANEL_TIME].value = time;
-      game_panel_controls[GAME_PANEL_SCORE].value = score;
-
-      DisplayGameControlValues();
+      LevelSolved_DisplayFinalGameValues(time, score, health);
 
       if (time == time_final)
        StopSound(SND_GAME_LEVELTIME_BONUS);
@@ -4930,13 +4936,7 @@ void GameWon(void)
       health += health_count_dir;
       score  += time_score;
 
-      game.LevelSolved_CountingHealth = health;
-      game.LevelSolved_CountingScore = score;
-
-      game_panel_controls[GAME_PANEL_HEALTH].value = health;
-      game_panel_controls[GAME_PANEL_SCORE].value = score;
-
-      DisplayGameControlValues();
+      LevelSolved_DisplayFinalGameValues(time, score, health);
 
       if (health == health_final)
        StopSound(SND_GAME_LEVELTIME_BONUS);
@@ -4965,6 +4965,7 @@ void GameEnd(void)
 {
   // used instead of "level_nr" (needed for network games)
   int last_level_nr = levelset.level_nr;
+  boolean tape_saved = FALSE;
 
   game.LevelSolved_GameEnd = TRUE;
 
@@ -4974,7 +4975,8 @@ void GameEnd(void)
     if (!global.use_envelope_request)
       CloseDoor(DOOR_CLOSE_1);
 
-    SaveTapeChecked_LevelSolved(tape.level_nr);                // ask to save tape
+    // ask to save tape
+    tape_saved = SaveTapeChecked_LevelSolved(tape.level_nr);
 
     // set unique basename for score tape (also saved in high score table)
     strcpy(tape.score_tape_basename, getScoreTapeBasename(setup.player_name));
@@ -5009,7 +5011,7 @@ void GameEnd(void)
   }
 
   // save score and score tape before potentially erasing tape below
-  NewHighScore(last_level_nr);
+  NewHighScore(last_level_nr, tape_saved);
 
   if (setup.increment_levels &&
       level_nr < leveldir_current->last_level &&
@@ -5117,7 +5119,7 @@ static int addScoreEntry(struct ScoreInfo *list, struct ScoreEntry *new_entry,
   return -1;
 }
 
-void NewHighScore(int level_nr)
+void NewHighScore(int level_nr, boolean tape_saved)
 {
   struct ScoreEntry new_entry = {{ 0 }}; // (prevent warning from GCC bug 53119)
   boolean one_per_name = FALSE;
@@ -5132,19 +5134,37 @@ void NewHighScore(int level_nr)
 
   scores.last_added = addScoreEntry(&scores, &new_entry, one_per_name);
 
-  if (scores.last_added >= 0)
-  {
-    SaveScore(level_nr);
+  if (scores.last_added < 0)
+    return;
 
-    // store last added local score entry (before merging server scores)
-    scores.last_added_local = scores.last_added;
-  }
+  SaveScore(level_nr);
 
-  if (game.LevelSolved_SaveTape)
+  // store last added local score entry (before merging server scores)
+  scores.last_added_local = scores.last_added;
+
+  if (!game.LevelSolved_SaveTape)
+    return;
+
+  SaveScoreTape(level_nr);
+
+  if (setup.ask_for_using_api_server)
   {
-    SaveScoreTape(level_nr);
-    SaveServerScore(level_nr);
+    setup.use_api_server =
+      Request("Upload your score and tape to the high score server?", REQ_ASK);
+
+    if (!setup.use_api_server)
+      Request("Not using high score server! Use setup menu to enable again!",
+             REQ_CONFIRM);
+
+    runtime.use_api_server = setup.use_api_server;
+
+    // after asking for using API server once, do not ask again
+    setup.ask_for_using_api_server = FALSE;
+
+    SaveSetup_ServerSetup();
   }
+
+  SaveServerScore(level_nr, tape_saved);
 }
 
 void MergeServerScore(void)
@@ -11711,7 +11731,7 @@ static void GameActionsExt(void)
     Warn("element '%s' caused endless loop in game engine",
         EL_NAME(recursion_loop_element));
 
-    RequestQuitGameExt(FALSE, level_editor_test_game, message);
+    RequestQuitGameExt(program.headless, level_editor_test_game, message);
 
     recursion_loop_detected = FALSE;   // if game should be continued
 
@@ -13968,7 +13988,11 @@ static void TestFieldAfterSnapping(int x, int y, int element, int direction,
   if (level.finish_dig_collect)
   {
     int dig_side = MV_DIR_OPPOSITE(direction);
+    int change_event = (IS_DIGGABLE(element) ? CE_PLAYER_DIGS_X :
+                       CE_PLAYER_COLLECTS_X);
 
+    CheckTriggeredElementChangeByPlayer(x, y, element, change_event,
+                                       player_index_bit, dig_side);
     CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X,
                                        player_index_bit, dig_side);
   }
@@ -16162,12 +16186,18 @@ static void UnmapGameButtonsAtSamePosition(int id)
 
 static void UnmapGameButtonsAtSamePosition_All(void)
 {
-  if (setup.show_snapshot_buttons)
+  if (setup.show_load_save_buttons)
   {
     UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_SAVE);
     UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_PAUSE2);
     UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_LOAD);
   }
+  else if (setup.show_undo_redo_buttons)
+  {
+    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_UNDO);
+    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_PAUSE2);
+    UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_REDO);
+  }
   else
   {
     UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_STOP);
@@ -16180,17 +16210,13 @@ static void UnmapGameButtonsAtSamePosition_All(void)
   }
 }
 
-static void MapGameButtonsAtSamePosition(int id)
+void MapLoadSaveButtons(void)
 {
-  int i;
+  UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_LOAD);
+  UnmapGameButtonsAtSamePosition(GAME_CTRL_ID_SAVE);
 
-  for (i = 0; i < NUM_GAME_BUTTONS; i++)
-    if (i != id &&
-       gamebutton_info[i].pos->x == gamebutton_info[id].pos->x &&
-       gamebutton_info[i].pos->y == gamebutton_info[id].pos->y)
-      MapGadget(game_gadget[i]);
-
-  UnmapGameButtonsAtSamePosition_All();
+  MapGadget(game_gadget[GAME_CTRL_ID_LOAD]);
+  MapGadget(game_gadget[GAME_CTRL_ID_SAVE]);
 }
 
 void MapUndoRedoButtons(void)
@@ -16202,15 +16228,6 @@ void MapUndoRedoButtons(void)
   MapGadget(game_gadget[GAME_CTRL_ID_REDO]);
 }
 
-void UnmapUndoRedoButtons(void)
-{
-  UnmapGadget(game_gadget[GAME_CTRL_ID_UNDO]);
-  UnmapGadget(game_gadget[GAME_CTRL_ID_REDO]);
-
-  MapGameButtonsAtSamePosition(GAME_CTRL_ID_UNDO);
-  MapGameButtonsAtSamePosition(GAME_CTRL_ID_REDO);
-}
-
 void ModifyPauseButtons(void)
 {
   static int ids[] =
@@ -16232,9 +16249,7 @@ static void MapGameButtonsExt(boolean on_tape)
   int i;
 
   for (i = 0; i < NUM_GAME_BUTTONS; i++)
-    if ((!on_tape || gamebutton_info[i].allowed_on_tape) &&
-       i != GAME_CTRL_ID_UNDO &&
-       i != GAME_CTRL_ID_REDO)
+    if (!on_tape || gamebutton_info[i].allowed_on_tape)
       MapGadget(game_gadget[i]);
 
   UnmapGameButtonsAtSamePosition_All();
@@ -16326,6 +16341,8 @@ static void GameUndoRedoExt(void)
   DrawVideoDisplay(VIDEO_STATE_FRAME_ON, FrameCounter);
   DrawVideoDisplay(VIDEO_STATE_1STEP(tape.single_step), 0);
 
+  ModifyPauseButtons();
+
   BackToFront();
 }
 
@@ -16334,8 +16351,12 @@ static void GameUndo(int steps)
   if (!CheckEngineSnapshotList())
     return;
 
+  int tape_property_bits = tape.property_bits;
+
   LoadEngineSnapshot_Undo(steps);
 
+  tape.property_bits |= tape_property_bits | TAPE_PROPERTY_SNAPSHOT;
+
   GameUndoRedoExt();
 }
 
@@ -16344,8 +16365,12 @@ static void GameRedo(int steps)
   if (!CheckEngineSnapshotList())
     return;
 
+  int tape_property_bits = tape.property_bits;
+
   LoadEngineSnapshot_Redo(steps);
 
+  tape.property_bits |= tape_property_bits | TAPE_PROPERTY_SNAPSHOT;
+
   GameUndoRedoExt();
 }