214 lines
7.1 KiB
Python

import logging
from dataclasses import dataclass
from typing import Optional
import dcs
from dcs.planes import PlaneType, plane_map
from dcs.unittype import VehicleType, UnitType
from dcs.vehicles import vehicle_map, Armor, Unarmed, Infantry, Fortification, Artillery, AirDefence
from game.data.building_data import WW2_ALLIES_BUILDINGS, DEFAULT_AVAILABLE_BUILDINGS, WW2_GERMANY_BUILDINGS
from game.data.doctrine import Doctrine, MODERN_DOCTRINE, COLDWAR_DOCTRINE, WWII_DOCTRINE
from pydcs_extensions.mod_units import MODDED_VEHICLES, MODDED_AIRPLANES
@dataclass
class Faction:
# Country used by this faction
country: str
# Nice name of the faction
name: str
# Available aircraft
aircrafts: [UnitType]
# Available awacs aircraft
awacs: [UnitType]
# Available tanker aircraft
tankers: [UnitType]
# Available frontline units
frontline_units: [VehicleType]
# Available artillery units
artillery_units: [VehicleType]
# Infantry units used
infantry_units: [VehicleType]
# Logistics units used
logistics_units: [VehicleType]
# List of units that can be deployed as SHORAD
shorads: [str]
# Possible SAMS site generators for this faction
sams: [str]
# Possible Missile site generators for this faction
missiles: [str]
# Required mods or asset packs
requirements: {str: str}
# possible aircraft carrier units
aircraft_carrier: [UnitType]
# possible helicopter carrier units
helicopter_carrier: [UnitType]
# Possible carrier names
carrier_names: [str]
# Possible helicopter carrier names
lha_names: [str]
# Navy group generators
navy_generators: [str]
# Available destroyers
destroyers: [str]
# Available cruisers
cruisers: [str]
# How many navy group should we try to generate per CP on startup for this faction
navy_group_count: int
# How many missiles group should we try to generate per CP on startup for this faction
missiles_group_count: int
# Whether this faction has JTAC access
has_jtac: bool
# Unit to use as JTAC for this faction
jtac_unit: str
# doctrine
doctrine: Doctrine
# List of available buildings for this faction
building_set: [str]
def __init__(self):
self.country = ""
self.name = ""
self.aircrafts = []
self.awacs = []
self.tankers = []
self.frontline_units = []
self.artillery_units = []
self.infantry_units = []
self.logistics_units = []
self.shorads = []
self.sams = []
self.missiles = []
self.requirements = {}
self.aircraft_carrier = []
self.helicopter_carrier = []
self.carrier_names = []
self.lha_names = []
self.navy_generators = []
self.destroyers = []
self.cruisers = []
self.navy_group_count = 0
self.missiles_group_count = 0
self.has_jtac = False
self.jtac_unit = ""
self.doctrine = None
@classmethod
def from_json(cls, json):
faction = Faction()
faction.country = json.get("country", "USA")
faction.name = json.get("name", "???")
faction.aircrafts = [f for f in [aircraft_loader(aircraft) for aircraft in json.get("aircrafts", [])] if f is not None]
faction.awacs = [f for f in [aircraft_loader(aircraft) for aircraft in json.get("awacs", [])] if f is not None]
faction.tankers = [f for f in [aircraft_loader(aircraft) for aircraft in json.get("tankers", [])] if f is not None]
faction.frontline_units = [f for f in [vehicle_loader(vehicle) for vehicle in json.get("frontline_units", [])] if f is not None]
faction.artillery_units = [f for f in [vehicle_loader(vehicle) for vehicle in json.get("artillery_units", [])] if f is not None]
faction.infantry_units = [f for f in [vehicle_loader(vehicle) for vehicle in json.get("infantry_units", [])] if f is not None]
faction.logistics_units = [f for f in [vehicle_loader(vehicle) for vehicle in json.get("logistics_units", [])] if f is not None]
faction.sams = json.get("sams", [])
faction.shorads = json.get("shorads", [])
faction.missiles = json.get("missiles", [])
faction.name = json.get("requirements", {})
faction.carrier_names = json.get("carrier_names", [])
faction.lha_names = json.get("lha_names", [])
faction.navy_generators = json.get("navy_generators", [])
faction.aircraft_carrier = [f for f in [ship_loader(vehicle) for vehicle in json.get("aircraft_carrier", [])] if f is not None]
faction.helicopter_carrier = [f for f in [ship_loader(vehicle) for vehicle in json.get("helicopter_carrier", [])] if f is not None]
faction.destroyers = [f for f in [ship_loader(vehicle) for vehicle in json.get("destroyers", [])] if f is not None]
faction.cruisers = [f for f in [ship_loader(vehicle) for vehicle in json.get("cruisers", [])] if f is not None]
faction.has_jtac = json.get("has_jtac", False)
faction.jtac_unit = aircraft_loader(json.get("jtac_unit", None))
faction.navy_group_count = int(json.get("navy_group_count", 1))
faction.missiles_group_count = int(json.get("missiles_group_count", 0))
# Load doctrine
doctrine = json.get("doctrine", "modern")
if doctrine == "modern":
faction.doctrine = MODERN_DOCTRINE
if doctrine == "coldwar":
faction.doctrine = COLDWAR_DOCTRINE
else:
faction.doctrine = WWII_DOCTRINE
# Load the building set
building_set = json.get("building_set", "default")
if building_set == "default":
faction.building_set = DEFAULT_AVAILABLE_BUILDINGS
elif building_set == "ww2ally":
faction.building_set = WW2_ALLIES_BUILDINGS
else:
faction.building_set = WW2_GERMANY_BUILDINGS
return faction
@property
def units(self):
return self.infantry_units + self.aircrafts + self.awacs + self.artillery_units + self.frontline_units + self.tankers + self.logistics_units
def unit_loader(unit: str, class_repository:[]) -> Optional[PlaneType]:
"""
Find unit by name
:param unit: Unit name as string
:return: The unit as a PyDCS type
"""
if unit is None:
return None
elif unit in plane_map.keys():
return plane_map[unit]
else:
for mother_class in class_repository:
if getattr(mother_class, unit, None) is not None:
return getattr(mother_class, unit)
if type(mother_class) is list:
for m in mother_class:
if m.__name__ == unit:
return m
logging.info("FACTION ERROR : Unable to find " + unit + " in pydcs")
print("FACTION ERROR : Unable to find " + unit + " in pydcs")
return None
aircraft_loader = lambda x: unit_loader(x, [dcs.planes, dcs.helicopters, MODDED_AIRPLANES])
vehicle_loader = lambda x: unit_loader(x, [Infantry, Unarmed, Armor, AirDefence, Artillery, MODDED_VEHICLES])
ship_loader = lambda x: unit_loader(x, [dcs.ships])