fixed bug where player actions were incorrectly mapped in single player mode (also...
[rocksndiamonds.git] / src / game.c
index ae986a08e95addad91474169bd154bc788f41b2b..cc6bcdfc33e33cedb876ec0bd0cb63d3f821c5b1 100644 (file)
@@ -3040,11 +3040,14 @@ static void InitGameEngine()
   for (i = 0; i < MAX_PLAYERS; i++)
     game.snapshot.last_action[i] = 0;
   game.snapshot.changed_action = FALSE;
+  game.snapshot.collected_item = FALSE;
   game.snapshot.mode =
     (strEqual(setup.engine_snapshot_mode, STR_SNAPSHOT_MODE_EVERY_STEP) ?
      SNAPSHOT_MODE_EVERY_STEP :
      strEqual(setup.engine_snapshot_mode, STR_SNAPSHOT_MODE_EVERY_MOVE) ?
-     SNAPSHOT_MODE_EVERY_MOVE : SNAPSHOT_MODE_OFF);
+     SNAPSHOT_MODE_EVERY_MOVE :
+     strEqual(setup.engine_snapshot_mode, STR_SNAPSHOT_MODE_EVERY_COLLECT) ?
+     SNAPSHOT_MODE_EVERY_COLLECT : SNAPSHOT_MODE_OFF);
 }
 
 int get_num_special_action(int element, int action_first, int action_last)
@@ -9494,6 +9497,8 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
     {
       local_player->gems_still_needed = action_arg_number_new;
 
+      game.snapshot.collected_item = TRUE;
+
       game_panel_controls[GAME_PANEL_GEMS].value =
        local_player->gems_still_needed;
 
@@ -11092,8 +11097,11 @@ void GameActions()
     SendToServer_MovePlayer(summarized_player_action);
 #endif
 
+  // summarize all actions at local players mapped input device position
+  // (this allows using different input devices in single player mode)
   if (!options.network && !game.team_mode)
-    local_player->effective_action = summarized_player_action;
+    stored_player[map_player_action[local_player->index_nr]].effective_action =
+      summarized_player_action;
 
   if (tape.recording &&
       setup.team_mode &&
@@ -11129,6 +11137,7 @@ void GameActions()
 #if USE_NEW_PLAYER_ASSIGNMENTS
   // !!! also map player actions in single player mode !!!
   // if (game.team_mode)
+  if (1)
   {
     byte mapped_action[MAX_PLAYERS];
 
@@ -13458,6 +13467,8 @@ static int DigField(struct PlayerInfo *player,
       if (local_player->gems_still_needed < 0)
        local_player->gems_still_needed = 0;
 
+      game.snapshot.collected_item = TRUE;
+
       game_panel_controls[GAME_PANEL_GEMS].value = local_player->gems_still_needed;
 
       DisplayGameControlValues();
@@ -13656,9 +13667,16 @@ static int DigField(struct PlayerInfo *player,
       SCAN_PLAYFIELD(xx, yy)
       {
        if (Feld[xx][yy] == EL_SP_DISK_YELLOW)
+       {
          Bang(xx, yy);
+       }
        else if (Feld[xx][yy] == EL_SP_TERMINAL)
+       {
          Feld[xx][yy] = EL_SP_TERMINAL_ACTIVE;
+
+         ResetGfxAnimation(xx, yy);
+         TEST_DrawLevelField(xx, yy);
+       }
       }
     }
     else if (IS_BELT_SWITCH(element))
@@ -14450,19 +14468,11 @@ void RequestQuitGameExt(boolean skip_request, boolean quick_quit, char *message)
 #endif
     {
       if (quick_quit)
-      {
        FadeSkipNextFadeIn();
 
-       game_status = GAME_MODE_MAIN;
+      game_status = GAME_MODE_MAIN;
 
-       DrawMainMenu();
-      }
-      else
-      {
-       game_status = GAME_MODE_MAIN;
-
-       DrawMainMenu();
-      }
+      DrawMainMenu();
     }
   }
   else         /* continue playing the game */
@@ -14753,9 +14763,12 @@ static boolean SaveEngineSnapshotToListExt(boolean initial_snapshot)
     (initial_snapshot ||
      (game.snapshot.mode == SNAPSHOT_MODE_EVERY_STEP) ||
      (game.snapshot.mode == SNAPSHOT_MODE_EVERY_MOVE &&
-      game.snapshot.changed_action));
+      game.snapshot.changed_action) ||
+     (game.snapshot.mode == SNAPSHOT_MODE_EVERY_COLLECT &&
+      game.snapshot.collected_item));
 
   game.snapshot.changed_action = FALSE;
+  game.snapshot.collected_item = FALSE;
 
   if (game.snapshot.mode == SNAPSHOT_MODE_OFF ||
       tape.quick_resume ||
@@ -15097,6 +15110,7 @@ void GameRedo(int steps)
 
 static void HandleGameButtonsExt(int id, int button)
 {
+  static boolean game_undo_executed = FALSE;
   int steps = BUTTON_STEPSIZE(button);
   boolean handle_game_buttons =
     (game_status == GAME_MODE_PLAYING ||
@@ -15131,6 +15145,9 @@ static void HandleGameButtonsExt(int id, int button)
       }
       else
        TapeTogglePause(TAPE_TOGGLE_MANUAL);
+
+      game_undo_executed = FALSE;
+
       break;
 
     case GAME_CTRL_ID_PLAY:
@@ -15150,6 +15167,17 @@ static void HandleGameButtonsExt(int id, int button)
       break;
 
     case GAME_CTRL_ID_UNDO:
+      // Important: When using "save snapshot when collecting an item" mode,
+      // load last (current) snapshot for first "undo" after pressing "pause"
+      // (else the last-but-one snapshot would be loaded, because the snapshot
+      // pointer already points to the last snapshot when pressing "pause",
+      // which is fine for "every step/move" mode, but not for "every collect")
+      if (game.snapshot.mode == SNAPSHOT_MODE_EVERY_COLLECT &&
+         !game_undo_executed)
+       steps--;
+
+      game_undo_executed = TRUE;
+
       GameUndo(steps);
       break;