mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Redo convoy attack flight plans.
The previous flight plan only makes sense if the convoy will make it a significant distance from its starting point. At road speeds over the typical mission duration this is not true, so we can actually plan this as if it was a strike mission near the origin point and that's close enough. There's some cleanup work to do here that I've added todos for. Fixes https://github.com/Khopa/dcs_liberation/issues/996
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
from __future__ import annotations
|
||||
from game.theater.theatergroundobject import TheaterGroundObject
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Iterable, List, Optional, Set
|
||||
from typing import Iterable, List, Optional, Set, TYPE_CHECKING
|
||||
|
||||
from dcs import Mission
|
||||
from dcs.action import DoScript, DoScriptFile
|
||||
@@ -14,7 +13,9 @@ from dcs.lua.parse import loads
|
||||
from dcs.mapping import Point
|
||||
from dcs.translation import String
|
||||
from dcs.triggers import TriggerStart
|
||||
|
||||
from game.plugins import LuaPluginManager
|
||||
from game.theater.theatergroundobject import TheaterGroundObject
|
||||
from gen import Conflict, FlightType, VisualGenerator
|
||||
from gen.aircraft import AIRCRAFT_DATA, AircraftConflictGenerator, FlightData
|
||||
from gen.airfields import AIRFIELD_DATA
|
||||
@@ -31,7 +32,6 @@ from gen.naming import namegen
|
||||
from gen.radios import RadioFrequency, RadioRegistry
|
||||
from gen.tacan import TacanRegistry
|
||||
from gen.triggergen import TRIGGER_RADIUS_MEDIUM, TriggersGenerator
|
||||
|
||||
from .. import db
|
||||
from ..theater import Airfield
|
||||
from ..unitmap import UnitMap
|
||||
@@ -43,18 +43,13 @@ if TYPE_CHECKING:
|
||||
class Operation:
|
||||
"""Static class for managing the final Mission generation"""
|
||||
|
||||
current_mission = None # type: Mission
|
||||
airgen = None # type: AircraftConflictGenerator
|
||||
triggersgen = None # type: TriggersGenerator
|
||||
airsupportgen = None # type: AirSupportConflictGenerator
|
||||
visualgen = None # type: VisualGenerator
|
||||
groundobjectgen = None # type: GroundObjectsGenerator
|
||||
briefinggen = None # type: BriefingGenerator
|
||||
forcedoptionsgen = None # type: ForcedOptionsGenerator
|
||||
radio_registry: Optional[RadioRegistry] = None
|
||||
tacan_registry: Optional[TacanRegistry] = None
|
||||
game = None # type: Game
|
||||
environment_settings = None
|
||||
current_mission: Mission
|
||||
airgen: AircraftConflictGenerator
|
||||
airsupportgen: AirSupportConflictGenerator
|
||||
groundobjectgen: GroundObjectsGenerator
|
||||
radio_registry: RadioRegistry
|
||||
tacan_registry: TacanRegistry
|
||||
game: Game
|
||||
trigger_radius = TRIGGER_RADIUS_MEDIUM
|
||||
is_quick = None
|
||||
player_awacs_enabled = True
|
||||
@@ -309,13 +304,13 @@ class Operation:
|
||||
# Set mission time and weather conditions.
|
||||
EnvironmentGenerator(cls.current_mission, cls.game.conditions).generate()
|
||||
cls._generate_ground_units()
|
||||
cls._generate_convoys()
|
||||
cls._generate_destroyed_units()
|
||||
cls._generate_air_units()
|
||||
cls.assign_channels_to_flights(
|
||||
cls.airgen.flights, cls.airsupportgen.air_support
|
||||
)
|
||||
cls._generate_ground_conflicts()
|
||||
cls._generate_convoys()
|
||||
|
||||
# Triggers
|
||||
triggersgen = TriggersGenerator(cls.current_mission, cls.game)
|
||||
|
||||
@@ -6,8 +6,6 @@ from collections import defaultdict
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Dict, Iterator, List, Optional
|
||||
|
||||
from dcs import Point
|
||||
from game.theater import FlightType, MissionTarget
|
||||
from game.theater.controlpoint import ControlPoint
|
||||
|
||||
|
||||
@@ -99,25 +97,3 @@ class SupplyRoute:
|
||||
current = previous
|
||||
path.reverse()
|
||||
return path
|
||||
|
||||
|
||||
class SupplyRouteLink(MissionTarget):
|
||||
def __init__(self, a: ControlPoint, b: ControlPoint) -> None:
|
||||
self.control_point_a = a
|
||||
self.control_point_b = b
|
||||
super().__init__(
|
||||
f"Supply route between {a} and {b}",
|
||||
Point((a.position.x + b.position.x) / 2, (a.position.y + b.position.y) / 2),
|
||||
)
|
||||
|
||||
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
|
||||
yield from [
|
||||
FlightType.BAI,
|
||||
# TODO: Escort
|
||||
# TODO: SEAD
|
||||
# TODO: Recon
|
||||
# TODO: TARCAP
|
||||
]
|
||||
|
||||
def is_friendly(self, to_player: bool) -> bool:
|
||||
return self.control_point_a.captured
|
||||
|
||||
@@ -3,8 +3,10 @@ from dataclasses import dataclass, field
|
||||
from typing import Dict, Iterator, List, Type
|
||||
|
||||
from dcs.unittype import VehicleType
|
||||
from game.theater import ControlPoint
|
||||
from game.theater import ControlPoint, MissionTarget
|
||||
from game.theater.supplyroutes import SupplyRoute
|
||||
from gen.naming import namegen
|
||||
from gen.flights.flight import FlightType
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -35,6 +37,8 @@ class RoadTransferOrder(TransferOrder):
|
||||
#: point a turn through the supply line.
|
||||
position: ControlPoint = field(init=False)
|
||||
|
||||
name: str = field(init=False, default_factory=namegen.next_convoy_name)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
self.position = self.origin
|
||||
|
||||
@@ -46,6 +50,27 @@ class RoadTransferOrder(TransferOrder):
|
||||
return self.path()[0]
|
||||
|
||||
|
||||
class Convoy(MissionTarget):
|
||||
def __init__(self, transfer: RoadTransferOrder) -> None:
|
||||
self.transfer = transfer
|
||||
count = sum(c for c in transfer.units.values())
|
||||
super().__init__(
|
||||
f"{transfer.name} of {count} units moving from {transfer.position} to "
|
||||
f"{transfer.destination}",
|
||||
transfer.position.position,
|
||||
)
|
||||
|
||||
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
|
||||
if self.is_friendly(for_player):
|
||||
return
|
||||
|
||||
yield FlightType.BAI
|
||||
yield from super().mission_types(for_player)
|
||||
|
||||
def is_friendly(self, to_player: bool) -> bool:
|
||||
return self.transfer.position.captured
|
||||
|
||||
|
||||
class PendingTransfers:
|
||||
def __init__(self) -> None:
|
||||
self.pending_transfers: List[RoadTransferOrder] = []
|
||||
|
||||
Reference in New Issue
Block a user