mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Checkpoint game before sim, auto-revert on abort.
An alternative to https://github.com/dcs-liberation/dcs_liberation/pull/2891 that I ended up liking much better (I had assumed some part of the UI would fail or at least look terrible with this approach, but it seems to work quite well). On by default now since it's far less frightening than the previous thing. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2735.
This commit is contained in:
@@ -25,6 +25,7 @@ class SaveGameBundle:
|
||||
MANUAL_SAVE_NAME = "player.liberation"
|
||||
LAST_TURN_SAVE_NAME = "last_turn.liberation"
|
||||
START_OF_TURN_SAVE_NAME = "start_of_turn.liberation"
|
||||
PRE_SIM_CHECKPOINT_SAVE_NAME = "pre_sim_checkpoint.liberation"
|
||||
|
||||
def __init__(self, bundle_path: Path) -> None:
|
||||
self.bundle_path = bundle_path
|
||||
@@ -58,6 +59,19 @@ class SaveGameBundle:
|
||||
game, self.START_OF_TURN_SAVE_NAME, copy_from=self
|
||||
)
|
||||
|
||||
def save_pre_sim_checkpoint(self, game: Game) -> None:
|
||||
"""Writes the save file for the state before beginning simulation.
|
||||
|
||||
This save is the state of the game after the player presses "TAKE OFF", but
|
||||
before the fast-forward simulation begins. It is not practical to rewind, but
|
||||
players commonly will want to cancel and continue planning after pressing that
|
||||
button, so we make a checkpoint that we can reload on abort.
|
||||
"""
|
||||
with logged_duration("Saving pre-sim checkpoint"):
|
||||
self._update_bundle_member(
|
||||
game, self.PRE_SIM_CHECKPOINT_SAVE_NAME, copy_from=self
|
||||
)
|
||||
|
||||
def load_player(self) -> Game:
|
||||
"""Loads the save manually created by the player via save/save-as."""
|
||||
return self._load_from(self.MANUAL_SAVE_NAME)
|
||||
@@ -70,6 +84,10 @@ class SaveGameBundle:
|
||||
"""Loads the save automatically created at the end of the last turn."""
|
||||
return self._load_from(self.LAST_TURN_SAVE_NAME)
|
||||
|
||||
def load_pre_sim_checkpoint(self) -> Game:
|
||||
"""Loads the save automatically created before the simulation began."""
|
||||
return self._load_from(self.PRE_SIM_CHECKPOINT_SAVE_NAME)
|
||||
|
||||
def _load_from(self, name: str) -> Game:
|
||||
with ZipFile(self.bundle_path) as zip_bundle:
|
||||
with zip_bundle.open(name, "r") as save:
|
||||
|
||||
@@ -51,6 +51,10 @@ class SaveManager:
|
||||
with self._save_bundle_context() as bundle:
|
||||
bundle.save_start_of_turn(self.game)
|
||||
|
||||
def save_pre_sim_checkpoint(self) -> None:
|
||||
with self._save_bundle_context() as bundle:
|
||||
bundle.save_pre_sim_checkpoint(self.game)
|
||||
|
||||
def set_loaded_from(self, bundle: SaveGameBundle) -> None:
|
||||
"""Reconfigures this save manager based on the loaded game.
|
||||
|
||||
@@ -81,6 +85,9 @@ class SaveManager:
|
||||
self.last_saved_bundle = previous_saved_bundle
|
||||
raise
|
||||
|
||||
def load_pre_sim_checkpoint(self) -> Game:
|
||||
return self.default_save_bundle.load_pre_sim_checkpoint()
|
||||
|
||||
@staticmethod
|
||||
def load_last_turn(bundle_path: Path) -> Game:
|
||||
return SaveGameBundle(bundle_path).load_last_turn()
|
||||
|
||||
@@ -324,17 +324,15 @@ class Settings:
|
||||
"modifications."
|
||||
),
|
||||
)
|
||||
reset_simulation_on_abort: bool = boolean_option(
|
||||
"Reset mission to pre-take off conditions on abort (experimental)",
|
||||
reload_pre_sim_checkpoint_on_abort: bool = boolean_option(
|
||||
"Reset mission to pre-take off conditions on abort",
|
||||
page=MISSION_GENERATOR_PAGE,
|
||||
section=GAMEPLAY_SECTION,
|
||||
default=False,
|
||||
default=True,
|
||||
detail=(
|
||||
"If enabled, the fast-forward effects will be rewound when aborting take "
|
||||
"off. <strong>DO NOT USE THIS WITH AUTO-RESOLVE ENABLED.</strong> Lost "
|
||||
"aircraft will not be recovered. This option is experimental and may not "
|
||||
"work. It is always safer to reload your save after abort when using fast-"
|
||||
"forward."
|
||||
"If enabled, the game will automatically reload a pre-take off save when "
|
||||
"aborting take off. If this is disabled, you will need to manually re-load "
|
||||
"your game after aborting take off."
|
||||
),
|
||||
)
|
||||
player_mission_interrupts_sim_at: Optional[StartType] = choices_option(
|
||||
|
||||
@@ -69,12 +69,9 @@ class AircraftSimulation:
|
||||
for flight in self.iter_flights():
|
||||
flight.state.reinitialize(now)
|
||||
|
||||
def reset(self, events: GameUpdateEvents | None = None) -> None:
|
||||
if events is None:
|
||||
events = GameUpdateEvents()
|
||||
def reset(self) -> None:
|
||||
for flight in self.iter_flights():
|
||||
flight.set_state(Uninitialized(flight, self.game.settings))
|
||||
events.update_flight(flight)
|
||||
self.combats = []
|
||||
|
||||
def iter_flights(self) -> Iterator[Flight]:
|
||||
|
||||
@@ -36,17 +36,10 @@ class GameLoop:
|
||||
def elapsed_time(self) -> timedelta:
|
||||
return self.sim.time - self.game.conditions.start_time
|
||||
|
||||
def reset(self) -> None:
|
||||
self.pause()
|
||||
self.events = GameUpdateEvents()
|
||||
self.sim.reset(self.events)
|
||||
self.send_update(rate_limit=False)
|
||||
self.started = False
|
||||
self.completed = False
|
||||
|
||||
def start(self) -> None:
|
||||
if self.started:
|
||||
raise RuntimeError("Cannot start game loop because it has already started")
|
||||
self.game.save_manager.save_pre_sim_checkpoint()
|
||||
self.started = True
|
||||
self.sim.begin_simulation()
|
||||
|
||||
|
||||
@@ -33,11 +33,6 @@ class MissionSimulation:
|
||||
self.completed = False
|
||||
self.time = self.game.conditions.start_time
|
||||
|
||||
def reset(self, events: GameUpdateEvents) -> None:
|
||||
self.completed = False
|
||||
self.time = self.game.conditions.start_time
|
||||
self.aircraft_simulation.reset(events)
|
||||
|
||||
def begin_simulation(self) -> None:
|
||||
self.time = self.game.conditions.start_time
|
||||
self.aircraft_simulation.begin_simulation()
|
||||
|
||||
Reference in New Issue
Block a user