From 7582040d4197fa6b3d36a6a892cbaf531947fc66 Mon Sep 17 00:00:00 2001 From: Raffson Date: Sun, 28 May 2023 21:05:17 +0200 Subject: [PATCH] Allow harriers to operate from FOBs/FARPs Resolve #109 --- changelog.md | 6 +++-- game/ato/flight.py | 4 +++- .../aircraft/flightgroupspawner.py | 23 +++++++++++++++---- game/squadrons/squadron.py | 8 +++++++ game/theater/controlpoint.py | 6 +++-- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/changelog.md b/changelog.md index 7196af1c..9162ab72 100644 --- a/changelog.md +++ b/changelog.md @@ -14,11 +14,13 @@ * **[Modding]** Support for SW mod v2.55 * **[Modding]** Support for Spanish & Australian Naval Assets v3.2.0 by desdemicabina * **[Modding]** Support for Iron Dome v1.2 by IDF Mods Project -* **[NewGameWizard]** Re-organized generator options & show the regular settings menu instead of the limited "Difficulty & Automation" page. +* **[New Game Wizard]** Re-organized generator options & show the regular settings menu instead of the limited "Difficulty & Automation" page. +* **[Campaign Management]** Ability to operate harriers from FOBs/FARPs for __human pilots only__. Please note that the autoplanner won't generate flights for harriers at FOBs/FARPs, which means you need to plan your missions manually. ## Fixes -* **[New Game Wizard]** Settings would not persist when going back to a previous page. +* **[New Game Wizard]** Settings would not persist when going back to a previous page (obsolete due to overhaul). * **[Mission Generation]** Unused aircraft are no longer claimed, fixing a bug where these aircraft would no longer be available after aborting the mission. +* **[Mission Generation]** Fixed (potential) bug in helipad assignments at FOBs/FARPs. # Retribution v1.1.1 (hotfix) diff --git a/game/ato/flight.py b/game/ato/flight.py index 86e8c995..54bbe498 100644 --- a/game/ato/flight.py +++ b/game/ato/flight.py @@ -7,6 +7,7 @@ from typing import Any, List, Optional, TYPE_CHECKING from dcs import Point from dcs.planes import C_101CC, C_101EB, Su_33, FA_18C_hornet +from game.dcs.aircrafttype import AircraftType from pydcs_extensions.hercules.hercules import Hercules from .flightroster import FlightRoster from .flightstate import FlightState, Navigating, Uninitialized @@ -23,7 +24,6 @@ from ..sidc import ( Status, SymbolSet, ) -from game.dcs.aircrafttype import AircraftType if TYPE_CHECKING: from game.sim.gameupdateevents import GameUpdateEvents @@ -228,6 +228,8 @@ class Flight(SidcDescribable, RadioFrequencyContainer, TacanContainer): self.fuel = unit_type.fuel_max * 0.5 elif unit_type == Hercules: self.fuel = unit_type.fuel_max * 0.75 + elif self.departure.cptype.name in ["FARP", "FOB"] and not self.is_helo: + self.fuel = unit_type.fuel_max * 0.75 def __repr__(self) -> str: return self.__str__() diff --git a/game/missiongenerator/aircraft/flightgroupspawner.py b/game/missiongenerator/aircraft/flightgroupspawner.py index 7ea0d3c0..69c8793f 100644 --- a/game/missiongenerator/aircraft/flightgroupspawner.py +++ b/game/missiongenerator/aircraft/flightgroupspawner.py @@ -7,6 +7,7 @@ from dcs.country import Country from dcs.mapping import Vector2 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 Airport, NoParkingSlotError from dcs.unitgroup import FlyingGroup, ShipGroup, StaticGroup @@ -118,9 +119,16 @@ class FlightGroupSpawner: ) return self._generate_at_group(name, carrier_group) elif isinstance(cp, Fob): - if not self.flight.unit_type.helicopter: + is_heli = self.flight.squadron.aircraft.helicopter + is_vtol = not is_heli and self.flight.squadron.aircraft.lha_capable + if not is_heli and not is_vtol: raise RuntimeError( - f"Cannot spawn fixed-wing aircraft at {cp} because it is a FOB" + f"Cannot spawn non-VTOL aircraft at {cp} because it is a FOB" + ) + pilot_count = len(self.flight.roster.pilots) + if is_vtol and self.flight.roster.player_count != pilot_count: + raise RuntimeError( + f"VTOL aircraft at {cp} must be piloted by humans exclusively." ) return self._generate_at_cp_helipad(name, cp) elif isinstance(cp, Airfield): @@ -252,13 +260,18 @@ class FlightGroupSpawner: group = self._generate_at_group(name, helipad) + group.points[0].type = "TakeOffGround" + group.points[0].action = PointAction.FromGroundArea + if self.start_type is StartType.WARM: - group.points[0].type = "TakeOffParkingHot" + group.points[0].type = "TakeOffGroundHot" + group.points[0].action = PointAction.FromGroundAreaHot hpad = helipad.units[0] for i in range(self.flight.count): - group.units[i].position = hpad.position + pos = cp.helipads.pop(0) + group.units[i].position = pos group.units[i].heading = hpad.heading - group.units[i].parking_id = str(i + 1) + cp.helipads.append(pos) return group def dcs_start_type(self) -> DcsStartType: diff --git a/game/squadrons/squadron.py b/game/squadrons/squadron.py index ee074382..6d820781 100644 --- a/game/squadrons/squadron.py +++ b/game/squadrons/squadron.py @@ -264,6 +264,14 @@ class Squadron: def can_auto_assign_mission( self, location: MissionTarget, task: FlightType, size: int, this_turn: bool ) -> bool: + if ( + self.location.cptype.name in ["FOB", "FARP"] + and not self.aircraft.helicopter + ): + # AI harriers can't handle FOBs/FARPs + # AI has a hard time taking off and will not land back at FOB/FARP + # thus, disable auto-planning + return False if not self.can_auto_assign(task): return False if this_turn and not self.can_fulfill_flight(size): diff --git a/game/theater/controlpoint.py b/game/theater/controlpoint.py index 6ae5ffea..61cf1424 100644 --- a/game/theater/controlpoint.py +++ b/game/theater/controlpoint.py @@ -103,7 +103,7 @@ class ControlPointType(Enum): AIRCRAFT_CARRIER_GROUP = 1 #: A group with a Tarawa carrier (Helicopters & Harrier). LHA_GROUP = 2 - #: A FARP, with slots for helicopters + #: A FARP, with slots for helicopters & harrier FARP = 4 #: A FOB (ground units only) FOB = 5 @@ -1474,7 +1474,9 @@ class Fob(ControlPoint, RadioFrequencyContainer, CTLD): # FOBs and FARPs are the same class, distinguished only by non-FARP FOBs having # zero parking. # https://github.com/dcs-liberation/dcs_liberation/issues/2378 - return aircraft.helicopter and self.total_aircraft_parking > 0 + return ( + aircraft.helicopter or aircraft.lha_capable + ) and self.total_aircraft_parking > 0 @property def heading(self) -> Heading: