mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Save-compat changes to allow loading Liberation saves
May be incomplete, some discrepancies in naming may still exist, but at least Kerbo's campaign can be loaded.
This commit is contained in:
parent
aaaa9847b1
commit
3b745c43eb
@ -31,6 +31,16 @@ def weapons_migrator(name: str) -> str:
|
|||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def weapons_migrator_lib(name: str) -> str:
|
||||||
|
# Splitting this from our own migrations
|
||||||
|
if "KH" in name:
|
||||||
|
return "Kh" + name[2:]
|
||||||
|
migration_map = {}
|
||||||
|
while name in migration_map:
|
||||||
|
name = migration_map[name]
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Weapon:
|
class Weapon:
|
||||||
"""Wrapper for DCS weapons."""
|
"""Wrapper for DCS weapons."""
|
||||||
@ -153,7 +163,9 @@ class WeaponGroup:
|
|||||||
|
|
||||||
def __setstate__(self, state: dict[str, Any]) -> None:
|
def __setstate__(self, state: dict[str, Any]) -> None:
|
||||||
# Update any existing models with new data on load.
|
# Update any existing models with new data on load.
|
||||||
updated = WeaponGroup.named(weapons_migrator(state["name"]))
|
name = weapons_migrator(state["name"])
|
||||||
|
name = weapons_migrator_lib(name)
|
||||||
|
updated = WeaponGroup.named(name)
|
||||||
state.update(updated.__dict__)
|
state.update(updated.__dict__)
|
||||||
self.__dict__.update(state)
|
self.__dict__.update(state)
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from dcs.countries import countries_by_name
|
from dcs.countries import countries_by_name
|
||||||
@ -18,8 +19,9 @@ def try_set_attr(obj: Any, attr_name: str, val: Any = None) -> None:
|
|||||||
|
|
||||||
|
|
||||||
class Migrator:
|
class Migrator:
|
||||||
def __init__(self, game: Game):
|
def __init__(self, game: Game, is_liberation: bool):
|
||||||
self.game = game
|
self.game = game
|
||||||
|
self.is_liberation = is_liberation
|
||||||
self._migrate_game()
|
self._migrate_game()
|
||||||
|
|
||||||
def _migrate_game(self) -> None:
|
def _migrate_game(self) -> None:
|
||||||
@ -62,6 +64,10 @@ class Migrator:
|
|||||||
for p in c.ato.packages:
|
for p in c.ato.packages:
|
||||||
try_set_attr(p, "custom_name")
|
try_set_attr(p, "custom_name")
|
||||||
try_set_attr(p, "frequency")
|
try_set_attr(p, "frequency")
|
||||||
|
if self.is_liberation and isinstance(p.time_over_target, datetime):
|
||||||
|
p.time_over_target = (
|
||||||
|
p.time_over_target - self.game.conditions.start_time
|
||||||
|
)
|
||||||
|
|
||||||
def _update_control_points(self) -> None:
|
def _update_control_points(self) -> None:
|
||||||
for cp in self.game.theater.controlpoints:
|
for cp in self.game.theater.controlpoints:
|
||||||
|
|||||||
@ -17,6 +17,11 @@ _dcs_saved_game_folder: Optional[str] = None
|
|||||||
|
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
|
class DummyObject:
|
||||||
|
def __setstate__(self, state):
|
||||||
|
self.__dict__.update(state)
|
||||||
|
|
||||||
|
|
||||||
class MigrationUnpickler(pickle.Unpickler):
|
class MigrationUnpickler(pickle.Unpickler):
|
||||||
"""Custom unpickler to migrate campaign save-files for when components have been moved"""
|
"""Custom unpickler to migrate campaign save-files for when components have been moved"""
|
||||||
def find_class(self, module: Any, name: str) -> Any:
|
def find_class(self, module: Any, name: str) -> Any:
|
||||||
@ -52,6 +57,8 @@ class MigrationUnpickler(pickle.Unpickler):
|
|||||||
return Thunderstorm
|
return Thunderstorm
|
||||||
if name == "Hipico":
|
if name == "Hipico":
|
||||||
return dcs.terrain.falklands.airports.Hipico_Flying_Club
|
return dcs.terrain.falklands.airports.Hipico_Flying_Club
|
||||||
|
if name in ["SaveManager", "SaveGameBundle"]:
|
||||||
|
return DummyObject
|
||||||
return super().find_class(module, name)
|
return super().find_class(module, name)
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
|
|||||||
@ -326,7 +326,8 @@ class QLiberationWindow(QMainWindow):
|
|||||||
|
|
||||||
def migrate_game(self, game, path):
|
def migrate_game(self, game, path):
|
||||||
if game:
|
if game:
|
||||||
Migrator(game)
|
is_liberation = ".liberation" in path
|
||||||
|
Migrator(game, is_liberation)
|
||||||
else:
|
else:
|
||||||
relative_path = Path(path)
|
relative_path = Path(path)
|
||||||
QMessageBox.critical(
|
QMessageBox.critical(
|
||||||
|
|||||||
@ -17,6 +17,7 @@ price: 20
|
|||||||
role: Attack
|
role: Attack
|
||||||
variants:
|
variants:
|
||||||
Ka-50 Hokum III: {}
|
Ka-50 Hokum III: {}
|
||||||
|
Ka-50 Hokum (Blackshark 3): {} # for compatibility with Liberation
|
||||||
radios:
|
radios:
|
||||||
intra_flight: R-800L1
|
intra_flight: R-800L1
|
||||||
inter_flight: R-800L1
|
inter_flight: R-800L1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user