mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Add option to force air-starts at Nevatim
This commit is contained in:
parent
93c5cb767e
commit
9e1a642eb2
@ -41,6 +41,7 @@
|
|||||||
* **[Config]** Preference setting to use custom Liberation payloads instead of prioritizing Retribution's default
|
* **[Config]** Preference setting to use custom Liberation payloads instead of prioritizing Retribution's default
|
||||||
* **[Config]** Preference setting to configure the server-port on which Retribution's back-end will run
|
* **[Config]** Preference setting to configure the server-port on which Retribution's back-end will run
|
||||||
* **[Options]** Made AI jettisoning empty fuel tanks optional (disabled by default)
|
* **[Options]** Made AI jettisoning empty fuel tanks optional (disabled by default)
|
||||||
|
* **[Options]** Add option (so it can be disabled when fixed in DCS) to force air-starts (except for the slots that work) at Nevatim due to https://forum.dcs.world/topic/335545-29-nevatim-ramp-starts-still-bugged/.
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
* **[Mission Generation]** Anti-ship strikes should use "group attack" in their attack-task
|
* **[Mission Generation]** Anti-ship strikes should use "group attack" in their attack-task
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
from typing import Any, Union, Tuple, Optional
|
from typing import Any, Union, Tuple, Optional, List
|
||||||
|
|
||||||
from dcs import Mission
|
from dcs import Mission
|
||||||
from dcs.country import Country
|
from dcs.country import Country
|
||||||
@ -18,7 +18,8 @@ from dcs.planes import (
|
|||||||
)
|
)
|
||||||
from dcs.point import PointAction
|
from dcs.point import PointAction
|
||||||
from dcs.ships import KUZNECOW
|
from dcs.ships import KUZNECOW
|
||||||
from dcs.terrain import NoParkingSlotError
|
from dcs.terrain import NoParkingSlotError, Sinai, ParkingSlot
|
||||||
|
from dcs.terrain.sinai.airports import Nevatim
|
||||||
from dcs.unitgroup import (
|
from dcs.unitgroup import (
|
||||||
FlyingGroup,
|
FlyingGroup,
|
||||||
ShipGroup,
|
ShipGroup,
|
||||||
@ -109,24 +110,31 @@ class FlightGroupSpawner:
|
|||||||
|
|
||||||
def create_idle_aircraft(self) -> Optional[FlyingGroup[Any]]:
|
def create_idle_aircraft(self) -> Optional[FlyingGroup[Any]]:
|
||||||
group = None
|
group = None
|
||||||
if (
|
cp = self.flight.squadron.location
|
||||||
self.flight.is_helo
|
if self.flight.is_helo or self.flight.is_lha and isinstance(cp, Fob):
|
||||||
or self.flight.is_lha
|
|
||||||
and isinstance(self.flight.squadron.location, Fob)
|
|
||||||
):
|
|
||||||
group = self._generate_at_cp_helipad(
|
group = self._generate_at_cp_helipad(
|
||||||
name=namegen.next_aircraft_name(self.country, self.flight),
|
name=namegen.next_aircraft_name(self.country, self.flight),
|
||||||
cp=self.flight.squadron.location,
|
cp=self.flight.squadron.location,
|
||||||
)
|
)
|
||||||
elif isinstance(self.flight.squadron.location, Fob):
|
elif isinstance(cp, Fob):
|
||||||
group = self._generate_at_cp_ground_spawn(
|
group = self._generate_at_cp_ground_spawn(
|
||||||
name=namegen.next_aircraft_name(self.country, self.flight),
|
name=namegen.next_aircraft_name(self.country, self.flight),
|
||||||
cp=self.flight.squadron.location,
|
cp=self.flight.squadron.location,
|
||||||
)
|
)
|
||||||
elif isinstance(self.flight.squadron.location, Airfield):
|
elif isinstance(cp, Airfield):
|
||||||
|
# TODO: remove hack when fixed in DCS
|
||||||
|
slots = None
|
||||||
|
if self._check_nevatim_hack(cp):
|
||||||
|
ac_type = self.flight.unit_type.dcs_unit_type
|
||||||
|
slots = [
|
||||||
|
slot
|
||||||
|
for slot in cp.dcs_airport.free_parking_slots(ac_type)
|
||||||
|
if slot.slot_name in [str(n) for n in range(55, 66)]
|
||||||
|
]
|
||||||
group = self._generate_at_airfield(
|
group = self._generate_at_airfield(
|
||||||
name=namegen.next_aircraft_name(self.country, self.flight),
|
name=namegen.next_aircraft_name(self.country, self.flight),
|
||||||
airfield=self.flight.squadron.location,
|
airfield=cp,
|
||||||
|
parking_slots=slots,
|
||||||
)
|
)
|
||||||
if group:
|
if group:
|
||||||
group.uncontrolled = True
|
group.uncontrolled = True
|
||||||
@ -195,7 +203,19 @@ class FlightGroupSpawner:
|
|||||||
pad_group = self._generate_at_cp_ground_spawn(name, cp)
|
pad_group = self._generate_at_cp_ground_spawn(name, cp)
|
||||||
if pad_group is not None:
|
if pad_group is not None:
|
||||||
return pad_group
|
return pad_group
|
||||||
return self._generate_at_airfield(name, cp)
|
|
||||||
|
# TODO: get rid of the nevatim hack once fixed in DCS...
|
||||||
|
if self._check_nevatim_hack(cp):
|
||||||
|
slots = [
|
||||||
|
slot
|
||||||
|
for slot in cp.dcs_airport.free_parking_slots(
|
||||||
|
self.flight.squadron.aircraft.dcs_unit_type
|
||||||
|
)
|
||||||
|
if slot.slot_name in [str(n) for n in range(55, 66)]
|
||||||
|
]
|
||||||
|
return self._generate_at_airfield(name, cp, slots)
|
||||||
|
else:
|
||||||
|
return self._generate_at_airfield(name, cp)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
f"Aircraft spawn behavior not implemented for {cp} ({cp.__class__})"
|
f"Aircraft spawn behavior not implemented for {cp} ({cp.__class__})"
|
||||||
@ -209,6 +229,13 @@ class FlightGroupSpawner:
|
|||||||
group = self._generate_over_departure(name, cp)
|
group = self._generate_over_departure(name, cp)
|
||||||
return group
|
return group
|
||||||
|
|
||||||
|
def _check_nevatim_hack(self, cp: ControlPoint) -> bool:
|
||||||
|
# TODO: get rid of the nevatim hack once fixed in DCS...
|
||||||
|
nevatim_hack = self.flight.coalition.game.settings.nevatim_parking_fix
|
||||||
|
nevatim_hack &= isinstance(self.mission.terrain, Sinai)
|
||||||
|
nevatim_hack &= isinstance(cp.dcs_airport, Nevatim)
|
||||||
|
return nevatim_hack
|
||||||
|
|
||||||
def generate_mid_mission(self) -> FlyingGroup[Any]:
|
def generate_mid_mission(self) -> FlyingGroup[Any]:
|
||||||
assert isinstance(self.flight.state, InFlight)
|
assert isinstance(self.flight.state, InFlight)
|
||||||
name = namegen.next_aircraft_name(self.country, self.flight)
|
name = namegen.next_aircraft_name(self.country, self.flight)
|
||||||
@ -250,7 +277,12 @@ class FlightGroupSpawner:
|
|||||||
group.points[0].alt_type = alt_type
|
group.points[0].alt_type = alt_type
|
||||||
return group
|
return group
|
||||||
|
|
||||||
def _generate_at_airfield(self, name: str, airfield: Airfield) -> FlyingGroup[Any]:
|
def _generate_at_airfield(
|
||||||
|
self,
|
||||||
|
name: str,
|
||||||
|
airfield: Airfield,
|
||||||
|
parking_slots: Optional[List[ParkingSlot]] = None,
|
||||||
|
) -> FlyingGroup[Any]:
|
||||||
# TODO: Delayed runway starts should be converted to air starts for multiplayer.
|
# TODO: Delayed runway starts should be converted to air starts for multiplayer.
|
||||||
# Runway starts do not work with late activated aircraft in multiplayer. Instead
|
# 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
|
# of spawning on the runway the aircraft will spawn on the taxiway, potentially
|
||||||
@ -267,7 +299,7 @@ class FlightGroupSpawner:
|
|||||||
maintask=None,
|
maintask=None,
|
||||||
start_type=self._start_type_at_airfield(airfield),
|
start_type=self._start_type_at_airfield(airfield),
|
||||||
group_size=self.flight.count,
|
group_size=self.flight.count,
|
||||||
parking_slots=None,
|
parking_slots=parking_slots,
|
||||||
callsign_name=self.flight.callsign.name if self.flight.callsign else None,
|
callsign_name=self.flight.callsign.name if self.flight.callsign else None,
|
||||||
callsign_nr=self.flight.callsign.nr if self.flight.callsign else None,
|
callsign_nr=self.flight.callsign.nr if self.flight.callsign else None,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -703,6 +703,16 @@ class Settings:
|
|||||||
"will not be included in automatically planned OCA packages."
|
"will not be included in automatically planned OCA packages."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
nevatim_parking_fix: bool = boolean_option(
|
||||||
|
"Force air-starts for all aircraft at Nevatim",
|
||||||
|
page=MISSION_GENERATOR_PAGE,
|
||||||
|
section=GAMEPLAY_SECTION,
|
||||||
|
default=True, # TODO: set to False or remove this when DCS is fixed
|
||||||
|
detail=(
|
||||||
|
"Air-starts forced for all aircraft at Nevatim except parking slots "
|
||||||
|
"55 till 65, since those are the only ones that work."
|
||||||
|
),
|
||||||
|
)
|
||||||
# Mission specific
|
# Mission specific
|
||||||
desired_player_mission_duration: timedelta = minutes_option(
|
desired_player_mission_duration: timedelta = minutes_option(
|
||||||
"Desired mission duration",
|
"Desired mission duration",
|
||||||
|
|||||||
@ -32,7 +32,7 @@ pluggy==1.4.0
|
|||||||
pre-commit==3.6.0
|
pre-commit==3.6.0
|
||||||
pydantic==2.6.0
|
pydantic==2.6.0
|
||||||
pydantic-settings==2.1.0
|
pydantic-settings==2.1.0
|
||||||
-e git+https://github.com/dcs-retribution/pydcs@353f5b177dd406122a83e8572fd6ca54adf84389#egg=pydcs
|
-e git+https://github.com/dcs-retribution/pydcs@9b2f17865859120779385fc546f1b7be3f8ef9c7#egg=pydcs
|
||||||
pyinstaller==5.13.2
|
pyinstaller==5.13.2
|
||||||
pyinstaller-hooks-contrib==2024.0
|
pyinstaller-hooks-contrib==2024.0
|
||||||
pyparsing==3.1.1
|
pyparsing==3.1.1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user