Add off-map spawn locations.

The AI isn't making use of these yet, but it's not smart enough to do so
anyway.

Would benefit from an icon to differentiate it on the map.

I'm stretching the definition of "control point" quite a bit. We might
want to put a class above `ControlPoint` for `AirSpawnLocation` to
represent types of spawn locations that can't be captured and don't have
ground objectives.

Fixes https://github.com/Khopa/dcs_liberation/issues/274
This commit is contained in:
Dan Albert 2020-11-20 01:58:55 -08:00
parent 4e910c4b09
commit 18b6f7b84c
15 changed files with 178 additions and 99 deletions

View File

@ -26,7 +26,7 @@ from .event.frontlineattack import FrontlineAttackEvent
from .factions.faction import Faction from .factions.faction import Faction
from .infos.information import Information from .infos.information import Information
from .settings import Settings from .settings import Settings
from .theater import ConflictTheater, ControlPoint from .theater import ConflictTheater, ControlPoint, OffMapSpawn
from .weather import Conditions, TimeOfDay from .weather import Conditions, TimeOfDay
COMMISION_UNIT_VARIETY = 4 COMMISION_UNIT_VARIETY = 4
@ -289,6 +289,9 @@ class Game:
if len(potential_cp_armor) == 0: if len(potential_cp_armor) == 0:
potential_cp_armor = self.theater.enemy_points() potential_cp_armor = self.theater.enemy_points()
potential_cp_armor = [p for p in potential_cp_armor if
not isinstance(p, OffMapSpawn)]
i = 0 i = 0
potential_units = db.FACTIONS[self.enemy_name].frontline_units potential_units = db.FACTIONS[self.enemy_name].frontline_units

View File

