From f2eec530dba984845ef81a33ab214ff9fca8962e Mon Sep 17 00:00:00 2001 From: Raffson Date: Fri, 27 Dec 2024 23:00:53 +0100 Subject: [PATCH] Load landmap data on the fly Avoids saving unnecessary data to the save-file --- changelog.md | 1 + game/theater/conflicttheater.py | 32 ++++++++++++++++++++++++++++---- game/theater/theaterloader.py | 11 ++++------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/changelog.md b/changelog.md index 3c5a898d..768ec51e 100644 --- a/changelog.md +++ b/changelog.md @@ -43,6 +43,7 @@ * **[Autoplanner]** Plan Air-to-Air Escorts for AWACS & Tankers * **[Package Planning]** Ability to plan recovery tanker flights * **[Modding]** Support for Bandit's cloud presets mod (v15) +* **[UX]** Reduce size of save-file by loading landmap data on the fly, which also implies no new campaign needs to be started to benefit from an updated landmap ## Fixes * **[UI/UX]** A-10A flights can be edited again diff --git a/game/theater/conflicttheater.py b/game/theater/conflicttheater.py index 98ed275c..af4f2daa 100644 --- a/game/theater/conflicttheater.py +++ b/game/theater/conflicttheater.py @@ -2,7 +2,8 @@ from __future__ import annotations import math from datetime import timezone -from typing import Iterator, List, Optional, TYPE_CHECKING, Tuple +from pathlib import Path +from typing import Iterator, List, Optional, TYPE_CHECKING, Tuple, Any from uuid import UUID from dcs.mapping import Point @@ -12,7 +13,7 @@ from shapely import geometry, ops from .daytimemap import DaytimeMap from .frontline import FrontLine from .iadsnetwork.iadsnetwork import IadsNetwork -from .landmap import Landmap, poly_contains +from .landmap import poly_contains, load_landmap from .seasonalconditions import SeasonalConditions from ..utils import Heading @@ -21,24 +22,47 @@ if TYPE_CHECKING: from .theatergroundobject import TheaterGroundObject +THEATER_RESOURCE_DIR = Path("resources/theaters") + + class ConflictTheater: iads_network: IadsNetwork def __init__( self, terrain: Terrain, - landmap: Landmap | None, + landmap_path: Path, time_zone: timezone, seasonal_conditions: SeasonalConditions, daytime_map: DaytimeMap, ) -> None: self.terrain = terrain - self.landmap = landmap + self.landmap_path = landmap_path + self.landmap = load_landmap(self.landmap_path) self.timezone = time_zone self.seasonal_conditions = seasonal_conditions self.daytime_map = daytime_map self.controlpoints: list[ControlPoint] = [] + def __setstate__(self, state: dict[str, Any]) -> None: + if "landmap_path" not in state: + state["landmap_path"] = self.landmap_path_for_terrain_name( + state["terrain"].name + ) + self.__dict__ = state + self.landmap = load_landmap(self.landmap_path) + + def __getstate__(self) -> dict[str, Any]: + self.landmap = None + return self.__dict__ + + @staticmethod + def landmap_path_for_terrain_name(terrain_name: str) -> Path: + for theater_dir in THEATER_RESOURCE_DIR.iterdir(): + if theater_dir.name.lower() in terrain_name.lower(): + return theater_dir / "landmap.p" + raise RuntimeError(f"Could not determine landmap path for {terrain_name}") + def add_controlpoint(self, point: ControlPoint) -> None: self.controlpoints.append(point) diff --git a/game/theater/theaterloader.py b/game/theater/theaterloader.py index dc8d1e0c..576a1f94 100644 --- a/game/theater/theaterloader.py +++ b/game/theater/theaterloader.py @@ -22,9 +22,8 @@ from dcs.terrain import ( Iraq, ) -from .conflicttheater import ConflictTheater +from .conflicttheater import ConflictTheater, THEATER_RESOURCE_DIR from .daytimemap import DaytimeMap -from .landmap import load_landmap from .seasonalconditions import Season, SeasonalConditions, WeatherTypeChances ALL_TERRAINS = [ @@ -83,15 +82,13 @@ class TurbulenceData: class TheaterLoader: - THEATER_RESOURCE_DIR = Path("resources/theaters") - def __init__(self, name: str) -> None: self.name = name - self.descriptor_path = self.THEATER_RESOURCE_DIR / self.name / "info.yaml" + self.descriptor_path = THEATER_RESOURCE_DIR / self.name / "info.yaml" @classmethod def each(cls) -> Iterator[ConflictTheater]: - for theater_dir in cls.THEATER_RESOURCE_DIR.iterdir(): + for theater_dir in THEATER_RESOURCE_DIR.iterdir(): yield TheaterLoader(theater_dir.name).load() @property @@ -114,7 +111,7 @@ class TheaterLoader: data = yaml.safe_load(descriptor_file) return ConflictTheater( TERRAINS_BY_NAME[data.get("pydcs_name", data["name"])], - load_landmap(self.landmap_path), + self.landmap_path, datetime.timezone(datetime.timedelta(hours=data["timezone"])), self._load_seasonal_conditions(data["climate"]), self._load_daytime_map(data["daytime"]),