diff --git a/theater/conflicttheater.py b/theater/conflicttheater.py index 373eb959..cf611b10 100644 --- a/theater/conflicttheater.py +++ b/theater/conflicttheater.py @@ -15,9 +15,7 @@ from dcs.terrain.terrain import Terrain from .controlpoint import ControlPoint from .landmap import Landmap, load_landmap, poly_contains - -if TYPE_CHECKING: - from . import FrontLine +from .frontline import FrontLine SIZE_TINY = 150 SIZE_SMALL = 600 @@ -128,7 +126,6 @@ class ConflictTheater: return [point for point in self.controlpoints if point.captured] def conflicts(self, from_player=True) -> Iterator[FrontLine]: - from . import FrontLine # Circular import that needs to be resolved. for cp in [x for x in self.controlpoints if x.captured == from_player]: for connected_point in [x for x in cp.connected_points if x.captured != from_player]: yield FrontLine(cp, connected_point) @@ -169,7 +166,7 @@ class ConflictTheater: cp.captured_invert = False return cp - + @staticmethod def from_json(data: Dict[str, Any]) -> ConflictTheater: theaters = { @@ -183,7 +180,6 @@ class ConflictTheater: theater = theaters[data["theater"]] t = theater() cps = {} - for p in data["player_points"]: cp = t.add_json_cp(theater, p) cp.captured = True diff --git a/theater/frontline.py b/theater/frontline.py index aa2852af..f8c5c4d3 100644 --- a/theater/frontline.py +++ b/theater/frontline.py @@ -3,9 +3,10 @@ from __future__ import annotations from dataclasses import dataclass import logging - +import json +from pathlib import Path from itertools import tee -from typing import Tuple, List, Union, Dict +from typing import Tuple, List, Union, Dict, Optional from dcs.mapping import Point @@ -60,18 +61,19 @@ class FrontLine(MissionTarget): Overwrites the entirety of MissionTarget __init__ method to allow for dynamic position calculation. """ + frontline_data: Optional[Dict[str, ComplexFrontLine]] = None def __init__( self, control_point_a: ControlPoint, control_point_b: ControlPoint, - frontline_data: Dict[str, ComplexFrontLine], ) -> None: self.control_point_a = control_point_a self.control_point_b = control_point_b self.segments: List[FrontLineSegment] = [] - self._build_segments(frontline_data) + self._build_segments() self.name = f"Front line {control_point_a}/{control_point_b}" + print(f"FRONTLINE SEGMENTS {len(self.segments)}") @property def position(self): @@ -125,6 +127,24 @@ class FrontLine(MissionTarget): strength_pct = self.control_point_a.base.strength / total_strength return self._adjust_for_min_dist(strength_pct * self.attack_distance) + @classmethod + def load_json_frontlines(cls, terrain_name: str) -> None: + try: + path = Path(f"resources/frontlines/{terrain_name.lower()}.json") + with open(path, "r") as file: + logging.debug(f"Loading frontline from {path}...") + data = json.load(file) + cls.frontline_data = { + frontline: ComplexFrontLine( + data[frontline]["start_cp"], + [Point(i[0], i[1]) for i in data[frontline]["points"]], + ) + for frontline in data + } + print(cls.frontline_data) + except OSError: + logging.warning(f"Unable to load preset frontlines for {terrain_name}") + def _calculate_position(self) -> Point: """ The position where the conflict should occur @@ -132,14 +152,14 @@ class FrontLine(MissionTarget): """ return self.point_from_a(self._position_distance) - def _build_segments(self, frontline_data: Dict[str, ComplexFrontLine]) -> None: + def _build_segments(self) -> None: control_point_ids = "|".join( [str(self.control_point_a.id), str(self.control_point_b.id)] ) reversed_cp_ids = "|".join( [str(self.control_point_b.id), str(self.control_point_a.id)] ) - complex_frontlines = frontline_data + complex_frontlines = FrontLine.frontline_data if (complex_frontlines) and ( (control_point_ids in complex_frontlines) or (reversed_cp_ids in complex_frontlines) diff --git a/theater/start_generator.py b/theater/start_generator.py index eb0252c4..968dc9af 100644 --- a/theater/start_generator.py +++ b/theater/start_generator.py @@ -40,6 +40,7 @@ from theater.theatergroundobject import ( LhaGroundObject, MissileSiteGroundObject, ShipGroundObject, ) +from theater.frontline import FrontLine GroundObjectTemplates = Dict[str, Dict[str, Any]] @@ -73,7 +74,7 @@ class GameGenerator: namegen.reset() self.prepare_theater() self.populate_red_airbases() - + FrontLine.load_json_frontlines(self.theater.terrain.name) game = Game(player_name=self.player, enemy_name=self.enemy, theater=self.theater, @@ -89,7 +90,6 @@ class GameGenerator: def prepare_theater(self) -> None: to_remove = [] - # Auto-capture half the bases if midgame. if self.midgame: control_points = self.theater.controlpoints