Changed helipad generation structure as to not impact "Game" object, as suggested by Dan.

This commit is contained in:
Khopa 2021-08-07 01:05:57 +02:00
parent 5412487178
commit 5e715daded
6 changed files with 44 additions and 82 deletions

View File

@ -1,25 +0,0 @@
from __future__ import annotations
from typing import Optional
from dcs import Point
from dcs.unitgroup import StaticGroup
from game.point_with_heading import PointWithHeading
from game.utils import Heading
class Helipad(PointWithHeading):
def __init__(self) -> None:
super(Helipad, self).__init__()
self.heading = Heading.from_degrees(0)
self.occupied = False
self.static_unit: Optional[StaticGroup] = None
@staticmethod
def from_point(point: Point, heading: Heading) -> Helipad:
h = Helipad()
h.x = point.x
h.y = point.y
h.heading = heading
return h

View File

@ -375,6 +375,7 @@ class Operation:
cls.laser_code_registry,
cls.unit_map,
air_support=cls.airsupportgen.air_support,
helipads=cls.groundobjectgen.helipads,
)
cls.airgen.clear_parking_slots()

View File

@ -56,7 +56,6 @@ from .landmap import Landmap, load_landmap, poly_contains
from .latlon import LatLon
from .projections import TransverseMercator
from .seasonalconditions import SeasonalConditions
from ..helipad import Helipad
from ..point_with_heading import PointWithHeading
from ..positioned import Positioned
from ..profiling import logged_duration
@ -482,7 +481,7 @@ class MizCampaignLoader:
for static in self.helipads:
closest, distance = self.objective_info(static)
closest.helipads.append(
Helipad.from_point(
PointWithHeading.from_point(
static.position, Heading.from_degrees(static.units[0].heading)
)
)

View File

@ -49,7 +49,6 @@ from .theatergroundobject import (
)
from ..dcs.aircrafttype import AircraftType
from ..dcs.groundunittype import GroundUnitType
from ..helipad import Helipad
from ..utils import nautical_miles
from ..weather import Conditions
@ -307,7 +306,7 @@ class ControlPoint(MissionTarget, ABC):
self.at = at
self.connected_objectives: List[TheaterGroundObject[Any]] = []
self.preset_locations = PresetLocations()
self.helipads: List[Helipad] = []
self.helipads: List[PointWithHeading] = []
# TODO: Should be Airbase specific.
self.size = size
@ -400,22 +399,6 @@ class ControlPoint(MissionTarget, ABC):
"""
return len(self.helipads) > 0
@property
def has_free_helipad(self) -> bool:
"""
Returns true if cp has a free helipad
"""
return not all(h.occupied for h in self.helipads)
def get_free_helipad(self) -> Optional[Helipad]:
"""
Returns the first free additional helipad
"""
for h in self.helipads:
if not h.occupied:
return h
return None
def can_recruit_ground_units(self, game: Game) -> bool:
"""Returns True if this control point is capable of recruiting ground units."""
if not self.can_deploy_ground_units:

View File

@ -68,7 +68,6 @@ from game import db
from game.data.weapons import Pylon, WeaponType as WeaponTypeEnum
from game.dcs.aircrafttype import AircraftType
from game.factions.faction import Faction
from game.helipad import Helipad
from game.settings import Settings
from game.squadrons import Pilot
from game.theater.controlpoint import (
@ -229,6 +228,7 @@ class AircraftConflictGenerator:
laser_code_registry: LaserCodeRegistry,
unit_map: UnitMap,
air_support: AirSupport,
helipads: dict[ControlPoint, list[StaticGroup]],
) -> None:
self.m = mission
self.game = game
@ -239,6 +239,7 @@ class AircraftConflictGenerator:
self.unit_map = unit_map
self.flights: List[FlightData] = []
self.air_support = air_support
self.helipads = helipads
@cached_property
def use_client(self) -> bool:
@ -550,40 +551,37 @@ class AircraftConflictGenerator:
unit_type, side.id, cp.name
)
)
helipad = cp.get_free_helipad()
if helipad is not None and helipad.static_unit is not None:
group = self._generate_at_group(
name=name,
side=side,
unit_type=unit_type,
count=count,
start_type=start_type,
at=helipad.static_unit,
)
# Note : A bit dirty, need better support in pydcs
group.points[0].action = PointAction.FromGroundArea
group.points[0].type = "TakeOffGround"
group.units[0].heading = helipad.heading
if start_type != "Cold":
group.points[0].action = PointAction.FromGroundAreaHot
group.points[0].type = "TakeOffGroundHot"
try:
helipad = self.helipads[cp].pop()
except IndexError as ex:
raise RuntimeError(f"Not enough helipads available at {cp}") from ex
helipad.occupied = True
group = self._generate_at_group(
name=name,
side=side,
unit_type=unit_type,
count=count,
start_type=start_type,
at=helipad,
)
for i in range(count - 1):
helipad = cp.get_free_helipad()
if helipad is not None:
helipad.occupied = True
group.units[1 + i].position = Point(helipad.x, helipad.y)
group.units[1 + i].heading = helipad.heading
else:
raise RuntimeError(
f"Control Point {cp.name} does not have enough helipads"
)
return group
else:
raise RuntimeError(f"Control Point {cp.name} does not have enough helipads")
# Note : A bit dirty, need better support in pydcs
group.points[0].action = PointAction.FromGroundArea
group.points[0].type = "TakeOffGround"
group.units[0].heading = helipad.units[0].heading
if start_type != "Cold":
group.points[0].action = PointAction.FromGroundAreaHot
group.points[0].type = "TakeOffGroundHot"
for i in range(count - 1):
try:
helipad = self.helipads[cp].pop()
group.units[1 + i].position = Point(helipad.x, helipad.y)
group.units[1 + i].heading = helipad.units[0].heading
except IndexError as ex:
raise RuntimeError(f"Not enough helipads available at {cp}") from ex
return group
def _add_radio_waypoint(
self,

View File

@ -9,6 +9,7 @@ from __future__ import annotations
import logging
import random
from collections import defaultdict
from typing import (
Dict,
Iterator,
@ -587,6 +588,7 @@ class HelipadGenerator:
self.game = game
self.radio_registry = radio_registry
self.tacan_registry = tacan_registry
self.helipads: list[StaticGroup] = []
def generate(self) -> None:
@ -595,7 +597,7 @@ class HelipadGenerator:
country = self.m.country(self.game.coalition_for(self.cp.captured).country_name)
for i, helipad in enumerate(self.cp.helipads):
name = self.cp.name + "_helipad_" + str(i)
logging.info("Generating helipad : " + name)
logging.info("Generating helipad static : " + name)
pad = InvisibleFARP(name=name)
pad.position = Point(helipad.x, helipad.y)
pad.heading = helipad.heading.degrees
@ -606,8 +608,7 @@ class HelipadGenerator:
sg.add_point(sp)
neutral_country.add_static_group(sg)
helipad.static_unit = sg
helipad.occupied = False
self.helipads.append(sg)
# Generate a FARP Ammo and Fuel stack for each pad
self.m.static_group(
@ -652,13 +653,18 @@ class GroundObjectsGenerator:
self.unit_map = unit_map
self.icls_alloc = iter(range(1, 21))
self.runways: Dict[str, RunwayData] = {}
self.helipads: dict[ControlPoint, list[StaticGroup]] = defaultdict(list)
def generate(self) -> None:
for cp in self.game.theater.controlpoints:
country = self.m.country(self.game.coalition_for(cp.captured).country_name)
HelipadGenerator(
# Generate helipads
helipad_gen = HelipadGenerator(
self.m, cp, self.game, self.radio_registry, self.tacan_registry
).generate()
)
helipad_gen.generate()
self.helipads[cp] = helipad_gen.helipads
for ground_object in cp.ground_objects:
generator: GenericGroundObjectGenerator[Any]