Skip to content

Commit

Permalink
Fix spawns on carriers and FARPs in DCS 2.9.6 (#387)
Browse files Browse the repository at this point in the history
* Introduce function update_warehouses to update warehouses at save time, as warehouses are added unit-by-unit and units can be added without going through wrapper functions like ship_group()
* Fix spawns on carriers in DCS 2.9.6
* handle FARPs as well
  • Loading branch information
zhexu14 authored Aug 2, 2024
1 parent 15e1361 commit d94fa3d
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 50 deletions.
23 changes: 23 additions & 0 deletions dcs/mission.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import dcs.lua as lua
import dcs.mapping as mapping
import dcs.planes as planes
import dcs.ships as ships
import dcs.task as task
import dcs.unitgroup as unitgroup
import dcs.unittype as unittype
Expand Down Expand Up @@ -1006,6 +1007,27 @@ def _load_tasks(mp: MovingPoint, maintask: Type[task.MainTask]):
mp.tasks.append(ptask)
return mp

def update_warehouses(self):
"""Some units need to have warehouse entries. This function updates warehouse entries based on units defined
in the mission.
"""
coalition_to_warehouse_names = {'red': 'RED', 'blue': 'BLUE', 'neutrals': 'NEUTRAL'}
for coalition_name in self.coalition:
coalition_name_in_warehouse = coalition_to_warehouse_names[coalition_name]
for country_name in self.coalition[coalition_name].countries:
# Ships that can have aircraft parked need a warehouse entry.
for ship_group in self.coalition[coalition_name].countries[country_name].ship_group:
for unit_ in ship_group.units:
if ships.ship_map[unit_.type].parking > 0:
self.warehouses.warehouses[str(unit_.id)] = terrain_.terrain.Warehouse().dict()
self.warehouses.warehouses[str(unit_.id)]['coalition'] = coalition_name_in_warehouse
# FARPs need a warehouse entry.
for static_group in self.coalition[coalition_name].countries[country_name].static_group:
for unit_ in static_group.units:
if isinstance(unit_, unit.BaseFARP):
self.warehouses.warehouses[str(unit_.id)] = terrain_.terrain.Warehouse().dict()
self.warehouses.warehouses[str(unit_.id)]['coalition'] = coalition_name_in_warehouse

def _flying_group_from_airport(self, _country, group: unitgroup.FlyingGroup,
maintask: Type[task.MainTask],
airport: terrain_.Airport,
Expand Down Expand Up @@ -2055,6 +2077,7 @@ def save(self, filename=None):
self.filename = filename # store filename

options = str(self.options)
self.update_warehouses() # update warehouses to make sure units that need warehouses have them.
warehouses = str(self.warehouses)
mission = str(self)

Expand Down
111 changes: 61 additions & 50 deletions dcs/terrain/terrain.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,29 +116,9 @@ class NoParkingSlotError(RuntimeError):
pass


class Airport:
id: int
name: str
tacan = None
frequencies: List[float] = []
unit_zones: List[mapping.Rectangle] = []
civilian = True
slot_version = 1
atc_radio: Optional[AtcRadio]
class Warehouse:

def __init__(self, position: mapping.Point, terrain: Terrain) -> None:
self.position = position
self._terrain = terrain
self.runway_used = None
self.runways = [] # type: List[Runway]
self.parking_slots = [] # type: List[ParkingSlot]
# This is currently the raw data from DCS, not a useful API. We don't (yet) have
# the info for the beacons themselves, so the beacon associations are not useful
# unless that information is available elsewhere. This data contained in this
# field will change once pydcs has more data for beacons.
self.beacons: list[AirportBeacon] = []

# warehouse values
def __init__(self):
self.coalition = "NEUTRAL"
self.size = 100
self.speed = 16.666666
Expand All @@ -156,24 +136,77 @@ def __init__(self, position: mapping.Point, terrain: Terrain) -> None:
self.methanol_mixture_init = 100
self.diesel_init = 100
self.jet_init = 100
self.dynamic_spawn = False
self.dynamic_cargo = False

def load_from_dict(self, d):
self.coalition = d["coalition"]
self.speed = d["speed"]
self.size = d["size"]
self.speed = d["speed"]
self.periodicity = d["periodicity"]
self.unlimited_munitions = d["unlimitedMunitions"]
self.unlimited_fuel = d["unlimitedFuel"]
self.unlimited_aircrafts = d["unlimitedAircrafts"]
self.unlimited_fuel = d["unlimitedFuel"]
self.operating_level_air = d["OperatingLevel_Air"]
self.operating_level_equipment = d["OperatingLevel_Eqp"]
self.operating_level_fuel = d["OperatingLevel_Fuel"]
self.operating_level_equipment = d["OperatingLevel_Eqp"]
self.aircrafts = d["aircrafts"]
self.weapons = d["weapons"]
self.suppliers = d["suppliers"]
self.gasoline_init = d.get("gasoline", {}).get("InitFuel", 100)
self.methanol_mixture_init = d.get("methanol_mixture", {}).get("InitFuel", 100)
self.diesel_init = d.get("diesel", {}).get("InitFuel", 100)
self.jet_init = d.get("jet_fuel", {}).get("InitFuel", 100)
self.methanol_mixture_init = d.get("methanol_mixture", {}).get("InitFuel", 100)
self.aircrafts = d["aircrafts"]
self.weapons = d["weapons"]
self.dynamic_spawn = d.get("dynamicSpawn", False)
self.dynamic_cargo = d.get("dynamicCargo", False)

def dict(self):
d = {
"coalition": self.coalition,
"size": self.size,
"speed": self.speed,
"periodicity": self.periodicity,
"unlimitedMunitions": self.unlimited_munitions,
"unlimitedAircrafts": self.unlimited_aircrafts,
"unlimitedFuel": self.unlimited_fuel,
"OperatingLevel_Air": self.operating_level_air,
"OperatingLevel_Fuel": self.operating_level_fuel,
"OperatingLevel_Eqp": self.operating_level_equipment,
"aircrafts": self.aircrafts,
"weapons": self.weapons,
"suppliers": self.suppliers,
"gasoline": {"InitFuel": self.gasoline_init},
"methanol_mixture": {"InitFuel": self.methanol_mixture_init},
"diesel": {"InitFuel": self.diesel_init},
"jet_fuel": {"InitFuel": self.jet_init},
"dynamicSpawn": self.dynamic_spawn,
"dynamicCargo": self.dynamic_cargo
}
return d


class Airport(Warehouse):
id: int
name: str
tacan = None
frequencies: List[float] = []
unit_zones: List[mapping.Rectangle] = []
civilian = True
slot_version = 1
atc_radio: Optional[AtcRadio]

def __init__(self, position: mapping.Point, terrain: Terrain) -> None:
self.position = position
self._terrain = terrain
self.runway_used = None
self.runways = [] # type: List[Runway]
self.parking_slots = [] # type: List[ParkingSlot]
# This is currently the raw data from DCS, not a useful API. We don't (yet) have
# the info for the beacons themselves, so the beacon associations are not useful
# unless that information is available elsewhere. This data contained in this
# field will change once pydcs has more data for beacons.
self.beacons: list[AirportBeacon] = []
super().__init__()

def set_blue(self):
self.set_coalition("BLUE")
Expand Down Expand Up @@ -281,28 +314,6 @@ def free_parking_slot(self, aircraft_type: Type[unittype.FlyingType]) -> Optiona
return slots[0]
return None

def dict(self):
d = {
"coalition": self.coalition,
"speed": self.speed,
"size": self.size,
"periodicity": self.periodicity,
"unlimitedMunitions": self.unlimited_munitions,
"unlimitedFuel": self.unlimited_fuel,
"unlimitedAircrafts": self.unlimited_aircrafts,
"OperatingLevel_Air": self.operating_level_air,
"OperatingLevel_Eqp": self.operating_level_equipment,
"OperatingLevel_Fuel": self.operating_level_fuel,
"gasoline": {"InitFuel": self.gasoline_init},
"diesel": {"InitFuel": self.diesel_init},
"jet_fuel": {"InitFuel": self.jet_init},
"methanol_mixture": {"InitFuel": self.methanol_mixture_init},
"aircrafts": self.aircrafts,
"weapons": self.weapons,
"suppliers": self.suppliers
}
return d

def __repr__(self):
return "Airport(" + self.name + ")"

Expand Down

0 comments on commit d94fa3d

Please sign in to comment.