@ -16,6 +16,7 @@ from dcs.countries import (
) )
from dcs.country import Country from dcs.country import Country
from dcs.mapping import Point from dcs.mapping import Point
from dcs.planes import F_15C
from dcs.ships import ( from dcs.ships import (
CVN_74_John_C__Stennis, CVN_74_John_C__Stennis,
LHA_1_Tarawa, LHA_1_Tarawa,
@ -31,11 +32,17 @@ from dcs.terrain import (
thechannel, thechannel,
) )
from dcs.terrain.terrain import Airport, Terrain from dcs.terrain.terrain import Airport, Terrain
from dcs.unitgroup import Group, ShipGroup, StaticGroup, VehicleGroup from dcs.unitgroup import (
FlyingGroup,
Group,
ShipGroup,
StaticGroup,
VehicleGroup,
)
from dcs.vehicles import AirDefence, Armor from dcs.vehicles import AirDefence, Armor
from gen.flights.flight import FlightType from gen.flights.flight import FlightType
from .controlpoint import ControlPoint, MissionTarget from .controlpoint import ControlPoint, MissionTarget, OffMapSpawn
from .landmap import Landmap, load_landmap, poly_contains from .landmap import Landmap, load_landmap, poly_contains
from ..utils import nm_to_meter from ..utils import nm_to_meter
@ -94,6 +101,8 @@ class MizCampaignLoader:
BLUE_COUNTRY = CombinedJointTaskForcesBlue() BLUE_COUNTRY = CombinedJointTaskForcesBlue()
RED_COUNTRY = CombinedJointTaskForcesRed() RED_COUNTRY = CombinedJointTaskForcesRed()
OFF_MAP_UNIT_TYPE = F_15C.id
CV_UNIT_TYPE = CVN_74_John_C__Stennis.id CV_UNIT_TYPE = CVN_74_John_C__Stennis.id
LHA_UNIT_TYPE = LHA_1_Tarawa.id LHA_UNIT_TYPE = LHA_1_Tarawa.id
FRONT_LINE_UNIT_TYPE = Armor.APC_M113.id FRONT_LINE_UNIT_TYPE = Armor.APC_M113.id
@ -175,6 +184,11 @@ class MizCampaignLoader:
def red(self) -> Country: def red(self) -> Country:
return self.country(blue=False) return self.country(blue=False)
def off_map_spawns(self, blue: bool) -> Iterator[FlyingGroup]:
for group in self.country(blue).plane_group:
if group.units[0].type == self.OFF_MAP_UNIT_TYPE:
yield group
def carriers(self, blue: bool) -> Iterator[ShipGroup]: def carriers(self, blue: bool) -> Iterator[ShipGroup]:
for group in self.country(blue).ship_group: for group in self.country(blue).ship_group:
if group.units[0].type == self.CV_UNIT_TYPE: if group.units[0].type == self.CV_UNIT_TYPE:
@ -236,6 +250,12 @@ class MizCampaignLoader:
control_points[control_point.id] = control_point control_points[control_point.id] = control_point
for blue in (False, True): for blue in (False, True):
for group in self.off_map_spawns(blue):
control_point = OffMapSpawn(next(self.control_point_id),
str(group.name), group.position)
control_point.captured = blue
control_point.captured_invert = group.late_activation
control_points[control_point.id] = control_point
for group in self.carriers(blue): for group in self.carriers(blue):
# TODO: Name the carrier. # TODO: Name the carrier.
control_point = ControlPoint.carrier( control_point = ControlPoint.carrier(

View File

@ -40,6 +40,7 @@ class ControlPointType(Enum):
LHA_GROUP = 2 # A group with a Tarawa carrier (Helicopters & Harrier) LHA_GROUP = 2 # A group with a Tarawa carrier (Helicopters & Harrier)
FARP = 4 # A FARP, with slots for helicopters FARP = 4 # A FARP, with slots for helicopters
FOB = 5 # A FOB (ground units only) FOB = 5 # A FOB (ground units only)
OFF_MAP = 6
class LocationType(Enum): class LocationType(Enum):
@ -364,3 +365,17 @@ class ControlPoint(MissionTarget):
yield from [ yield from [
# TODO: FlightType.STRIKE # TODO: FlightType.STRIKE
] ]
class OffMapSpawn(ControlPoint):
def __init__(self, id: int, name: str, position: Point):
from . import IMPORTANCE_MEDIUM, SIZE_REGULAR
super().__init__(id, name, position, at=position, radials=[],
size=SIZE_REGULAR, importance=IMPORTANCE_MEDIUM,
has_frontline=False, cptype=ControlPointType.OFF_MAP)
def capture(self, game: Game, for_player: bool) -> None:
raise RuntimeError("Off map control points cannot be captured")
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
yield from []

View File

@ -42,8 +42,7 @@ from gen.sam.sam_group_generator import (
from theater import ( from theater import (
ConflictTheater, ConflictTheater,
ControlPoint, ControlPoint,
ControlPointType, ControlPointType, OffMapSpawn,
TheaterGroundObject,
) )
GroundObjectTemplates = Dict[str, Dict[str, Any]] GroundObjectTemplates = Dict[str, Dict[str, Any]]
@ -139,7 +138,13 @@ class GameGenerator:
control_point.base.commision_points = {} control_point.base.commision_points = {}
control_point.base.strength = 1 control_point.base.strength = 1
# The tasks here are confusing. PinpointStrike for some reason means
# ground units.
for task in [PinpointStrike, CAP, CAS, AirDefence]: for task in [PinpointStrike, CAP, CAS, AirDefence]:
if isinstance(control_point, OffMapSpawn):
# Off-map spawn locations start with no aircraft.
continue
if IMPORTANCE_HIGH <= control_point.importance <= IMPORTANCE_LOW: if IMPORTANCE_HIGH <= control_point.importance <= IMPORTANCE_LOW:
raise ValueError( raise ValueError(
f"CP importance must be between {IMPORTANCE_LOW} and " f"CP importance must be between {IMPORTANCE_LOW} and "
@ -366,6 +371,11 @@ class ControlPointGroundObjectGenerator:
self.control_point.connected_objectives.append(g) self.control_point.connected_objectives.append(g)
class NoOpGroundObjectGenerator(ControlPointGroundObjectGenerator):
def generate(self) -> bool:
return True
class CarrierGroundObjectGenerator(ControlPointGroundObjectGenerator): class CarrierGroundObjectGenerator(ControlPointGroundObjectGenerator):
def generate(self) -> bool: def generate(self) -> bool:
if not super().generate(): if not super().generate():
@ -660,6 +670,8 @@ class GroundObjectGenerator:
generator = CarrierGroundObjectGenerator(self.game, control_point) generator = CarrierGroundObjectGenerator(self.game, control_point)
elif control_point.cptype == ControlPointType.LHA_GROUP: elif control_point.cptype == ControlPointType.LHA_GROUP:
generator = LhaGroundObjectGenerator(self.game, control_point) generator = LhaGroundObjectGenerator(self.game, control_point)
elif isinstance(control_point, OffMapSpawn):
generator = NoOpGroundObjectGenerator(self.game, control_point)
else: else:
generator = AirbaseGroundObjectGenerator(self.game, control_point, generator = AirbaseGroundObjectGenerator(self.game, control_point,
self.templates) self.templates)

View File

@ -12,3 +12,7 @@ def meter_to_nm(value_in_meter: float) -> int:
def nm_to_meter(value_in_nm: float) -> int: def nm_to_meter(value_in_nm: float) -> int:
return int(value_in_nm * 1852) return int(value_in_nm * 1852)
def knots_to_kph(knots: float) -> int:
return int(knots * 1.852)

View File

@ -70,7 +70,7 @@ from dcs.unittype import FlyingType, UnitType
from game import db from game import db
from game.data.cap_capabilities_db import GUNFIGHTERS from game.data.cap_capabilities_db import GUNFIGHTERS
from game.settings import Settings from game.settings import Settings
from game.utils import nm_to_meter from game.utils import knots_to_kph, nm_to_meter
from gen.airsupportgen import AirSupport from gen.airsupportgen import AirSupport
from gen.ato import AirTaskingOrder, Package from gen.ato import AirTaskingOrder, Package
from gen.callsigns import create_group_callsign_from_unit from gen.callsigns import create_group_callsign_from_unit
@ -84,7 +84,11 @@ from gen.flights.flight import (
from gen.radios import MHz, Radio, RadioFrequency, RadioRegistry, get_radio from gen.radios import MHz, Radio, RadioFrequency, RadioRegistry, get_radio
from gen.runways import RunwayData from gen.runways import RunwayData
from theater import TheaterGroundObject from theater import TheaterGroundObject
from game.theater.controlpoint import ControlPoint, ControlPointType from game.theater.controlpoint import (
ControlPoint,
ControlPointType,
OffMapSpawn,
)
from .conflictgen import Conflict from .conflictgen import Conflict
from .flights.flightplan import ( from .flights.flightplan import (
CasFlightPlan, CasFlightPlan,
@ -92,7 +96,7 @@ from .flights.flightplan import (
PatrollingFlightPlan, PatrollingFlightPlan,
SweepFlightPlan, SweepFlightPlan,
) )
from .flights.traveltime import TotEstimator from .flights.traveltime import GroundSpeed, TotEstimator
from .naming import namegen from .naming import namegen
from .runways import RunwayAssigner from .runways import RunwayAssigner
@ -804,31 +808,37 @@ class AircraftConflictGenerator:
group_size=count, group_size=count,
parking_slots=None) parking_slots=None)
def _generate_inflight(self, name: str, side: Country, unit_type: FlyingType, count: int, at: Point) -> FlyingGroup: def _generate_inflight(self, name: str, side: Country, flight: Flight,
assert count > 0 origin: ControlPoint) -> FlyingGroup:
assert flight.count > 0
at = origin.position
if unit_type in helicopters.helicopter_map.values(): alt_type = "RADIO"
if isinstance(origin, OffMapSpawn):
alt = flight.flight_plan.waypoints[0].alt
alt_type = flight.flight_plan.waypoints[0].alt_type
elif flight.unit_type in helicopters.helicopter_map.values():
alt = WARM_START_HELI_ALT alt = WARM_START_HELI_ALT
speed = WARM_START_HELI_AIRSPEED
else: else:
alt = WARM_START_ALTITUDE alt = WARM_START_ALTITUDE
speed = WARM_START_AIRSPEED
speed = knots_to_kph(GroundSpeed.for_flight(flight, alt))
pos = Point(at.x + random.randint(100, 1000), at.y + random.randint(100, 1000)) pos = Point(at.x + random.randint(100, 1000), at.y + random.randint(100, 1000))
logging.info("airgen: {} for {} at {} at {}".format(unit_type, side.id, alt, speed)) logging.info("airgen: {} for {} at {} at {}".format(flight.unit_type, side.id, alt, speed))
group = self.m.flight_group( group = self.m.flight_group(
country=side, country=side,
name=name, name=name,
aircraft_type=unit_type, aircraft_type=flight.unit_type,
airport=None, airport=None,
position=pos, position=pos,
altitude=alt, altitude=alt,
speed=speed, speed=speed,
maintask=None, maintask=None,
group_size=count) group_size=flight.count)
group.points[0].alt_type = "RADIO" group.points[0].alt_type = alt_type
return group return group
def _generate_at_group(self, name: str, side: Country, def _generate_at_group(self, name: str, side: Country,
@ -974,9 +984,8 @@ class AircraftConflictGenerator:
group = self._generate_inflight( group = self._generate_inflight(
name=namegen.next_unit_name(country, cp.id, flight.unit_type), name=namegen.next_unit_name(country, cp.id, flight.unit_type),
side=country, side=country,
unit_type=flight.unit_type, flight=flight,
count=flight.count, origin=cp)
at=cp.position)
elif cp.is_fleet: elif cp.is_fleet:
group_name = cp.get_carrier_group_name() group_name = cp.get_carrier_group_name()
group = self._generate_at_group( group = self._generate_at_group(
@ -1002,9 +1011,8 @@ class AircraftConflictGenerator:
group = self._generate_inflight( group = self._generate_inflight(
name=namegen.next_unit_name(country, cp.id, flight.unit_type), name=namegen.next_unit_name(country, cp.id, flight.unit_type),
side=country, side=country,
unit_type=flight.unit_type, flight=flight,
count=flight.count, origin=cp)
at=cp.position)
group.points[0].alt = 1500 group.points[0].alt = 1500
return group return group

View File

@ -50,7 +50,7 @@ from theater import (
ControlPoint, ControlPoint,
FrontLine, FrontLine,
MissionTarget, MissionTarget,
TheaterGroundObject, OffMapSpawn, TheaterGroundObject,
SamGroundObject, SamGroundObject,
) )
@ -232,8 +232,12 @@ class PackageBuilder:
if assignment is None: if assignment is None:
return False return False
airfield, aircraft = assignment airfield, aircraft = assignment
if isinstance(airfield, OffMapSpawn):
start_type = "In Flight"
else:
start_type = self.start_type
flight = Flight(self.package, aircraft, plan.num_aircraft, airfield, flight = Flight(self.package, aircraft, plan.num_aircraft, airfield,
plan.task, self.start_type) plan.task, start_type)
self.package.add_flight(flight) self.package.add_flight(flight)
return True return True
@ -406,6 +410,9 @@ class ObjectiveFinder:
CP. CP.
""" """
for cp in self.friendly_control_points(): for cp in self.friendly_control_points():
if isinstance(cp, OffMapSpawn):
# Off-map spawn locations don't need protection.
continue
airfields_in_proximity = self.closest_airfields_to(cp) airfields_in_proximity = self.closest_airfields_to(cp)
airfields_in_threat_range = airfields_in_proximity.airfields_within( airfields_in_threat_range = airfields_in_proximity.airfields_within(
self.AIRFIELD_THREAT_RANGE self.AIRFIELD_THREAT_RANGE

View File

@ -8,11 +8,15 @@ from dcs.unit import Unit
from dcs.unitgroup import VehicleGroup from dcs.unitgroup import VehicleGroup
from game.data.doctrine import Doctrine from game.data.doctrine import Doctrine
from game.utils import nm_to_meter from game.utils import feet_to_meter
from game.weather import Conditions from game.weather import Conditions
from theater import ControlPoint, MissionTarget, TheaterGroundObject from theater import (
ControlPoint,
MissionTarget,
OffMapSpawn,
TheaterGroundObject,
)
from .flight import Flight, FlightWaypoint, FlightWaypointType from .flight import Flight, FlightWaypoint, FlightWaypointType
from ..runways import RunwayAssigner
@dataclass(frozen=True) @dataclass(frozen=True)
@ -34,8 +38,7 @@ class WaypointBuilder:
def is_helo(self) -> bool: def is_helo(self) -> bool:
return getattr(self.flight.unit_type, "helicopter", False) return getattr(self.flight.unit_type, "helicopter", False)
@staticmethod def takeoff(self, departure: ControlPoint) -> FlightWaypoint:
def takeoff(departure: ControlPoint) -> FlightWaypoint:
"""Create takeoff waypoint for the given arrival airfield or carrier. """Create takeoff waypoint for the given arrival airfield or carrier.
Note that the takeoff waypoint will automatically be created by pydcs Note that the takeoff waypoint will automatically be created by pydcs
@ -46,36 +49,59 @@ class WaypointBuilder:
departure: Departure airfield or carrier. departure: Departure airfield or carrier.
""" """
position = departure.position position = departure.position
waypoint = FlightWaypoint( if isinstance(departure, OffMapSpawn):
FlightWaypointType.TAKEOFF, waypoint = FlightWaypoint(
position.x, FlightWaypointType.NAV,
position.y, position.x,
0 position.y,
) 500 if self.is_helo else self.doctrine.rendezvous_altitude
waypoint.name = "TAKEOFF" )
waypoint.alt_type = "RADIO" waypoint.name = "NAV"
waypoint.description = "Takeoff" waypoint.alt_type = "BARO"
waypoint.pretty_name = "Takeoff" waypoint.description = "Enter theater"
waypoint.pretty_name = "Enter theater"
else:
waypoint = FlightWaypoint(
FlightWaypointType.TAKEOFF,
position.x,
position.y,
0
)
waypoint.name = "TAKEOFF"
waypoint.alt_type = "RADIO"
waypoint.description = "Takeoff"
waypoint.pretty_name = "Takeoff"
return waypoint return waypoint
@staticmethod def land(self, arrival: ControlPoint) -> FlightWaypoint:
def land(arrival: ControlPoint) -> FlightWaypoint:
"""Create descent waypoint for the given arrival airfield or carrier. """Create descent waypoint for the given arrival airfield or carrier.
Args: Args:
arrival: Arrival airfield or carrier. arrival: Arrival airfield or carrier.
""" """
position = arrival.position position = arrival.position
waypoint = FlightWaypoint( if isinstance(arrival, OffMapSpawn):
FlightWaypointType.LANDING_POINT, waypoint = FlightWaypoint(
position.x, FlightWaypointType.NAV,
position.y, position.x,
0 position.y,
) 500 if self.is_helo else self.doctrine.rendezvous_altitude
waypoint.name = "LANDING" )
waypoint.alt_type = "RADIO" waypoint.name = "NAV"
waypoint.description = "Land" waypoint.alt_type = "BARO"
waypoint.pretty_name = "Land" waypoint.description = "Exit theater"
waypoint.pretty_name = "Exit theater"
else:
waypoint = FlightWaypoint(
FlightWaypointType.LANDING_POINT,
position.x,
position.y,
0
)
waypoint.name = "LANDING"
waypoint.alt_type = "RADIO"
waypoint.description = "Land"
waypoint.pretty_name = "Land"
return waypoint return waypoint
def hold(self, position: Point) -> FlightWaypoint: def hold(self, position: Point) -> FlightWaypoint:

View File

@ -79,11 +79,8 @@ class QMapControlPoint(QMapObject):
for connected in self.control_point.connected_points: for connected in self.control_point.connected_points:
if connected.captured: if connected.captured:
menu.addAction(self.capture_action)
break break
else:
return
menu.addAction(self.capture_action)
def cheat_capture(self) -> None: def cheat_capture(self) -> None:
self.control_point.capture(self.game_model.game, for_player=True) self.control_point.capture(self.game_model.game, for_player=True)

View File

@ -47,9 +47,12 @@ class QMapObject(QGraphicsRectItem):
object_details_action.triggered.connect(self.on_click) object_details_action.triggered.connect(self.on_click)
menu.addAction(object_details_action) menu.addAction(object_details_action)
new_package_action = QAction(f"New package") # Not all locations have valid objetives. Off-map spawns, for example,
new_package_action.triggered.connect(self.open_new_package_dialog) # have no mission types.
menu.addAction(new_package_action) if list(self.mission_target.mission_types(for_player=True)):
new_package_action = QAction(f"New package")
new_package_action.triggered.connect(self.open_new_package_dialog)
menu.addAction(new_package_action)
self.add_context_menu_actions(menu) self.add_context_menu_actions(menu)

View File

@ -18,7 +18,6 @@ class QBaseMenu2(QDialog):
# Attrs # Attrs
self.cp = cp self.cp = cp
self.game_model = game_model self.game_model = game_model
self.is_carrier = self.cp.cptype in [ControlPointType.AIRCRAFT_CARRIER_GROUP, ControlPointType.LHA_GROUP]
self.objectName = "menuDialogue" self.objectName = "menuDialogue"
# Widgets # Widgets

View File

@ -5,39 +5,30 @@ from qt_ui.windows.basemenu.airfield.QAirfieldCommand import QAirfieldCommand
from qt_ui.windows.basemenu.base_defenses.QBaseDefensesHQ import QBaseDefensesHQ from qt_ui.windows.basemenu.base_defenses.QBaseDefensesHQ import QBaseDefensesHQ
from qt_ui.windows.basemenu.ground_forces.QGroundForcesHQ import QGroundForcesHQ from qt_ui.windows.basemenu.ground_forces.QGroundForcesHQ import QGroundForcesHQ
from qt_ui.windows.basemenu.intel.QIntelInfo import QIntelInfo from qt_ui.windows.basemenu.intel.QIntelInfo import QIntelInfo
from theater import ControlPoint from theater import ControlPoint, OffMapSpawn
class QBaseMenuTabs(QTabWidget): class QBaseMenuTabs(QTabWidget):
def __init__(self, cp: ControlPoint, game_model: GameModel): def __init__(self, cp: ControlPoint, game_model: GameModel):
super(QBaseMenuTabs, self).__init__() super(QBaseMenuTabs, self).__init__()
self.cp = cp
if cp:
if not cp.captured:
if not cp.is_carrier:
self.base_defenses_hq = QBaseDefensesHQ(cp, game_model.game)
self.addTab(self.base_defenses_hq, "Base Defenses")
self.intel = QIntelInfo(cp, game_model.game)
self.addTab(self.intel, "Intel")
else:
if cp.has_runway():
self.airfield_command = QAirfieldCommand(cp, game_model)
self.addTab(self.airfield_command, "Airfield Command")
if not cp.is_carrier:
self.ground_forces_hq = QGroundForcesHQ(cp, game_model)
self.addTab(self.ground_forces_hq, "Ground Forces HQ")
self.base_defenses_hq = QBaseDefensesHQ(cp, game_model.game)
self.addTab(self.base_defenses_hq, "Base Defenses")
else:
self.base_defenses_hq = QBaseDefensesHQ(cp, game_model.game)
self.addTab(self.base_defenses_hq, "Fleet")
if not cp.captured:
if not cp.is_carrier and not isinstance(cp, OffMapSpawn):
self.base_defenses_hq = QBaseDefensesHQ(cp, game_model.game)
self.addTab(self.base_defenses_hq, "Base Defenses")
self.intel = QIntelInfo(cp, game_model.game)
self.addTab(self.intel, "Intel")
else: else:
tabError = QFrame() if cp.has_runway():
l = QGridLayout() self.airfield_command = QAirfieldCommand(cp, game_model)
l.addWidget(QLabel("No Control Point")) self.addTab(self.airfield_command, "Airfield Command")
tabError.setLayout(l)
self.addTab(tabError, "No Control Point") if cp.is_carrier:
self.base_defenses_hq = QBaseDefensesHQ(cp, game_model.game)
self.addTab(self.base_defenses_hq, "Fleet")
elif not isinstance(cp, OffMapSpawn):
self.ground_forces_hq = QGroundForcesHQ(cp, game_model)
self.addTab(self.ground_forces_hq, "Ground Forces HQ")
self.base_defenses_hq = QBaseDefensesHQ(cp, game_model.game)
self.addTab(self.base_defenses_hq, "Base Defenses")

View File

@ -18,7 +18,7 @@ from qt_ui.widgets.QLabeledWidget import QLabeledWidget
from qt_ui.widgets.combos.QAircraftTypeSelector import QAircraftTypeSelector from qt_ui.widgets.combos.QAircraftTypeSelector import QAircraftTypeSelector
from qt_ui.widgets.combos.QFlightTypeComboBox import QFlightTypeComboBox from qt_ui.widgets.combos.QFlightTypeComboBox import QFlightTypeComboBox
from qt_ui.widgets.combos.QOriginAirfieldSelector import QOriginAirfieldSelector from qt_ui.widgets.combos.QOriginAirfieldSelector import QOriginAirfieldSelector
from theater import ControlPoint from theater import ControlPoint, OffMapSpawn
class QFlightCreator(QDialog): class QFlightCreator(QDialog):
@ -107,7 +107,9 @@ class QFlightCreator(QDialog):
origin = self.airfield_selector.currentData() origin = self.airfield_selector.currentData()
size = self.flight_size_spinner.value() size = self.flight_size_spinner.value()
if self.game.settings.perf_ai_parking_start: if isinstance(origin, OffMapSpawn):
start_type = "In Flight"
elif self.game.settings.perf_ai_parking_start:
start_type = "Cold" start_type = "Cold"
else: else:
start_type = "Warm" start_type = "Warm"

View File

@ -42,15 +42,7 @@ class QFlightWaypointList(QTableView):
self.model.setHorizontalHeaderLabels(["Name", "Alt", "TOT/DEPART"]) self.model.setHorizontalHeaderLabels(["Name", "Alt", "TOT/DEPART"])
# The first waypoint is set up by pydcs at mission generation time, so waypoints = self.flight.flight_plan.waypoints
# we need to add that waypoint manually.
takeoff = FlightWaypoint(self.flight.from_cp.position.x,
self.flight.from_cp.position.y, 0)
takeoff.description = "Take Off"
takeoff.name = takeoff.pretty_name = "Take Off from " + self.flight.from_cp.name
takeoff.alt_type = "RADIO"
waypoints = itertools.chain([takeoff], self.flight.points)
for row, waypoint in enumerate(waypoints): for row, waypoint in enumerate(waypoints):
self.add_waypoint_row(row, self.flight, waypoint) self.add_waypoint_row(row, self.flight, waypoint)
self.selectionModel().setCurrentIndex(self.indexAt(QPoint(1, 1)), self.selectionModel().setCurrentIndex(self.indexAt(QPoint(1, 1)),