mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Implemented generating trigger zones for supply routes, theater ground objects and helicopter supply points. Implemented name generator for Pretense air units.
This commit is contained in:
parent
af4cf03335
commit
9b54730191
@ -36,7 +36,6 @@ from game.theater.controlpoint import (
|
|||||||
from game.unitmap import UnitMap
|
from game.unitmap import UnitMap
|
||||||
from game.missiongenerator.aircraft.aircraftpainter import AircraftPainter
|
from game.missiongenerator.aircraft.aircraftpainter import AircraftPainter
|
||||||
from game.missiongenerator.aircraft.flightdata import FlightData
|
from game.missiongenerator.aircraft.flightdata import FlightData
|
||||||
from game.missiongenerator.aircraft.flightgroupspawner import FlightGroupSpawner
|
|
||||||
from game.data.weapons import WeaponType
|
from game.data.weapons import WeaponType
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -194,8 +193,10 @@ class PretenseAircraftGenerator:
|
|||||||
def create_and_configure_flight(
|
def create_and_configure_flight(
|
||||||
self, flight: Flight, country: Country, dynamic_runways: Dict[str, RunwayData]
|
self, flight: Flight, country: Country, dynamic_runways: Dict[str, RunwayData]
|
||||||
) -> FlyingGroup[Any]:
|
) -> FlyingGroup[Any]:
|
||||||
|
from game.pretense.pretenseflightgroupspawner import PretenseFlightGroupSpawner
|
||||||
|
|
||||||
"""Creates and configures the flight group in the mission."""
|
"""Creates and configures the flight group in the mission."""
|
||||||
group = FlightGroupSpawner(
|
group = PretenseFlightGroupSpawner(
|
||||||
flight,
|
flight,
|
||||||
country,
|
country,
|
||||||
self.mission,
|
self.mission,
|
||||||
|
|||||||
@ -1,53 +1,40 @@
|
|||||||
import logging
|
import logging
|
||||||
import random
|
import re
|
||||||
from typing import Any, Union, Tuple, Optional
|
from typing import Any, Tuple
|
||||||
|
|
||||||
from dcs import Mission
|
from dcs import Mission
|
||||||
from dcs.country import Country
|
from dcs.country import Country
|
||||||
from dcs.mapping import Vector2, Point
|
from dcs.mapping import Vector2, Point
|
||||||
from dcs.mission import StartType as DcsStartType
|
|
||||||
from dcs.planes import F_14A, Su_33
|
|
||||||
from dcs.point import PointAction
|
|
||||||
from dcs.ships import KUZNECOW
|
|
||||||
from dcs.terrain import NoParkingSlotError
|
from dcs.terrain import NoParkingSlotError
|
||||||
from dcs.unitgroup import (
|
from dcs.unitgroup import (
|
||||||
FlyingGroup,
|
FlyingGroup,
|
||||||
ShipGroup,
|
ShipGroup,
|
||||||
StaticGroup,
|
StaticGroup,
|
||||||
HelicopterGroup,
|
|
||||||
PlaneGroup,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from game.ato import Flight
|
from game.ato import Flight
|
||||||
from game.ato.flightstate import InFlight
|
|
||||||
from game.ato.starttype import StartType
|
from game.ato.starttype import StartType
|
||||||
from game.ato.traveltime import GroundSpeed
|
from game.missiongenerator.aircraft.flightgroupspawner import FlightGroupSpawner
|
||||||
from game.missiongenerator.missiondata import MissionData
|
from game.missiongenerator.missiondata import MissionData
|
||||||
from game.naming import namegen
|
from game.naming import NameGenerator
|
||||||
from game.theater import Airfield, ControlPoint, Fob, NavalControlPoint, OffMapSpawn
|
from game.theater import Airfield, ControlPoint, Fob, NavalControlPoint
|
||||||
from game.utils import feet, meters
|
from game.utils import feet, meters
|
||||||
|
|
||||||
WARM_START_HELI_ALT = meters(500)
|
|
||||||
WARM_START_ALTITUDE = meters(3000)
|
|
||||||
|
|
||||||
# In-flight spawns are MSL for the first waypoint (this can maybe be changed to AGL, but
|
class PretenseNameGenerator(NameGenerator):
|
||||||
# AGL waypoints have different piloting behavior, so we need to check whether that's
|
@classmethod
|
||||||
# safe to do first), so spawn them high enough that they're unlikely to be near (or
|
def next_pretense_aircraft_name(cls, cp: ControlPoint, flight: Flight) -> str:
|
||||||
# under) the ground, or any nearby obstacles. The highest airfield in DCS is Kerman in
|
cls.aircraft_number += 1
|
||||||
# PG at 5700ft. This could still be too low if there are tall obstacles near the
|
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||||
# airfield, but the lowest we can push this the better to avoid spawning helicopters
|
return "{}-{}-{}".format(
|
||||||
# well above the altitude for WP1.
|
cp_name_trimmed, str(flight.flight_type).lower(), cls.aircraft_number
|
||||||
MINIMUM_MID_MISSION_SPAWN_ALTITUDE_MSL = feet(6000)
|
)
|
||||||
MINIMUM_MID_MISSION_SPAWN_ALTITUDE_AGL = feet(500)
|
|
||||||
|
|
||||||
STACK_SEPARATION = feet(200)
|
|
||||||
|
|
||||||
RTB_ALTITUDE = meters(800)
|
|
||||||
RTB_DISTANCE = 5000
|
|
||||||
HELI_ALT = 500
|
|
||||||
|
|
||||||
|
|
||||||
class FlightGroupSpawner:
|
namegen = PretenseNameGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class PretenseFlightGroupSpawner(FlightGroupSpawner):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
flight: Flight,
|
flight: Flight,
|
||||||
@ -58,6 +45,16 @@ class FlightGroupSpawner:
|
|||||||
ground_spawns: dict[ControlPoint, list[Tuple[StaticGroup, Point]]],
|
ground_spawns: dict[ControlPoint, list[Tuple[StaticGroup, Point]]],
|
||||||
mission_data: MissionData,
|
mission_data: MissionData,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
super().__init__(
|
||||||
|
flight,
|
||||||
|
country,
|
||||||
|
mission,
|
||||||
|
helipads,
|
||||||
|
ground_spawns_roadbase,
|
||||||
|
ground_spawns,
|
||||||
|
mission_data,
|
||||||
|
)
|
||||||
|
|
||||||
self.flight = flight
|
self.flight = flight
|
||||||
self.country = country
|
self.country = country
|
||||||
self.mission = mission
|
self.mission = mission
|
||||||
@ -66,69 +63,11 @@ class FlightGroupSpawner:
|
|||||||
self.ground_spawns = ground_spawns
|
self.ground_spawns = ground_spawns
|
||||||
self.mission_data = mission_data
|
self.mission_data = mission_data
|
||||||
|
|
||||||
def create_flight_group(self) -> FlyingGroup[Any]:
|
|
||||||
"""Creates the group for the flight and adds it to the mission.
|
|
||||||
|
|
||||||
Each flight is spawned according to its FlightState at the time of mission
|
|
||||||
generation. Aircraft that are WaitingForStart will be set up based on their
|
|
||||||
StartType with a delay. Note that delays are actually created during waypoint
|
|
||||||
generation.
|
|
||||||
|
|
||||||
Aircraft that are *not* WaitingForStart will be spawned in their current state.
|
|
||||||
We cannot spawn aircraft mid-taxi, so when the simulated state is near the end
|
|
||||||
of a long taxi period the aircraft will be spawned in their parking spot. This
|
|
||||||
could lead to problems but that's what loiter points are for. The other pre-
|
|
||||||
flight states have the same problem but are much shorter and more easily covered
|
|
||||||
by the loiter time. Player flights that are spawned near the end of their cold
|
|
||||||
start have the biggest problem but players are able to cut corners to make up
|
|
||||||
for lost time.
|
|
||||||
|
|
||||||
Aircraft that are already in the air will be spawned at their estimated
|
|
||||||
location, speed, and altitude based on their flight plan.
|
|
||||||
"""
|
|
||||||
if (
|
|
||||||
self.flight.state.is_waiting_for_start
|
|
||||||
or self.flight.state.spawn_type is not StartType.IN_FLIGHT
|
|
||||||
):
|
|
||||||
grp = self.generate_flight_at_departure()
|
|
||||||
self.flight.group_id = grp.id
|
|
||||||
return grp
|
|
||||||
grp = self.generate_mid_mission()
|
|
||||||
self.flight.group_id = grp.id
|
|
||||||
return grp
|
|
||||||
|
|
||||||
def create_idle_aircraft(self) -> Optional[FlyingGroup[Any]]:
|
|
||||||
group = None
|
|
||||||
if (
|
|
||||||
self.flight.is_helo
|
|
||||||
or self.flight.is_lha
|
|
||||||
and isinstance(self.flight.squadron.location, Fob)
|
|
||||||
):
|
|
||||||
group = self._generate_at_cp_helipad(
|
|
||||||
name=namegen.next_aircraft_name(self.country, self.flight),
|
|
||||||
cp=self.flight.squadron.location,
|
|
||||||
)
|
|
||||||
elif isinstance(self.flight.squadron.location, Fob):
|
|
||||||
group = self._generate_at_cp_ground_spawn(
|
|
||||||
name=namegen.next_aircraft_name(self.country, self.flight),
|
|
||||||
cp=self.flight.squadron.location,
|
|
||||||
)
|
|
||||||
elif isinstance(self.flight.squadron.location, Airfield):
|
|
||||||
group = self._generate_at_airfield(
|
|
||||||
name=namegen.next_aircraft_name(self.country, self.flight),
|
|
||||||
airfield=self.flight.squadron.location,
|
|
||||||
)
|
|
||||||
if group:
|
|
||||||
group.uncontrolled = True
|
|
||||||
return group
|
|
||||||
|
|
||||||
@property
|
|
||||||
def start_type(self) -> StartType:
|
|
||||||
return self.flight.state.spawn_type
|
|
||||||
|
|
||||||
def generate_flight_at_departure(self) -> FlyingGroup[Any]:
|
def generate_flight_at_departure(self) -> FlyingGroup[Any]:
|
||||||
name = namegen.next_aircraft_name(self.country, self.flight)
|
|
||||||
cp = self.flight.departure
|
cp = self.flight.departure
|
||||||
|
name = namegen.next_pretense_aircraft_name(cp, self.flight)
|
||||||
|
|
||||||
|
print(name)
|
||||||
try:
|
try:
|
||||||
if self.start_type is StartType.IN_FLIGHT:
|
if self.start_type is StartType.IN_FLIGHT:
|
||||||
group = self._generate_over_departure(name, cp)
|
group = self._generate_over_departure(name, cp)
|
||||||
@ -198,236 +137,3 @@ class FlightGroupSpawner:
|
|||||||
self.flight.start_type = StartType.IN_FLIGHT
|
self.flight.start_type = StartType.IN_FLIGHT
|
||||||
group = self._generate_over_departure(name, cp)
|
group = self._generate_over_departure(name, cp)
|
||||||
return group
|
return group
|
||||||
|
|
||||||
def generate_mid_mission(self) -> FlyingGroup[Any]:
|
|
||||||
assert isinstance(self.flight.state, InFlight)
|
|
||||||
name = namegen.next_aircraft_name(self.country, self.flight)
|
|
||||||
speed = self.flight.state.estimate_speed()
|
|
||||||
pos = self.flight.state.estimate_position()
|
|
||||||
pos += Vector2(random.randint(100, 1000), random.randint(100, 1000))
|
|
||||||
alt, alt_type = self.flight.state.estimate_altitude()
|
|
||||||
cp = self.flight.squadron.location.id
|
|
||||||
|
|
||||||
if cp not in self.mission_data.cp_stack:
|
|
||||||
self.mission_data.cp_stack[cp] = MINIMUM_MID_MISSION_SPAWN_ALTITUDE_AGL
|
|
||||||
|
|
||||||
# We don't know where the ground is, so just make sure that any aircraft
|
|
||||||
# spawning at an MSL altitude is spawned at some minimum altitude.
|
|
||||||
# https://github.com/dcs-liberation/dcs_liberation/issues/1941
|
|
||||||
if alt_type == "BARO" and alt < MINIMUM_MID_MISSION_SPAWN_ALTITUDE_MSL:
|
|
||||||
alt = MINIMUM_MID_MISSION_SPAWN_ALTITUDE_MSL
|
|
||||||
|
|
||||||
# Set a minimum AGL value for 'alt' if needed,
|
|
||||||
# otherwise planes might crash in trees and stuff.
|
|
||||||
if alt_type == "RADIO" and alt < self.mission_data.cp_stack[cp]:
|
|
||||||
alt = self.mission_data.cp_stack[cp]
|
|
||||||
self.mission_data.cp_stack[cp] += STACK_SEPARATION
|
|
||||||
|
|
||||||
group = self.mission.flight_group(
|
|
||||||
country=self.country,
|
|
||||||
name=name,
|
|
||||||
aircraft_type=self.flight.unit_type.dcs_unit_type,
|
|
||||||
airport=None,
|
|
||||||
position=pos,
|
|
||||||
altitude=alt.meters,
|
|
||||||
speed=speed.kph,
|
|
||||||
maintask=None,
|
|
||||||
group_size=self.flight.count,
|
|
||||||
)
|
|
||||||
|
|
||||||
group.points[0].alt_type = alt_type
|
|
||||||
return group
|
|
||||||
|
|
||||||
def _generate_at_airfield(self, name: str, airfield: Airfield) -> FlyingGroup[Any]:
|
|
||||||
# TODO: Delayed runway starts should be converted to air starts for multiplayer.
|
|
||||||
# Runway starts do not work with late activated aircraft in multiplayer. Instead
|
|
||||||
# of spawning on the runway the aircraft will spawn on the taxiway, potentially
|
|
||||||
# somewhere that they don't fit anyway. We should either upgrade these to air
|
|
||||||
# starts or (less likely) downgrade to warm starts to avoid the issue when the
|
|
||||||
# player is generating the mission for multiplayer (which would need a new
|
|
||||||
# option).
|
|
||||||
self.flight.unit_type.dcs_unit_type.load_payloads()
|
|
||||||
return self.mission.flight_group_from_airport(
|
|
||||||
country=self.country,
|
|
||||||
name=name,
|
|
||||||
aircraft_type=self.flight.unit_type.dcs_unit_type,
|
|
||||||
airport=airfield.airport,
|
|
||||||
maintask=None,
|
|
||||||
start_type=self._start_type_at_airfield(airfield),
|
|
||||||
group_size=self.flight.count,
|
|
||||||
parking_slots=None,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _generate_over_departure(
|
|
||||||
self, name: str, origin: ControlPoint
|
|
||||||
) -> FlyingGroup[Any]:
|
|
||||||
at = origin.position
|
|
||||||
|
|
||||||
alt_type = "RADIO"
|
|
||||||
if isinstance(origin, OffMapSpawn):
|
|
||||||
alt = self.flight.flight_plan.waypoints[0].alt
|
|
||||||
alt_type = self.flight.flight_plan.waypoints[0].alt_type
|
|
||||||
elif self.flight.unit_type.helicopter:
|
|
||||||
alt = WARM_START_HELI_ALT
|
|
||||||
else:
|
|
||||||
if origin.id not in self.mission_data.cp_stack:
|
|
||||||
min_alt = MINIMUM_MID_MISSION_SPAWN_ALTITUDE_AGL
|
|
||||||
self.mission_data.cp_stack[origin.id] = min_alt
|
|
||||||
alt = self.mission_data.cp_stack[origin.id]
|
|
||||||
self.mission_data.cp_stack[origin.id] += STACK_SEPARATION
|
|
||||||
|
|
||||||
speed = GroundSpeed.for_flight(self.flight, alt)
|
|
||||||
pos = at + Vector2(random.randint(100, 1000), random.randint(100, 1000))
|
|
||||||
|
|
||||||
group = self.mission.flight_group(
|
|
||||||
country=self.country,
|
|
||||||
name=name,
|
|
||||||
aircraft_type=self.flight.unit_type.dcs_unit_type,
|
|
||||||
airport=None,
|
|
||||||
position=pos,
|
|
||||||
altitude=alt.meters,
|
|
||||||
speed=speed.kph,
|
|
||||||
maintask=None,
|
|
||||||
group_size=self.flight.count,
|
|
||||||
)
|
|
||||||
|
|
||||||
group.points[0].alt_type = alt_type
|
|
||||||
return group
|
|
||||||
|
|
||||||
def _generate_at_group(
|
|
||||||
self, name: str, at: Union[ShipGroup, StaticGroup]
|
|
||||||
) -> FlyingGroup[Any]:
|
|
||||||
return self.mission.flight_group_from_unit(
|
|
||||||
country=self.country,
|
|
||||||
name=name,
|
|
||||||
aircraft_type=self.flight.unit_type.dcs_unit_type,
|
|
||||||
pad_group=at,
|
|
||||||
maintask=None,
|
|
||||||
start_type=self._start_type_at_group(at),
|
|
||||||
group_size=self.flight.count,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _generate_at_cp_helipad(
|
|
||||||
self, name: str, cp: ControlPoint
|
|
||||||
) -> Optional[FlyingGroup[Any]]:
|
|
||||||
try:
|
|
||||||
helipad = self.helipads[cp].pop()
|
|
||||||
except IndexError as ex:
|
|
||||||
logging.warning("Not enough helipads available at " + str(ex))
|
|
||||||
if isinstance(cp, Airfield):
|
|
||||||
return self._generate_at_airfield(name, cp)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
# raise RuntimeError(f"Not enough helipads available at {cp}") from ex
|
|
||||||
|
|
||||||
group = self._generate_at_group(name, helipad)
|
|
||||||
|
|
||||||
# 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 self.start_type is not StartType.COLD:
|
|
||||||
group.points[0].action = PointAction.FromGroundAreaHot
|
|
||||||
group.points[0].type = "TakeOffGroundHot"
|
|
||||||
|
|
||||||
wpt = group.waypoint("LANDING")
|
|
||||||
if wpt:
|
|
||||||
hpad = self.helipads[self.flight.arrival].pop(0)
|
|
||||||
wpt.helipad_id = hpad.units[0].id
|
|
||||||
wpt.link_unit = hpad.units[0].id
|
|
||||||
self.helipads[self.flight.arrival].append(hpad)
|
|
||||||
|
|
||||||
for i in range(self.flight.count - 1):
|
|
||||||
try:
|
|
||||||
helipad = self.helipads[cp].pop()
|
|
||||||
terrain = cp.coalition.game.theater.terrain
|
|
||||||
group.units[1 + i].position = Point(
|
|
||||||
helipad.x, helipad.y, terrain=terrain
|
|
||||||
)
|
|
||||||
group.units[1 + i].heading = helipad.units[0].heading
|
|
||||||
except IndexError as ex:
|
|
||||||
logging.warning("Not enough helipads available at " + str(ex))
|
|
||||||
if isinstance(cp, Airfield):
|
|
||||||
return self._generate_at_airfield(name, cp)
|
|
||||||
else:
|
|
||||||
if isinstance(group, HelicopterGroup):
|
|
||||||
self.country.helicopter_group.remove(group)
|
|
||||||
elif isinstance(group, PlaneGroup):
|
|
||||||
self.country.plane_group.remove(group)
|
|
||||||
return None
|
|
||||||
return group
|
|
||||||
|
|
||||||
def _generate_at_cp_ground_spawn(
|
|
||||||
self, name: str, cp: ControlPoint
|
|
||||||
) -> Optional[FlyingGroup[Any]]:
|
|
||||||
try:
|
|
||||||
if len(self.ground_spawns_roadbase[cp]) > 0:
|
|
||||||
ground_spawn = self.ground_spawns_roadbase[cp].pop()
|
|
||||||
else:
|
|
||||||
ground_spawn = self.ground_spawns[cp].pop()
|
|
||||||
except IndexError as ex:
|
|
||||||
logging.warning("Not enough STOL slots available at " + str(ex))
|
|
||||||
return None
|
|
||||||
# raise RuntimeError(f"Not enough STOL slots available at {cp}") from ex
|
|
||||||
|
|
||||||
group = self._generate_at_group(name, ground_spawn[0])
|
|
||||||
|
|
||||||
# Note : A bit dirty, need better support in pydcs
|
|
||||||
group.points[0].action = PointAction.FromGroundArea
|
|
||||||
group.points[0].type = "TakeOffGround"
|
|
||||||
group.units[0].heading = ground_spawn[0].units[0].heading
|
|
||||||
|
|
||||||
try:
|
|
||||||
cp.coalition.game.scenery_clear_zones
|
|
||||||
except AttributeError:
|
|
||||||
cp.coalition.game.scenery_clear_zones = []
|
|
||||||
cp.coalition.game.scenery_clear_zones.append(ground_spawn[1])
|
|
||||||
|
|
||||||
for i in range(self.flight.count - 1):
|
|
||||||
try:
|
|
||||||
terrain = cp.coalition.game.theater.terrain
|
|
||||||
if len(self.ground_spawns_roadbase[cp]) > 0:
|
|
||||||
ground_spawn = self.ground_spawns_roadbase[cp].pop()
|
|
||||||
else:
|
|
||||||
ground_spawn = self.ground_spawns[cp].pop()
|
|
||||||
group.units[1 + i].position = Point(
|
|
||||||
ground_spawn[0].x, ground_spawn[0].y, terrain=terrain
|
|
||||||
)
|
|
||||||
group.units[1 + i].heading = ground_spawn[0].units[0].heading
|
|
||||||
except IndexError as ex:
|
|
||||||
raise RuntimeError(f"Not enough STOL slots available at {cp}") from ex
|
|
||||||
return group
|
|
||||||
|
|
||||||
def dcs_start_type(self) -> DcsStartType:
|
|
||||||
if self.start_type is StartType.RUNWAY:
|
|
||||||
return DcsStartType.Runway
|
|
||||||
elif self.start_type is StartType.COLD:
|
|
||||||
return DcsStartType.Cold
|
|
||||||
elif self.start_type is StartType.WARM:
|
|
||||||
return DcsStartType.Warm
|
|
||||||
raise ValueError(f"There is no pydcs StartType matching {self.start_type}")
|
|
||||||
|
|
||||||
def _start_type_at_airfield(
|
|
||||||
self,
|
|
||||||
airfield: Airfield,
|
|
||||||
) -> DcsStartType:
|
|
||||||
return self.dcs_start_type()
|
|
||||||
|
|
||||||
def _start_type_at_group(
|
|
||||||
self,
|
|
||||||
at: Union[ShipGroup, StaticGroup],
|
|
||||||
) -> DcsStartType:
|
|
||||||
group_units = at.units
|
|
||||||
# Setting Su-33s starting from the non-supercarrier Kuznetsov to take off from
|
|
||||||
# runway to work around a DCS AI issue preventing Su-33s from taking off when
|
|
||||||
# set to "Takeoff from ramp" (#1352)
|
|
||||||
# Also setting the F-14A AI variant to start from cats since they are reported
|
|
||||||
# to have severe pathfinding problems when doing ramp starts (#1927)
|
|
||||||
if self.flight.unit_type.dcs_unit_type == F_14A or (
|
|
||||||
self.flight.unit_type.dcs_unit_type == Su_33
|
|
||||||
and group_units[0] is not None
|
|
||||||
and group_units[0].type == KUZNECOW.id
|
|
||||||
):
|
|
||||||
return DcsStartType.Runway
|
|
||||||
else:
|
|
||||||
return self.dcs_start_type()
|
|
||||||
|
|||||||
@ -50,6 +50,9 @@ TRIGGER_RADIUS_MEDIUM = 100000
|
|||||||
TRIGGER_RADIUS_LARGE = 150000
|
TRIGGER_RADIUS_LARGE = 150000
|
||||||
TRIGGER_RADIUS_ALL_MAP = 3000000
|
TRIGGER_RADIUS_ALL_MAP = 3000000
|
||||||
TRIGGER_RADIUS_CLEAR_SCENERY = 1000
|
TRIGGER_RADIUS_CLEAR_SCENERY = 1000
|
||||||
|
TRIGGER_RADIUS_PRETENSE_TGO = 500
|
||||||
|
TRIGGER_RADIUS_PRETENSE_SUPPLY = 500
|
||||||
|
TRIGGER_RADIUS_PRETENSE_HELI = 1000
|
||||||
|
|
||||||
|
|
||||||
class Silence(Option):
|
class Silence(Option):
|
||||||
@ -156,7 +159,7 @@ class PretenseTriggerGenerator:
|
|||||||
for cp in self.game.theater.controlpoints:
|
for cp in self.game.theater.controlpoints:
|
||||||
if isinstance(cp, self.capture_zone_types) and not cp.is_fleet:
|
if isinstance(cp, self.capture_zone_types) and not cp.is_fleet:
|
||||||
|
|
||||||
zone_color = {1: 0.0, 2: 0.0, 3: 0.0, 4: 0.149}
|
zone_color = {1: 0.0, 2: 0.0, 3: 0.0, 4: 0.15}
|
||||||
trigger_zone = self.mission.triggers.add_triggerzone(
|
trigger_zone = self.mission.triggers.add_triggerzone(
|
||||||
cp.position,
|
cp.position,
|
||||||
radius=TRIGGER_RADIUS_CAPTURE,
|
radius=TRIGGER_RADIUS_CAPTURE,
|
||||||
@ -164,6 +167,45 @@ class PretenseTriggerGenerator:
|
|||||||
name=cp.name,
|
name=cp.name,
|
||||||
color=zone_color,
|
color=zone_color,
|
||||||
)
|
)
|
||||||
|
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||||
|
tgo_num = 0
|
||||||
|
for tgo in cp.ground_objects:
|
||||||
|
tgo_num += 1
|
||||||
|
zone_color = {1: 1.0, 2: 1.0, 3: 1.0, 4: 0.15}
|
||||||
|
trigger_zone = self.mission.triggers.add_triggerzone(
|
||||||
|
tgo.position,
|
||||||
|
radius=TRIGGER_RADIUS_PRETENSE_TGO,
|
||||||
|
hidden=False,
|
||||||
|
name=f"{cp_name_trimmed}-{tgo_num}",
|
||||||
|
color=zone_color,
|
||||||
|
)
|
||||||
|
for helipad in cp.helipads + cp.helipads_invisible + cp.helipads_quad:
|
||||||
|
zone_color = {1: 1.0, 2: 1.0, 3: 1.0, 4: 0.15}
|
||||||
|
trigger_zone = self.mission.triggers.add_triggerzone(
|
||||||
|
position=helipad,
|
||||||
|
radius=TRIGGER_RADIUS_PRETENSE_HELI,
|
||||||
|
hidden=False,
|
||||||
|
name=f"{cp_name_trimmed}-hsp",
|
||||||
|
color=zone_color,
|
||||||
|
)
|
||||||
|
break
|
||||||
|
for supply_route in cp.convoy_routes.values():
|
||||||
|
tgo_num += 1
|
||||||
|
zone_color = {1: 1.0, 2: 1.0, 3: 1.0, 4: 0.15}
|
||||||
|
origin_position = supply_route[0]
|
||||||
|
next_position = supply_route[1]
|
||||||
|
convoy_heading = origin_position.heading_between_point(next_position)
|
||||||
|
supply_position = origin_position.point_from_heading(
|
||||||
|
convoy_heading, 300
|
||||||
|
)
|
||||||
|
trigger_zone = self.mission.triggers.add_triggerzone(
|
||||||
|
supply_position,
|
||||||
|
radius=TRIGGER_RADIUS_PRETENSE_TGO,
|
||||||
|
hidden=False,
|
||||||
|
name=f"{cp_name_trimmed}-sp",
|
||||||
|
color=zone_color,
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
def generate(self) -> None:
|
def generate(self) -> None:
|
||||||
player_coalition = "blue"
|
player_coalition = "blue"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user