Improved faction & faction loader typing. Fixed error with netherlands faction.

This commit is contained in:
Khopa 2020-10-25 14:08:11 +01:00
parent 910af12fb9
commit e1572c09ff
4 changed files with 68 additions and 85 deletions

View File

@ -1,6 +1,6 @@
from datetime import datetime from datetime import datetime
from enum import Enum from enum import Enum
from typing import Any, Dict, List, Optional, Tuple, Type, Union from typing import Dict, List, Optional, Tuple, Type, Union
from dcs.countries import country_dict from dcs.countries import country_dict
from dcs.helicopters import ( from dcs.helicopters import (
@ -153,10 +153,9 @@ from dcs.vehicles import (
) )
import pydcs_extensions.frenchpack.frenchpack as frenchpack import pydcs_extensions.frenchpack.frenchpack as frenchpack
from game.factions import faction_loader
from game.factions.faction import Faction from game.factions.faction import Faction
# PATCH pydcs data with MODS # PATCH pydcs data with MODS
from game.factions.faction_loader import FactionLoader
from pydcs_extensions.a4ec.a4ec import A_4E_C from pydcs_extensions.a4ec.a4ec import A_4E_C
from pydcs_extensions.mb339.mb339 import MB_339PAN from pydcs_extensions.mb339.mb339 import MB_339PAN
from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M
@ -912,7 +911,7 @@ CARRIER_TAKEOFF_BAN: List[Type[FlyingType]] = [
Units separated by country. Units separated by country.
country : DCS Country name country : DCS Country name
""" """
FACTIONS: [Faction] = faction_loader.load_factions() FACTIONS: [Faction] = FactionLoader.load_factions()
CARRIER_TYPE_BY_PLANE = { CARRIER_TYPE_BY_PLANE = {
FA_18C_hornet: CVN_74_John_C__Stennis, FA_18C_hornet: CVN_74_John_C__Stennis,

View File

@ -1,11 +1,14 @@
from __future__ import annotations
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass, field
from typing import Optional from typing import Optional, Dict, Type, List, Any
import dcs import dcs
from dcs.countries import country_dict
from dcs.planes import PlaneType, plane_map from dcs.planes import PlaneType, plane_map
from dcs.unittype import VehicleType, UnitType from dcs.unittype import VehicleType, UnitType
from dcs.vehicles import vehicle_map, Armor, Unarmed, Infantry, Fortification, Artillery, AirDefence from dcs.vehicles import Armor, Unarmed, Infantry, Artillery, AirDefence
from game.data.building_data import WW2_ALLIES_BUILDINGS, DEFAULT_AVAILABLE_BUILDINGS, WW2_GERMANY_BUILDINGS 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 game.data.doctrine import Doctrine, MODERN_DOCTRINE, COLDWAR_DOCTRINE, WWII_DOCTRINE
@ -16,117 +19,96 @@ from pydcs_extensions.mod_units import MODDED_VEHICLES, MODDED_AIRPLANES
class Faction: class Faction:
# Country used by this faction # Country used by this faction
country: str country: str = field(default="")
# Nice name of the faction # Nice name of the faction
name: str name: str = field(default="")
# Available aircraft # Available aircraft
aircrafts: [UnitType] aircrafts: List[UnitType] = field(default_factory=list)
# Available awacs aircraft # Available awacs aircraft
awacs: [UnitType] awacs: List[UnitType] = field(default_factory=list)
# Available tanker aircraft # Available tanker aircraft
tankers: [UnitType] tankers: List[UnitType] = field(default_factory=list)
# Available frontline units # Available frontline units
frontline_units: [VehicleType] frontline_units: List[VehicleType] = field(default_factory=list)
# Available artillery units # Available artillery units
artillery_units: [VehicleType] artillery_units: List[VehicleType] = field(default_factory=list)
# Infantry units used # Infantry units used
infantry_units: [VehicleType] infantry_units: List[VehicleType] = field(default_factory=list)
# Logistics units used # Logistics units used
logistics_units: [VehicleType] logistics_units: List[VehicleType] = field(default_factory=list)
# List of units that can be deployed as SHORAD # List of units that can be deployed as SHORAD
shorads: [str] shorads: List[str] = field(default_factory=list)
# Possible SAMS site generators for this faction # Possible SAMS site generators for this faction
sams: [str] sams: List[str] = field(default_factory=list)
# Possible Missile site generators for this faction # Possible Missile site generators for this faction
missiles: [str] missiles: List[str] = field(default_factory=list)
# Required mods or asset packs # Required mods or asset packs
requirements: {str: str} requirements: {str: str} = field(default_factory=dict)
# possible aircraft carrier units # possible aircraft carrier units
aircraft_carrier: [UnitType] aircraft_carrier: List[UnitType] = field(default_factory=list)
# possible helicopter carrier units # possible helicopter carrier units
helicopter_carrier: [UnitType] helicopter_carrier: List[UnitType] = field(default_factory=list)
# Possible carrier names # Possible carrier names
carrier_names: [str] carrier_names: List[str] = field(default_factory=list)
# Possible helicopter carrier names # Possible helicopter carrier names
helicopter_carrier_names: [str] helicopter_carrier_names: List[str] = field(default_factory=list)
# Navy group generators # Navy group generators
navy_generators: [str] navy_generators: List[str] = field(default_factory=list)
# Available destroyers # Available destroyers
destroyers: [str] destroyers: List[str] = field(default_factory=list)
# Available cruisers # Available cruisers
cruisers: [str] cruisers: List[str] = field(default_factory=list)
# How many navy group should we try to generate per CP on startup for this faction # How many navy group should we try to generate per CP on startup for this faction
navy_group_count: int navy_group_count: int = field(default=1)
# How many missiles group should we try to generate per CP on startup for this faction # How many missiles group should we try to generate per CP on startup for this faction
missiles_group_count: int missiles_group_count: int = field(default=1)
# Whether this faction has JTAC access # Whether this faction has JTAC access
has_jtac: bool has_jtac: bool = field(default=False)
# Unit to use as JTAC for this faction # Unit to use as JTAC for this faction
jtac_unit: str jtac_unit: str = field(default="")
# doctrine # doctrine
doctrine: Doctrine doctrine: Doctrine = field(default=MODERN_DOCTRINE)
# List of available buildings for this faction # List of available buildings for this faction
building_set: [str] building_set: List[str] = field(default_factory=list)
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.helicopter_carrier_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 @classmethod
def from_json(cls, json): def from_json(cls: Type[Faction], json: Dict[str, any]) -> Faction:
faction = Faction() faction = Faction()
faction.country = json.get("country", "USA") faction.country = json.get("country", "/")
faction.name = json.get("name", "???") if faction.country not in [c.name for c in country_dict.values()]:
raise AssertionError("Faction's country (\"{}\") is not a valid DCS country ID".format(faction.country))
faction.name = json.get("name", "")
if not faction.name:
raise AssertionError("Faction has no valid name")
faction.aircrafts = [f for f in [aircraft_loader(aircraft) for aircraft in json.get("aircrafts", [])] if f is not None] 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.awacs = [f for f in [aircraft_loader(aircraft) for aircraft in json.get("awacs", [])] if f is not None]
@ -179,14 +161,15 @@ class Faction:
return faction return faction
@property @property
def units(self): def units(self) -> List[UnitType]:
return self.infantry_units + self.aircrafts + self.awacs + self.artillery_units + self.frontline_units + self.tankers + self.logistics_units 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]: def unit_loader(unit: str, class_repository: List[Any]) -> Optional[PlaneType]:
""" """
Find unit by name Find unit by name
:param unit: Unit name as string :param unit: Unit name as string
:param class_repository: Repository of classes (Either a module, a class, or a list of classes)
:return: The unit as a PyDCS type :return: The unit as a PyDCS type
""" """
if unit is None: if unit is None:
@ -202,9 +185,9 @@ def unit_loader(unit: str, class_repository:[]) -> Optional[PlaneType]:
if m.__name__ == unit: if m.__name__ == unit:
return m return m
logging.info("FACTION ERROR : Unable to find " + unit + " in pydcs") logging.info("FACTION ERROR : Unable to find " + unit + " in pydcs")
print("FACTION ERROR : Unable to find " + unit + " in pydcs")
return None return None
aircraft_loader = lambda x: unit_loader(x, [dcs.planes, dcs.helicopters, MODDED_AIRPLANES]) 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]) vehicle_loader = lambda x: unit_loader(x, [Infantry, Unarmed, Armor, AirDefence, Artillery, MODDED_VEHICLES])
ship_loader = lambda x: unit_loader(x, [dcs.ships]) ship_loader = lambda x: unit_loader(x, [dcs.ships])

View File

@ -1,30 +1,31 @@
from __future__ import annotations
import json import json
import os
import logging import logging
from pathlib import Path
from typing import Type
from game.factions.faction import Faction from game.factions.faction import Faction
FACTION_DIRECTORY = "./resources/factions/" FACTION_DIRECTORY = "./resources/factions/"
def load_factions() -> {str, Faction}: class FactionLoader:
files = os.listdir(FACTION_DIRECTORY)
files = [f for f in files if f.endswith(".json")]
factions = {} @classmethod
def load_factions(cls: Type[FactionLoader]) -> {str, Faction}:
for f in files: path = Path(FACTION_DIRECTORY)
print(f) files = [f for f in path.glob("*.json") if f.is_file()]
path = os.path.join(FACTION_DIRECTORY, f) factions = {}
logging.info("Loading faction" + path)
#try:
with open(path, "r", encoding="utf-8") as fdata:
data = json.load(fdata, encoding="utf-8")
factions[data["name"]] = Faction.from_json(data)
logging.info("Loaded faction : " + path)
#except Exception as e:
# print(e)
# logging.error("Unable to load faction : " + path)
print(factions) for f in files:
return factions logging.info("Loading faction" + str(f))
try:
with open(f, "r", encoding="utf-8") as fdata:
data = json.load(fdata, encoding="utf-8")
factions[data["name"]] = Faction.from_json(data)
logging.info("Loaded faction : " + str(f))
except Exception as e:
logging.error("Unable to load faction : " + path, e)
return factions

View File

@ -1,5 +1,5 @@
{ {
"country": "Netherlands", "country": "The Netherlands",
"name": "Netherlands 1990", "name": "Netherlands 1990",
"authors": "Khopa", "authors": "Khopa",
"description": "", "description": "",