diff --git a/game/data/cap_capabilities_db.py b/game/data/cap_capabilities_db.py index eb367238..438a0f80 100644 --- a/game/data/cap_capabilities_db.py +++ b/game/data/cap_capabilities_db.py @@ -1,4 +1,22 @@ -from dcs.planes import * +from dcs.planes import ( + Bf_109K_4, + C_101CC, + FW_190A8, + FW_190D9, + F_5E_3, + F_86F_Sabre, + I_16, + L_39ZA, + MiG_15bis, + MiG_19P, + MiG_21Bis, + P_47D_30, + P_51D, + P_51D_30_NA, + SpitfireLFMkIX, + SpitfireLFMkIXCW, +) + from pydcs_extensions.a4ec.a4ec import A_4E_C """ diff --git a/game/data/radar_db.py b/game/data/radar_db.py index c3c9e25a..4e90d56c 100644 --- a/game/data/radar_db.py +++ b/game/data/radar_db.py @@ -1,5 +1,26 @@ +from dcs.ships import ( + CGN_1144_2_Pyotr_Velikiy, + CG_1164_Moskva, + CVN_70_Carl_Vinson, + CVN_71_Theodore_Roosevelt, + CVN_72_Abraham_Lincoln, + CVN_73_George_Washington, + CVN_74_John_C__Stennis, + CV_1143_5_Admiral_Kuznetsov, + CV_1143_5_Admiral_Kuznetsov_2017, + FFG_11540_Neustrashimy, + FFL_1124_4_Grisha, + FF_1135M_Rezky, + FSG_1241_1MP_Molniya, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, + Type_052B_Destroyer, + Type_052C_Destroyer, + Type_054A_Frigate, + USS_Arleigh_Burke_IIa, +) from dcs.vehicles import AirDefence -from dcs.ships import * UNITS_WITH_RADAR = [ diff --git a/game/db.py b/game/db.py index 45ddfdf7..6ffa6cd7 100644 --- a/game/db.py +++ b/game/db.py @@ -1,34 +1,176 @@ -import typing -import enum from datetime import datetime +from enum import Enum +from typing import Any, Dict, List, Optional, Tuple, Type, Union -from dcs.countries import get_by_id, country_dict -from dcs.vehicles import * -from dcs.ships import * -from dcs.planes import * -from dcs.helicopters import * - -from dcs.task import * -from dcs.unit import * -from dcs.unittype import * -from dcs.unitgroup import * +from dcs.countries import country_dict +from dcs.helicopters import ( + AH_1W, + AH_64A, + AH_64D, + HelicopterType, + Ka_50, + Mi_24V, + Mi_28N, + Mi_8MT, + OH_58D, + SA342L, + SA342M, + SA342Minigun, + SA342Mistral, + UH_1H, + UH_60A, + helicopter_map, +) +from dcs.mapping import Point +# mypy can't resolve these if they're wildcard imports for some reason. +from dcs.planes import ( + AJS37, + AV8BNA, + A_10A, + A_10C, + A_10C_2, + A_20G, + A_50, + An_26B, + An_30M, + B_17G, + B_1B, + B_52H, + Bf_109K_4, + C_101CC, + C_130, + E_3A, + FA_18C_hornet, + FW_190A8, + FW_190D9, + F_14B, + F_15C, + F_15E, + F_16A, + F_16C_50, + F_4E, + F_5E_3, + F_86F_Sabre, + F_A_18C, + IL_76MD, + IL_78M, + JF_17, + J_11A, + Ju_88A4, + KC130, + KC_135, + KJ_2000, + L_39C, + L_39ZA, + MQ_9_Reaper, + M_2000C, + MiG_15bis, + MiG_19P, + MiG_21Bis, + MiG_23MLD, + MiG_25PD, + MiG_27K, + MiG_29A, + MiG_29G, + MiG_29S, + MiG_31, + Mirage_2000_5, + P_47D_30, + P_47D_30bl1, + P_47D_40, + P_51D, + P_51D_30_NA, + PlaneType, + RQ_1A_Predator, + S_3B_Tanker, + SpitfireLFMkIX, + SpitfireLFMkIXCW, + Su_17M4, + Su_24M, + Su_24MR, + Su_25, + Su_25T, + Su_25TM, + Su_27, + Su_30, + Su_33, + Su_34, + Tornado_GR4, + Tornado_IDS, + WingLoong_I, + Yak_40, + plane_map, +) +from dcs.ships import ( + Armed_speedboat, + Bulk_cargo_ship_Yakushev, + CVN_71_Theodore_Roosevelt, + CVN_72_Abraham_Lincoln, + CVN_73_George_Washington, + CVN_74_John_C__Stennis, + CV_1143_5_Admiral_Kuznetsov, + CV_1143_5_Admiral_Kuznetsov_2017, + Dry_cargo_ship_Ivanov, + LHA_1_Tarawa, + Tanker_Elnya_160, + ship_map, +) +from dcs.task import ( + AWACS, + AntishipStrike, + CAP, + CAS, + CargoTransportation, + Embarking, + GroundAttack, + Intercept, + MainTask, + Nothing, + PinpointStrike, + Reconnaissance, + Refueling, + SEAD, + Task, + Transport, +) +from dcs.terrain.terrain import Airport +from dcs.unit import Ship, Unit, Vehicle +from dcs.unitgroup import ShipGroup, StaticGroup +from dcs.unittype import FlyingType, ShipType, UnitType, VehicleType +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Carriage, + Infantry, + Unarmed, + vehicle_map, +) +import pydcs_extensions.frenchpack.frenchpack as frenchpack from game.factions.australia_2005 import Australia_2005 from game.factions.bluefor_coldwar import BLUEFOR_COLDWAR from game.factions.bluefor_coldwar_a4 import BLUEFOR_COLDWAR_A4 from game.factions.bluefor_coldwar_mods import BLUEFOR_COLDWAR_MODS +from game.factions.bluefor_modern import BLUEFOR_MODERN from game.factions.canada_2005 import Canada_2005 from game.factions.china_2010 import China_2010 from game.factions.france_1995 import France_1995 from game.factions.france_2005 import France_2005 from game.factions.france_modded import France_2005_Modded +from game.factions.germany_1944 import Germany_1944 from game.factions.germany_1944_easy import Germany_1944_Easy from game.factions.germany_1990 import Germany_1990 +from game.factions.india_2010 import India_2010 from game.factions.insurgent import Insurgent from game.factions.insurgent_modded import Insurgent_modded from game.factions.iran_2015 import Iran_2015 from game.factions.israel_1948 import Israel_1948 -from game.factions.israel_1973 import Israel_1973, Israel_1973_NO_WW2_UNITS, Israel_1982 +from game.factions.israel_1973 import ( + Israel_1973, + Israel_1973_NO_WW2_UNITS, + Israel_1982, +) from game.factions.israel_2000 import Israel_2000 from game.factions.italy_1990 import Italy_1990 from game.factions.italy_1990_mb339 import Italy_1990_MB339 @@ -37,35 +179,41 @@ from game.factions.libya_2011 import Libya_2011 from game.factions.netherlands_1990 import Netherlands_1990 from game.factions.north_korea_2000 import NorthKorea_2000 from game.factions.pakistan_2015 import Pakistan_2015 -from game.factions.private_miltary_companies import PMC_WESTERN_B, PMC_RUSSIAN, PMC_WESTERN_A -from game.factions.russia_1975 import Russia_1975 -from game.factions.germany_1944 import Germany_1944 -from game.factions.india_2010 import India_2010 +from game.factions.private_miltary_companies import ( + PMC_RUSSIAN, + PMC_WESTERN_A, + PMC_WESTERN_B, +) from game.factions.russia_1955 import Russia_1955 from game.factions.russia_1965 import Russia_1965 +from game.factions.russia_1975 import Russia_1975 from game.factions.russia_1990 import Russia_1990 from game.factions.russia_2010 import Russia_2010 from game.factions.spain_1990 import Spain_1990 from game.factions.sweden_1990 import Sweden_1990 -from game.factions.syria import Syria_2011, Syria_1967, Syria_1967_WW2_Weapons, Syria_1973, Arab_Armies_1948, Syria_1982 +from game.factions.syria import ( + Arab_Armies_1948, + Syria_1967, + Syria_1967_WW2_Weapons, + Syria_1973, + Syria_1982, + Syria_2011, +) from game.factions.turkey_2005 import Turkey_2005 from game.factions.uae_2005 import UAE_2005 from game.factions.uk_1944 import UK_1944 from game.factions.uk_1990 import UnitedKingdom_1990 from game.factions.ukraine_2010 import Ukraine_2010 from game.factions.us_aggressors import US_Aggressors -from game.factions.usa_1944 import USA_1944, ALLIES_1944 +from game.factions.usa_1944 import ALLIES_1944, USA_1944 from game.factions.usa_1955 import USA_1955 from game.factions.usa_1960 import USA_1960 from game.factions.usa_1965 import USA_1965 from game.factions.usa_1990 import USA_1990 from game.factions.usa_2005 import USA_2005 -from game.factions.bluefor_modern import BLUEFOR_MODERN - # PATCH pydcs data with MODS from pydcs_extensions.a4ec.a4ec import A_4E_C from pydcs_extensions.mb339.mb339 import MB_339PAN -import pydcs_extensions.frenchpack.frenchpack as frenchpack from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M plane_map["A-4E-C"] = A_4E_C @@ -793,13 +941,13 @@ SAM_CONVERT = { """ Units that will always be spawned in the air """ -TAKEOFF_BAN = [ +TAKEOFF_BAN: List[Type[FlyingType]] = [ ] """ Units that will be always spawned in the air if launched from the carrier """ -CARRIER_TAKEOFF_BAN = [ +CARRIER_TAKEOFF_BAN: List[Type[FlyingType]] = [ Su_33, # Kuznecow is bugged in a way that only 2 aircraft could be spawned ] @@ -807,7 +955,7 @@ CARRIER_TAKEOFF_BAN = [ Units separated by country. country : DCS Country name """ -FACTIONS: typing.Dict[str, typing.Dict[str, typing.Any]] = { +FACTIONS: Dict[str, Dict[str, Any]] = { "Bluefor Modern": BLUEFOR_MODERN, "Bluefor Cold War 1970s": BLUEFOR_COLDWAR, @@ -937,7 +1085,7 @@ COMMON_OVERRIDE = { GroundAttack: "STRIKE" } -PLANE_PAYLOAD_OVERRIDES = { +PLANE_PAYLOAD_OVERRIDES: Dict[Type[PlaneType], Dict[Type[Task], str]] = { FA_18C_hornet: { CAP: "CAP HEAVY", @@ -1134,17 +1282,17 @@ LHA_CAPABLE = [ ---------- END OF CONFIGURATION SECTION """ -UnitsDict = typing.Dict[UnitType, int] -PlaneDict = typing.Dict[FlyingType, int] -HeliDict = typing.Dict[HelicopterType, int] -ArmorDict = typing.Dict[VehicleType, int] -ShipDict = typing.Dict[ShipType, int] -AirDefenseDict = typing.Dict[AirDefence, int] +UnitsDict = Dict[UnitType, int] +PlaneDict = Dict[FlyingType, int] +HeliDict = Dict[HelicopterType, int] +ArmorDict = Dict[VehicleType, int] +ShipDict = Dict[ShipType, int] +AirDefenseDict = Dict[AirDefence, int] -AssignedUnitsDict = typing.Dict[typing.Type[UnitType], typing.Tuple[int, int]] -TaskForceDict = typing.Dict[typing.Type[MainTask], AssignedUnitsDict] +AssignedUnitsDict = Dict[Type[UnitType], Tuple[int, int]] +TaskForceDict = Dict[Type[MainTask], AssignedUnitsDict] -StartingPosition = typing.Optional[typing.Union[ShipGroup, StaticGroup, Airport, Point]] +StartingPosition = Union[ShipGroup, StaticGroup, Airport, Point] def upgrade_to_supercarrier(unit, name: str): @@ -1162,7 +1310,7 @@ def upgrade_to_supercarrier(unit, name: str): else: return unit -def unit_task(unit: UnitType) -> Task: +def unit_task(unit: UnitType) -> Optional[Task]: for task, units in UNIT_BY_TASK.items(): if unit in units: return task @@ -1173,10 +1321,10 @@ def unit_task(unit: UnitType) -> Task: print(unit.name + " cause issue") return None -def find_unittype(for_task: Task, country_name: str) -> typing.List[UnitType]: +def find_unittype(for_task: Task, country_name: str) -> List[UnitType]: return [x for x in UNIT_BY_TASK[for_task] if x in FACTIONS[country_name]["units"]] -def find_infantry(country_name: str) -> typing.List[UnitType]: +def find_infantry(country_name: str) -> List[UnitType]: inf = [ Infantry.Paratrooper_AKS, Infantry.Paratrooper_AKS, Infantry.Paratrooper_AKS, Infantry.Paratrooper_AKS, Infantry.Paratrooper_AKS, Infantry.Soldier_RPG, @@ -1199,7 +1347,7 @@ def unit_type_name(unit_type) -> str: def unit_type_name_2(unit_type) -> str: return unit_type.name and unit_type.name or unit_type.id -def unit_type_from_name(name: str) -> UnitType: +def unit_type_from_name(name: str) -> Optional[UnitType]: if name in vehicle_map: return vehicle_map[name] elif name in plane_map: @@ -1232,7 +1380,7 @@ def task_name(task) -> str: return task.name -def choose_units(for_task: Task, factor: float, count: int, country: str) -> typing.Collection[UnitType]: +def choose_units(for_task: Task, factor: float, count: int, country: str) -> List[UnitType]: suitable_unittypes = find_unittype(for_task, country) suitable_unittypes = [x for x in suitable_unittypes if x not in helicopter_map.values()] suitable_unittypes.sort(key=lambda x: PRICES[x]) @@ -1258,7 +1406,7 @@ def unitdict_merge(a: UnitsDict, b: UnitsDict) -> UnitsDict: def unitdict_split(unit_dict: UnitsDict, count: int): - buffer_dict = {} + buffer_dict: Dict[UnitType, int] = {} for unit_type, unit_count in unit_dict.items(): for _ in range(unit_count): unitdict_append(buffer_dict, unit_type, 1) @@ -1281,7 +1429,7 @@ def unitdict_restrict_count(unit_dict: UnitsDict, total_count: int) -> UnitsDict return {} -def assigned_units_split(fd: AssignedUnitsDict) -> typing.Tuple[PlaneDict, PlaneDict]: +def assigned_units_split(fd: AssignedUnitsDict) -> Tuple[PlaneDict, PlaneDict]: return {k: v1 for k, (v1, v2) in fd.items()}, {k: v2 for k, (v1, v2) in fd.items()}, @@ -1290,7 +1438,7 @@ def assigned_units_from(d: PlaneDict) -> AssignedUnitsDict: def assignedunits_split_to_count(dict: AssignedUnitsDict, count: int): - buffer_dict = {} + buffer_dict: Dict[Type[UnitType], Tuple[int, int]] = {} for unit_type, (unit_count, client_count) in dict.items(): for _ in range(unit_count): new_count, new_client_count = buffer_dict.get(unit_type, (0, 0)) diff --git a/game/event/event.py b/game/event/event.py index ea5cbb4c..0af3852c 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -1,13 +1,25 @@ +from __future__ import annotations + +import logging +import math +from typing import Dict, List, Optional, Type, TYPE_CHECKING + +from dcs.mapping import Point +from dcs.task import Task from dcs.unittype import UnitType -from game import * -from game import persistency +from game import db, persistency from game.debriefing import Debriefing from game.infos.information import Information +from game.operation.operation import Operation from gen.environmentgen import EnvironmentSettings -from theater import * +from gen.ground_forces.combat_stance import CombatStance +from theater import ControlPoint from theater.start_generator import generate_airbase_defense_group +if TYPE_CHECKING: + from ..game import Game + DIFFICULTY_LOG_BASE = 1.1 EVENT_DEPARTURE_MAX_DISTANCE = 340000 @@ -26,7 +38,6 @@ class Event: game = None # type: Game location = None # type: Point from_cp = None # type: ControlPoint - departure_cp = None # type: ControlPoint to_cp = None # type: ControlPoint operation = None # type: Operation @@ -36,7 +47,7 @@ class Event: def __init__(self, game, from_cp: ControlPoint, target_cp: ControlPoint, location: Point, attacker_name: str, defender_name: str): self.game = game - self.departure_cp = None + self.departure_cp: Optional[ControlPoint] = None self.from_cp = from_cp self.to_cp = target_cp self.location = location @@ -48,14 +59,14 @@ class Event: return self.attacker_name == self.game.player_name @property - def enemy_cp(self) -> ControlPoint: + def enemy_cp(self) -> Optional[ControlPoint]: if self.attacker_name == self.game.player_name: return self.to_cp else: return self.departure_cp @property - def tasks(self) -> typing.Collection[typing.Type[Task]]: + def tasks(self) -> List[Type[Task]]: return [] @property @@ -80,18 +91,6 @@ class Event: def is_successfull(self, debriefing: Debriefing) -> bool: return self.operation.is_successfull(debriefing) - def player_attacking(self, cp: ControlPoint, flights: db.TaskForceDict): - if self.is_player_attacking: - self.departure_cp = cp - else: - self.to_cp = cp - - def player_defending(self, cp: ControlPoint, flights: db.TaskForceDict): - if self.is_player_attacking: - self.departure_cp = cp - else: - self.to_cp = cp - def generate(self): self.operation.is_awacs_enabled = self.is_awacs_enabled self.operation.ca_slots = self.ca_slots @@ -242,7 +241,7 @@ class Event: for enemy_cp in enemy_cps: print("Compute frontline progression for : " + cp.name + " to " + enemy_cp.name) - delta = 0 + delta = 0.0 player_won = True ally_casualties = killed_unit_count_by_cp[cp.id] enemy_casualties = killed_unit_count_by_cp[enemy_cp.id] @@ -365,7 +364,6 @@ class Event: class UnitsDeliveryEvent(Event): informational = True - units = None # type: typing.Dict[UnitType, int] def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint, game): super(UnitsDeliveryEvent, self).__init__(game=game, @@ -375,12 +373,12 @@ class UnitsDeliveryEvent(Event): attacker_name=attacker_name, defender_name=defender_name) - self.units = {} + self.units: Dict[UnitType, int] = {} def __str__(self): return "Pending delivery to {}".format(self.to_cp) - def deliver(self, units: typing.Dict[UnitType, int]): + def deliver(self, units: Dict[UnitType, int]): for k, v in units.items(): self.units[k] = self.units.get(k, 0) + v diff --git a/game/event/frontlineattack.py b/game/event/frontlineattack.py index bde6c62d..0046526d 100644 --- a/game/event/frontlineattack.py +++ b/game/event/frontlineattack.py @@ -1,12 +1,17 @@ -from game.event import * +from typing import List, Type + +from dcs.task import CAP, CAS, Task + +from game import db from game.operation.frontlineattack import FrontlineAttackOperation +from .event import Event from ..debriefing import Debriefing class FrontlineAttackEvent(Event): @property - def tasks(self) -> typing.Collection[typing.Type[Task]]: + def tasks(self) -> List[Type[Task]]: if self.is_player_attacking: return [CAS, CAP] else: @@ -34,6 +39,7 @@ class FrontlineAttackEvent(Event): self.to_cp.base.affect_strength(-0.1) def player_attacking(self, flights: db.TaskForceDict): + assert self.departure_cp is not None op = FrontlineAttackOperation(game=self.game, attacker_name=self.attacker_name, defender_name=self.defender_name, @@ -41,13 +47,3 @@ class FrontlineAttackEvent(Event): departure_cp=self.departure_cp, to_cp=self.to_cp) self.operation = op - - def player_defending(self, flights: db.TaskForceDict): - op = FrontlineAttackOperation(game=self.game, - attacker_name=self.attacker_name, - defender_name=self.defender_name, - from_cp=self.from_cp, - departure_cp=self.departure_cp, - to_cp=self.to_cp) - self.operation = op - diff --git a/game/factions/australia_2005.py b/game/factions/australia_2005.py index df4972e6..c9cfb320 100644 --- a/game/factions/australia_2005.py +++ b/game/factions/australia_2005.py @@ -1,7 +1,27 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_1W, + UH_1H, +) +from dcs.planes import ( + C_130, + E_3A, + FA_18C_hornet, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Ticonderoga_class, + USS_Arleigh_Burke_IIa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Australia_2005 = { "country": "Australia", diff --git a/game/factions/bluefor_coldwar.py b/game/factions/bluefor_coldwar.py index 5db15d73..c241bbae 100644 --- a/game/factions/bluefor_coldwar.py +++ b/game/factions/bluefor_coldwar.py @@ -1,7 +1,30 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + SA342L, + SA342M, + UH_1H, +) +from dcs.planes import ( + AJS37, + A_10A, + C_130, + E_3A, + F_14B, + F_4E, + F_5E_3, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) BLUEFOR_COLDWAR = { "country": "Combined Joint Task Forces Blue", diff --git a/game/factions/bluefor_coldwar_a4.py b/game/factions/bluefor_coldwar_a4.py index 74983134..ce6cf016 100644 --- a/game/factions/bluefor_coldwar_a4.py +++ b/game/factions/bluefor_coldwar_a4.py @@ -1,7 +1,31 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + SA342L, + SA342M, + UH_1H, +) +from dcs.planes import ( + AJS37, + A_10A, + C_130, + E_3A, + F_14B, + F_4E, + F_5E_3, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Ticonderoga_class, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) from pydcs_extensions.a4ec.a4ec import A_4E_C diff --git a/game/factions/bluefor_coldwar_mods.py b/game/factions/bluefor_coldwar_mods.py index aece4e46..a395fc48 100644 --- a/game/factions/bluefor_coldwar_mods.py +++ b/game/factions/bluefor_coldwar_mods.py @@ -1,7 +1,31 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + SA342L, + SA342M, + UH_1H, +) +from dcs.planes import ( + AJS37, + A_10A, + C_130, + E_3A, + F_14B, + F_4E, + F_5E_3, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Ticonderoga_class, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) from pydcs_extensions.a4ec.a4ec import A_4E_C from pydcs_extensions.mb339.mb339 import MB_339PAN diff --git a/game/factions/bluefor_modern.py b/game/factions/bluefor_modern.py index 8db0ad89..9f97827b 100644 --- a/game/factions/bluefor_modern.py +++ b/game/factions/bluefor_modern.py @@ -1,7 +1,45 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_64D, + Ka_50, + SA342L, + SA342M, + UH_1H, +) +from dcs.planes import ( + AJS37, + AV8BNA, + A_10A, + A_10C, + A_10C_2, + C_130, + E_3A, + FA_18C_hornet, + F_14B, + F_15C, + F_16C_50, + F_5E_3, + JF_17, + KC130, + KC_135, + M_2000C, + Su_25T, + Su_27, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, + USS_Arleigh_Burke_IIa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) BLUEFOR_MODERN = { "country": "Combined Joint Task Forces Blue", diff --git a/game/factions/canada_2005.py b/game/factions/canada_2005.py index ea4497ca..7a664709 100644 --- a/game/factions/canada_2005.py +++ b/game/factions/canada_2005.py @@ -1,7 +1,26 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + UH_1H, +) +from dcs.planes import ( + C_130, + E_3A, + FA_18C_hornet, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Ticonderoga_class, + USS_Arleigh_Burke_IIa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Canada_2005 = { "country": "Canada", diff --git a/game/factions/china_2010.py b/game/factions/china_2010.py index 0d98d1b9..577fb33d 100644 --- a/game/factions/china_2010.py +++ b/game/factions/china_2010.py @@ -1,7 +1,38 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + Mi_28N, + Mi_8MT, +) +from dcs.planes import ( + An_26B, + An_30M, + IL_76MD, + IL_78M, + JF_17, + J_11A, + KJ_2000, + MiG_21Bis, + Su_30, + Su_33, + WingLoong_I, + Yak_40, +) +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + Tanker_Elnya_160, + Type_052B_Destroyer, + Type_052C_Destroyer, + Type_054A_Frigate, + Type_071_Amphibious_Transport_Dock, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) China_2010 = { "country": "China", diff --git a/game/factions/france_1995.py b/game/factions/france_1995.py index acf56495..a14f24e5 100644 --- a/game/factions/france_1995.py +++ b/game/factions/france_1995.py @@ -1,7 +1,28 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + SA342L, + SA342M, + SA342Mistral, +) +from dcs.planes import ( + C_130, + E_3A, + KC130, + KC_135, + M_2000C, + Mirage_2000_5, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) France_1995 = { "country": "France", diff --git a/game/factions/france_2005.py b/game/factions/france_2005.py index b2f4b87a..28c00ae4 100644 --- a/game/factions/france_2005.py +++ b/game/factions/france_2005.py @@ -1,7 +1,31 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + SA342L, + SA342M, + SA342Mistral, +) +from dcs.planes import ( + C_130, + E_3A, + FA_18C_hornet, + KC130, + KC_135, + M_2000C, + Mirage_2000_5, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) France_2005 = { "country": "France", diff --git a/game/factions/france_modded.py b/game/factions/france_modded.py index ad0f7de5..8283d090 100644 --- a/game/factions/france_modded.py +++ b/game/factions/france_modded.py @@ -1,10 +1,33 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + SA342L, + SA342M, + SA342Mistral, +) +from dcs.planes import ( + C_130, + E_3A, + KC130, + KC_135, + M_2000C, + Mirage_2000_5, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) import pydcs_extensions.frenchpack.frenchpack as frenchpack -from pydcs_extensions.rafale.rafale import Rafale_M, Rafale_A_S +from pydcs_extensions.rafale.rafale import Rafale_A_S, Rafale_M France_2005_Modded = { "country": "France", diff --git a/game/factions/germany_1944.py b/game/factions/germany_1944.py index 9123b350..c63f88f4 100644 --- a/game/factions/germany_1944.py +++ b/game/factions/germany_1944.py @@ -1,5 +1,16 @@ -from dcs.planes import * -from dcs.vehicles import * +from dcs.planes import ( + Bf_109K_4, + FW_190A8, + FW_190D9, + Ju_88A4, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) from game.data.building_data import WW2_GERMANY_BUILDINGS from game.data.doctrine import WWII_DOCTRINE diff --git a/game/factions/germany_1944_easy.py b/game/factions/germany_1944_easy.py index b79d45f0..8be93457 100644 --- a/game/factions/germany_1944_easy.py +++ b/game/factions/germany_1944_easy.py @@ -1,5 +1,16 @@ -from dcs.planes import * -from dcs.vehicles import * +from dcs.planes import ( + Bf_109K_4, + FW_190A8, + FW_190D9, + Ju_88A4, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) from game.data.building_data import WW2_GERMANY_BUILDINGS from game.data.doctrine import WWII_DOCTRINE diff --git a/game/factions/germany_1990.py b/game/factions/germany_1990.py index ae1f0668..54432ef4 100644 --- a/game/factions/germany_1990.py +++ b/game/factions/germany_1990.py @@ -1,7 +1,28 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + SA342L, + SA342M, + UH_1H, +) +from dcs.planes import ( + C_130, + E_3A, + F_4E, + KC130, + KC_135, + MiG_29G, + Tornado_IDS, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Germany_1990 = { "country": "Germany", diff --git a/game/factions/india_2010.py b/game/factions/india_2010.py index 2dc756ec..756faa23 100644 --- a/game/factions/india_2010.py +++ b/game/factions/india_2010.py @@ -1,7 +1,32 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_64A, + Mi_8MT, +) +from dcs.planes import ( + C_130, + E_3A, + KC130, + KC_135, + M_2000C, + MiG_21Bis, + MiG_27K, + MiG_29S, + Mirage_2000_5, + Su_30, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + CV_1143_5_Admiral_Kuznetsov, + FSG_1241_1MP_Molniya, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) India_2010 = { "country": "India", diff --git a/game/factions/insurgent.py b/game/factions/insurgent.py index d94603c6..66ae3459 100644 --- a/game/factions/insurgent.py +++ b/game/factions/insurgent.py @@ -1,7 +1,14 @@ -from dcs.vehicles import * -from dcs.ships import * -from dcs.planes import * -from dcs.helicopters import * +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + Dry_cargo_ship_Ivanov, + Tanker_Elnya_160, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Insurgent = { "country": "Insurgents", diff --git a/game/factions/insurgent_modded.py b/game/factions/insurgent_modded.py index 39e1e174..b19b4344 100644 --- a/game/factions/insurgent_modded.py +++ b/game/factions/insurgent_modded.py @@ -1,8 +1,21 @@ -from dcs.ships import * -from dcs.vehicles import * +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + Dry_cargo_ship_Ivanov, + Tanker_Elnya_160, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) -from pydcs_extensions.frenchpack.frenchpack import DIM__TOYOTA_BLUE, DIM__TOYOTA_DESERT, DIM__TOYOTA_GREEN, \ - DIM__KAMIKAZE +from pydcs_extensions.frenchpack.frenchpack import ( + DIM__KAMIKAZE, + DIM__TOYOTA_BLUE, + DIM__TOYOTA_DESERT, + DIM__TOYOTA_GREEN, +) Insurgent_modded = { "country": "Insurgents", diff --git a/game/factions/iran_2015.py b/game/factions/iran_2015.py index 56751a2c..53f20dd6 100644 --- a/game/factions/iran_2015.py +++ b/game/factions/iran_2015.py @@ -1,7 +1,35 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + Mi_24V, + Mi_28N, +) +from dcs.planes import ( + A_50, + An_26B, + An_30M, + F_14B, + F_4E, + F_5E_3, + IL_76MD, + IL_78M, + MiG_21Bis, + MiG_29A, + Su_17M4, + Su_24M, + Su_25, + Yak_40, +) +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + Tanker_Elnya_160, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Iran_2015 = { "country": "Iran", diff --git a/game/factions/israel_1948.py b/game/factions/israel_1948.py index ffa57fcb..bc3b615c 100644 --- a/game/factions/israel_1948.py +++ b/game/factions/israel_1948.py @@ -1,6 +1,20 @@ -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.planes import ( + B_17G, + Bf_109K_4, + P_51D, + P_51D_30_NA, + SpitfireLFMkIX, + SpitfireLFMkIXCW, +) +from dcs.ships import ( + Armed_speedboat, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Israel_1948 = { "country": "Israel", diff --git a/game/factions/israel_1973.py b/game/factions/israel_1973.py index 00624ec9..3bfa5d15 100644 --- a/game/factions/israel_1973.py +++ b/game/factions/israel_1973.py @@ -1,7 +1,26 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_1W, + UH_1H, +) +from dcs.planes import ( + C_130, + E_3A, + F_15C, + F_16A, + F_16C_50, + F_4E, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) from pydcs_extensions.a4ec.a4ec import A_4E_C diff --git a/game/factions/israel_2000.py b/game/factions/israel_2000.py index 6c0db9c0..d87460f9 100644 --- a/game/factions/israel_2000.py +++ b/game/factions/israel_2000.py @@ -1,7 +1,29 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_1W, + AH_64D, +) +from dcs.planes import ( + C_130, + E_3A, + F_15C, + F_15E, + F_16C_50, + F_4E, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) Israel_2000 = { "country": "Israel", diff --git a/game/factions/italy_1990.py b/game/factions/italy_1990.py index 2c2175a8..267cd611 100644 --- a/game/factions/italy_1990.py +++ b/game/factions/italy_1990.py @@ -1,7 +1,28 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_1W, + UH_1H, +) +from dcs.planes import ( + AV8BNA, + C_130, + E_3A, + KC_135, + S_3B_Tanker, + Tornado_IDS, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Italy_1990 = { "country": "Italy", diff --git a/game/factions/italy_1990_mb339.py b/game/factions/italy_1990_mb339.py index 92307749..9d594817 100644 --- a/game/factions/italy_1990_mb339.py +++ b/game/factions/italy_1990_mb339.py @@ -1,7 +1,28 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_1W, + UH_1H, +) +from dcs.planes import ( + AV8BNA, + C_130, + E_3A, + KC_135, + S_3B_Tanker, + Tornado_IDS, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) from pydcs_extensions.mb339.mb339 import MB_339PAN diff --git a/game/factions/japan_2005.py b/game/factions/japan_2005.py index c9657348..d33800ff 100644 --- a/game/factions/japan_2005.py +++ b/game/factions/japan_2005.py @@ -1,7 +1,24 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_1W, + AH_64D, +) +from dcs.planes import ( + C_130, + E_3A, + F_15C, + F_16C_50, + F_4E, + KC130, + KC_135, +) +from dcs.ships import LHA_1_Tarawa, Ticonderoga_class, USS_Arleigh_Burke_IIa +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) Japan_2005 = { "country": "Japan", diff --git a/game/factions/libya_2011.py b/game/factions/libya_2011.py index 688b4877..4de5b42c 100644 --- a/game/factions/libya_2011.py +++ b/game/factions/libya_2011.py @@ -1,6 +1,25 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.vehicles import * +from dcs.helicopters import ( + Mi_24V, +) +from dcs.planes import ( + A_50, + An_26B, + An_30M, + IL_76MD, + IL_78M, + MiG_21Bis, + MiG_23MLD, + Su_17M4, + Su_24M, + Yak_40, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) Libya_2011 = { "country": "Libya", diff --git a/game/factions/netherlands_1990.py b/game/factions/netherlands_1990.py index b32fe7d0..48c916bd 100644 --- a/game/factions/netherlands_1990.py +++ b/game/factions/netherlands_1990.py @@ -1,7 +1,25 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_64A, +) +from dcs.planes import ( + C_130, + E_3A, + F_16C_50, + F_5E_3, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Netherlands_1990 = { "country": "The Netherlands", diff --git a/game/factions/north_korea_2000.py b/game/factions/north_korea_2000.py index dd588f92..15d1f587 100644 --- a/game/factions/north_korea_2000.py +++ b/game/factions/north_korea_2000.py @@ -1,7 +1,33 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + Mi_24V, + Mi_8MT, +) +from dcs.planes import ( + A_50, + An_26B, + An_30M, + IL_76MD, + IL_78M, + MiG_15bis, + MiG_19P, + MiG_21Bis, + MiG_23MLD, + MiG_29A, + Su_25, + Yak_40, +) +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + Tanker_Elnya_160, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) NorthKorea_2000 = { "country": "North Korea", diff --git a/game/factions/pakistan_2015.py b/game/factions/pakistan_2015.py index 67bfa2aa..8d7c6190 100644 --- a/game/factions/pakistan_2015.py +++ b/game/factions/pakistan_2015.py @@ -1,7 +1,25 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_1W, + UH_1H, +) +from dcs.planes import ( + E_3A, + F_16C_50, + IL_78M, + JF_17, + MiG_19P, + MiG_21Bis, + WingLoong_I, +) +from dcs.ships import ( + Armed_speedboat, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Pakistan_2015 = { "country": "Pakistan", diff --git a/game/factions/private_miltary_companies.py b/game/factions/private_miltary_companies.py index 4f2860ca..23fbcbdd 100644 --- a/game/factions/private_miltary_companies.py +++ b/game/factions/private_miltary_companies.py @@ -1,7 +1,25 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + Ka_50, + Mi_24V, + Mi_8MT, + OH_58D, + SA342M, + UH_1H, +) +from dcs.planes import ( + C_101CC, + L_39C, + L_39ZA, +) +from dcs.ships import ( + Armed_speedboat, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) from pydcs_extensions.mb339.mb339 import MB_339PAN diff --git a/game/factions/russia_1955.py b/game/factions/russia_1955.py index dcaeec68..5730bd9d 100644 --- a/game/factions/russia_1955.py +++ b/game/factions/russia_1955.py @@ -1,6 +1,11 @@ -from dcs.planes import MiG_15bis, IL_76MD, IL_78M, An_26B, An_30M, Yak_40 -from dcs.ships import CV_1143_5_Admiral_Kuznetsov, Bulk_cargo_ship_Yakushev, Dry_cargo_ship_Ivanov, Tanker_Elnya_160 -from dcs.vehicles import AirDefence, Armor, Unarmed, Infantry, Artillery +from dcs.planes import An_26B, An_30M, IL_76MD, IL_78M, MiG_15bis, Yak_40 +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + Tanker_Elnya_160, +) +from dcs.vehicles import AirDefence, Armor, Artillery, Infantry, Unarmed Russia_1955 = { "country": "Russia", diff --git a/game/factions/russia_1965.py b/game/factions/russia_1965.py index bc5762c6..9d88d251 100644 --- a/game/factions/russia_1965.py +++ b/game/factions/russia_1965.py @@ -1,7 +1,22 @@ from dcs.helicopters import Mi_8MT -from dcs.planes import MiG_15bis, MiG_19P, MiG_21Bis, IL_76MD, IL_78M, An_26B, An_30M, Yak_40, A_50 -from dcs.ships import CV_1143_5_Admiral_Kuznetsov, Bulk_cargo_ship_Yakushev, Dry_cargo_ship_Ivanov, Tanker_Elnya_160 -from dcs.vehicles import AirDefence, Armor, Unarmed, Infantry, Artillery +from dcs.planes import ( + A_50, + An_26B, + An_30M, + IL_76MD, + IL_78M, + MiG_15bis, + MiG_19P, + MiG_21Bis, + Yak_40, +) +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + Tanker_Elnya_160, +) +from dcs.vehicles import AirDefence, Armor, Artillery, Infantry, Unarmed Russia_1965 = { "country": "Russia", diff --git a/game/factions/russia_1975.py b/game/factions/russia_1975.py index db6a50ae..b8a75437 100644 --- a/game/factions/russia_1975.py +++ b/game/factions/russia_1975.py @@ -1,8 +1,31 @@ -from dcs.helicopters import Mi_8MT, Mi_24V -from dcs.planes import MiG_21Bis, MiG_23MLD, MiG_25PD, MiG_29A, Su_17M4, Su_24M, Su_25, IL_76MD, IL_78M, An_26B, An_30M, \ - Yak_40, A_50 -from dcs.ships import * -from dcs.vehicles import AirDefence, Armor, Unarmed, Infantry, Artillery +from dcs.helicopters import ( + Mi_24V, + Mi_8MT, +) +from dcs.planes import ( + A_50, + An_26B, + An_30M, + IL_76MD, + IL_78M, + MiG_21Bis, + MiG_23MLD, + MiG_25PD, + MiG_29A, + Su_17M4, + Su_24M, + Su_25, + Yak_40, +) +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CGN_1144_2_Pyotr_Velikiy, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + FF_1135M_Rezky, + Tanker_Elnya_160, +) +from dcs.vehicles import AirDefence, Armor, Artillery, Infantry, Unarmed Russia_1975 = { "country": "Russia", diff --git a/game/factions/russia_1990.py b/game/factions/russia_1990.py index ee2758a5..747024a8 100644 --- a/game/factions/russia_1990.py +++ b/game/factions/russia_1990.py @@ -1,7 +1,39 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + Ka_50, + Mi_24V, + Mi_8MT, +) +from dcs.planes import ( + A_50, + An_26B, + An_30M, + IL_76MD, + IL_78M, + MiG_23MLD, + MiG_25PD, + MiG_29A, + MiG_29S, + MiG_31, + Su_24M, + Su_25, + Su_27, + Yak_40, +) +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + FF_1135M_Rezky, + FSG_1241_1MP_Molniya, + Tanker_Elnya_160, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) Russia_1990 = { "country": "Russia", diff --git a/game/factions/russia_2010.py b/game/factions/russia_2010.py index cc45f062..13adefb6 100644 --- a/game/factions/russia_2010.py +++ b/game/factions/russia_2010.py @@ -1,7 +1,42 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + Ka_50, + Mi_24V, + Mi_28N, + Mi_8MT, +) +from dcs.planes import ( + A_50, + An_26B, + An_30M, + IL_76MD, + IL_78M, + L_39ZA, + MiG_29S, + MiG_31, + Su_24M, + Su_25, + Su_25T, + Su_27, + Su_30, + Su_33, + Su_34, + Yak_40, +) +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + FF_1135M_Rezky, + FSG_1241_1MP_Molniya, + Tanker_Elnya_160, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) Russia_2010 = { "country": "Russia", diff --git a/game/factions/spain_1990.py b/game/factions/spain_1990.py index f016cb8a..246484a4 100644 --- a/game/factions/spain_1990.py +++ b/game/factions/spain_1990.py @@ -1,6 +1,26 @@ -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.planes import ( + AV8BNA, + C_101CC, + C_130, + E_3A, + FA_18C_hornet, + F_5E_3, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Spain_1990 = { "country": "Spain", diff --git a/game/factions/sweden_1990.py b/game/factions/sweden_1990.py index ebc754f9..058f1478 100644 --- a/game/factions/sweden_1990.py +++ b/game/factions/sweden_1990.py @@ -1,7 +1,21 @@ -from dcs.vehicles import * -from dcs.ships import * -from dcs.planes import * -from dcs.helicopters import * +from dcs.helicopters import ( + UH_1H, +) +from dcs.planes import ( + AJS37, +) +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + Tanker_Elnya_160, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Sweden_1990 = { "country": "Sweden", diff --git a/game/factions/syria.py b/game/factions/syria.py index de082320..f7017e86 100644 --- a/game/factions/syria.py +++ b/game/factions/syria.py @@ -1,6 +1,35 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.vehicles import * +from dcs.helicopters import ( + Mi_24V, + Mi_8MT, + SA342L, + SA342M, +) +from dcs.planes import ( + A_50, + An_26B, + An_30M, + IL_76MD, + IL_78M, + L_39ZA, + MiG_15bis, + MiG_19P, + MiG_21Bis, + MiG_23MLD, + MiG_25PD, + MiG_29S, + SpitfireLFMkIX, + SpitfireLFMkIXCW, + Su_17M4, + Su_24M, + Yak_40, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) Syria_2011 = { "country": "Syria", diff --git a/game/factions/turkey_2005.py b/game/factions/turkey_2005.py index 02b0500d..be68334c 100644 --- a/game/factions/turkey_2005.py +++ b/game/factions/turkey_2005.py @@ -1,7 +1,26 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_1W, + UH_1H, +) +from dcs.planes import ( + C_130, + E_3A, + F_16C_50, + F_4E, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Turkey_2005 = { "country": "Turkey", diff --git a/game/factions/uae_2005.py b/game/factions/uae_2005.py index cc412f06..d6240332 100644 --- a/game/factions/uae_2005.py +++ b/game/factions/uae_2005.py @@ -1,7 +1,27 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_64D, +) +from dcs.planes import ( + C_130, + E_3A, + F_16C_50, + KC130, + KC_135, + M_2000C, + Mirage_2000_5, + WingLoong_I, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) UAE_2005 = { "country": "United Arab Emirates", diff --git a/game/factions/uk_1944.py b/game/factions/uk_1944.py index 7798d714..2620fc86 100644 --- a/game/factions/uk_1944.py +++ b/game/factions/uk_1944.py @@ -1,6 +1,19 @@ -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.planes import ( + A_20G, + B_17G, + P_47D_30, + P_51D, + P_51D_30_NA, + SpitfireLFMkIX, + SpitfireLFMkIXCW, +) +from dcs.ships import LCVP__Higgins_boat, LST_Mk_II, LS_Samuel_Chase +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) from game.data.building_data import WW2_ALLIES_BUILDINGS from game.data.doctrine import WWII_DOCTRINE diff --git a/game/factions/uk_1990.py b/game/factions/uk_1990.py index f2bcc57a..4855059d 100644 --- a/game/factions/uk_1990.py +++ b/game/factions/uk_1990.py @@ -1,7 +1,29 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_64A, + SA342M, +) +from dcs.planes import ( + AV8BNA, + C_130, + E_3A, + F_4E, + KC130, + KC_135, + Tornado_GR4, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) UnitedKingdom_1990 = { "country": "UK", diff --git a/game/factions/ukraine_2010.py b/game/factions/ukraine_2010.py index cd5149b6..de030137 100644 --- a/game/factions/ukraine_2010.py +++ b/game/factions/ukraine_2010.py @@ -1,7 +1,33 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + Mi_24V, + Mi_8MT, +) +from dcs.planes import ( + A_50, + An_26B, + An_30M, + IL_76MD, + IL_78M, + L_39ZA, + MiG_29S, + Su_24M, + Su_25, + Su_25T, + Su_27, + Yak_40, +) +from dcs.ships import ( + Bulk_cargo_ship_Yakushev, + CV_1143_5_Admiral_Kuznetsov, + Dry_cargo_ship_Ivanov, + Tanker_Elnya_160, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) Ukraine_2010 = { "country": "Ukraine", diff --git a/game/factions/us_aggressors.py b/game/factions/us_aggressors.py index ab4e6ffd..650c09cd 100644 --- a/game/factions/us_aggressors.py +++ b/game/factions/us_aggressors.py @@ -1,7 +1,36 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_64D, + Ka_50, + SA342L, + SA342M, + UH_1H, +) +from dcs.planes import ( + C_130, + E_3A, + FA_18C_hornet, + F_15C, + F_16C_50, + F_5E_3, + KC130, + KC_135, + Su_27, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, + USS_Arleigh_Burke_IIa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) US_Aggressors = { "country": "USAF Aggressors", diff --git a/game/factions/usa_1944.py b/game/factions/usa_1944.py index 29e07372..7b99bd42 100644 --- a/game/factions/usa_1944.py +++ b/game/factions/usa_1944.py @@ -1,6 +1,20 @@ -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.planes import ( + A_20G, + B_17G, + P_47D_30, + P_51D, + P_51D_30_NA, + SpitfireLFMkIX, + SpitfireLFMkIXCW, +) +from dcs.ships import LCVP__Higgins_boat, LST_Mk_II, LS_Samuel_Chase +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) from game.data.building_data import WW2_ALLIES_BUILDINGS from game.data.doctrine import WWII_DOCTRINE diff --git a/game/factions/usa_1955.py b/game/factions/usa_1955.py index efa0af47..1943544b 100644 --- a/game/factions/usa_1955.py +++ b/game/factions/usa_1955.py @@ -1,7 +1,22 @@ -from dcs.vehicles import * -from dcs.ships import * -from dcs.planes import * -from dcs.helicopters import * +from dcs.planes import ( + C_130, + E_3A, + F_86F_Sabre, + KC130, + KC_135, + P_51D, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) USA_1955 = { "country": "USA", diff --git a/game/factions/usa_1960.py b/game/factions/usa_1960.py index e2b64bd1..ee162d04 100644 --- a/game/factions/usa_1960.py +++ b/game/factions/usa_1960.py @@ -1,7 +1,25 @@ -from dcs.vehicles import * -from dcs.ships import * -from dcs.planes import * -from dcs.helicopters import * +from dcs.helicopters import ( + UH_1H, +) +from dcs.planes import ( + C_130, + E_3A, + F_86F_Sabre, + KC130, + KC_135, + P_51D, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) USA_1960 = { "country": "USA", diff --git a/game/factions/usa_1965.py b/game/factions/usa_1965.py index 59dc651a..cba61391 100644 --- a/game/factions/usa_1965.py +++ b/game/factions/usa_1965.py @@ -1,7 +1,26 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + UH_1H, +) +from dcs.planes import ( + B_52H, + C_130, + E_3A, + F_4E, + F_5E_3, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) USA_1965 = { "country": "USA", diff --git a/game/factions/usa_1990.py b/game/factions/usa_1990.py index df2b37df..4014237a 100644 --- a/game/factions/usa_1990.py +++ b/game/factions/usa_1990.py @@ -1,7 +1,34 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_64A, + UH_1H, +) +from dcs.planes import ( + AV8BNA, + A_10A, + C_130, + E_3A, + FA_18C_hornet, + F_14B, + F_15C, + F_15E, + F_16C_50, + KC130, + KC_135, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Oliver_Hazzard_Perry_class, + Ticonderoga_class, + USS_Arleigh_Burke_IIa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Infantry, + Unarmed, +) USA_1990 = { "country": "USA", diff --git a/game/factions/usa_2005.py b/game/factions/usa_2005.py index d6b63a58..5b9e03ca 100644 --- a/game/factions/usa_2005.py +++ b/game/factions/usa_2005.py @@ -1,7 +1,36 @@ -from dcs.helicopters import * -from dcs.planes import * -from dcs.ships import * -from dcs.vehicles import * +from dcs.helicopters import ( + AH_64D, + UH_1H, +) +from dcs.planes import ( + AV8BNA, + A_10C, + A_10C_2, + C_130, + E_3A, + FA_18C_hornet, + F_14B, + F_15C, + F_15E, + F_16C_50, + KC130, + KC_135, + MQ_9_Reaper, +) +from dcs.ships import ( + Armed_speedboat, + CVN_74_John_C__Stennis, + LHA_1_Tarawa, + Ticonderoga_class, + USS_Arleigh_Burke_IIa, +) +from dcs.vehicles import ( + AirDefence, + Armor, + Artillery, + Infantry, + Unarmed, +) USA_2005 = { "country": "USA", diff --git a/game/game.py b/game/game.py index d1177f62..57fabfd6 100644 --- a/game/game.py +++ b/game/game.py @@ -1,6 +1,18 @@ +import logging +import math +import random +import sys from datetime import datetime, timedelta +from typing import Any, Dict, List -from game.db import REWARDS, PLAYER_BUDGET_BASE, sys +from dcs.action import Coalition +from dcs.mapping import Point +from dcs.task import CAP, CAS, PinpointStrike, Task +from dcs.unittype import UnitType +from dcs.vehicles import AirDefence + +from game import db +from game.db import PLAYER_BUDGET_BASE, REWARDS from game.inventory import GlobalAircraftInventory from game.models.game_stats import GameStats from gen.ato import AirTaskingOrder @@ -8,10 +20,15 @@ from gen.conflictgen import Conflict from gen.flights.ai_flight_planner import CoalitionMissionPlanner from gen.flights.closestairfields import ObjectiveDistanceCache from gen.ground_forces.ai_ground_planner import GroundPlanner -from .event import * +from theater import ConflictTheater, ControlPoint +from theater.conflicttheater import IMPORTANCE_HIGH, IMPORTANCE_LOW +from . import persistency +from .debriefing import Debriefing +from .event.event import Event, UnitsDeliveryEvent +from .event.frontlineattack import FrontlineAttackEvent +from .infos.information import Information from .settings import Settings - COMMISION_UNIT_VARIETY = 4 COMMISION_LIMITS_SCALE = 1.5 COMMISION_LIMITS_FACTORS = { @@ -50,20 +67,11 @@ PLAYER_BUDGET_IMPORTANCE_LOG = 2 class Game: - settings = None # type: Settings - budget = PLAYER_BUDGET_INITIAL - events = None # type: typing.List[Event] - pending_transfers = None # type: typing.Dict[] - ignored_cps = None # type: typing.Collection[ControlPoint] - turn = 0 - game_stats: GameStats = None - - current_unit_id = 0 - current_group_id = 0 - - def __init__(self, player_name: str, enemy_name: str, theater: ConflictTheater, start_date: datetime, settings): + def __init__(self, player_name: str, enemy_name: str, + theater: ConflictTheater, start_date: datetime, + settings: Settings): self.settings = settings - self.events = [] + self.events: List[Event] = [] self.theater = theater self.player_name = player_name self.player_country = db.FACTIONS[player_name]["country"] @@ -73,14 +81,15 @@ class Game: self.date = datetime(start_date.year, start_date.month, start_date.day) self.game_stats = GameStats() self.game_stats.update(self) - self.ground_planners = {} + self.ground_planners: Dict[int, GroundPlanner] = {} self.informations = [] self.informations.append(Information("Game Start", "-" * 40, 0)) self.__culling_points = self.compute_conflicts_position() - self.__frontlineData = [] - self.__destroyed_units = [] - self.jtacs = [] + self.__destroyed_units: List[str] = [] self.savepath = "" + self.budget = PLAYER_BUDGET_INITIAL + self.current_unit_id = 0 + self.current_group_id = 0 self.blue_ato = AirTaskingOrder() self.red_ato = AirTaskingOrder() @@ -128,7 +137,7 @@ class Game: for player_cp, enemy_cp in self.theater.conflicts(True): self._generate_player_event(FrontlineAttackEvent, player_cp, enemy_cp) - def commision_unit_types(self, cp: ControlPoint, for_task: Task) -> typing.Collection[UnitType]: + def commision_unit_types(self, cp: ControlPoint, for_task: Task) -> List[UnitType]: importance_factor = (cp.importance - IMPORTANCE_LOW) / (IMPORTANCE_HIGH - IMPORTANCE_LOW) if for_task == AirDefence and not self.settings.sams: @@ -209,7 +218,7 @@ class Game: def on_load(self) -> None: ObjectiveDistanceCache.set_theater(self.theater) - def pass_turn(self, no_action=False, ignored_cps: typing.Collection[ControlPoint] = None): + def pass_turn(self, no_action=False): logging.info("Pass turn") self.informations.append(Information("End of turn #" + str(self.turn), "-" * 40, 0)) self.turn = self.turn + 1 @@ -233,11 +242,7 @@ class Game: if not cp.is_carrier and not cp.is_lha: cp.base.affect_strength(-PLAYER_BASE_STRENGTH_RECOVERY) - self.ignored_cps = [] - if ignored_cps: - self.ignored_cps = ignored_cps - - self.events = [] # type: typing.List[Event] + self.events = [] self._generate_events() # Update statistics @@ -424,10 +429,10 @@ class Game: return 1 def get_player_coalition(self): - return dcs.action.Coalition.Blue + return Coalition.Blue def get_enemy_coalition(self): - return dcs.action.Coalition.Red + return Coalition.Red def get_player_color(self): return "blue" diff --git a/game/inventory.py b/game/inventory.py index 1d05a473..5ef68b04 100644 --- a/game/inventory.py +++ b/game/inventory.py @@ -5,12 +5,13 @@ from typing import Dict, Iterable, Iterator, Set, Tuple from dcs.unittype import UnitType from gen.flights.flight import Flight +from theater import ControlPoint class ControlPointAircraftInventory: """Aircraft inventory for a single control point.""" - def __init__(self, control_point: "ControlPoint") -> None: + def __init__(self, control_point: ControlPoint) -> None: self.control_point = control_point self.inventory: Dict[UnitType, int] = defaultdict(int) @@ -81,8 +82,8 @@ class ControlPointAircraftInventory: class GlobalAircraftInventory: """Game-wide aircraft inventory.""" - def __init__(self, control_points: Iterable["ControlPoint"]) -> None: - self.inventories: Dict["ControlPoint", ControlPointAircraftInventory] = { + def __init__(self, control_points: Iterable[ControlPoint]) -> None: + self.inventories: Dict[ControlPoint, ControlPointAircraftInventory] = { cp: ControlPointAircraftInventory(cp) for cp in control_points } @@ -91,7 +92,7 @@ class GlobalAircraftInventory: for inventory in self.inventories.values(): inventory.clear() - def set_from_control_point(self, control_point: "ControlPoint") -> None: + def set_from_control_point(self, control_point: ControlPoint) -> None: """Set the control point's aircraft inventory. If the inventory for the given control point has already been set for @@ -103,7 +104,7 @@ class GlobalAircraftInventory: def for_control_point( self, - control_point: "ControlPoint") -> ControlPointAircraftInventory: + control_point: ControlPoint) -> ControlPointAircraftInventory: """Returns the inventory specific to the given control point.""" return self.inventories[control_point] diff --git a/game/models/game_stats.py b/game/models/game_stats.py index 2690d861..e6d628f4 100644 --- a/game/models/game_stats.py +++ b/game/models/game_stats.py @@ -1,3 +1,5 @@ +from typing import List + class FactionTurnMetadata: """ Store metadata about a faction @@ -31,10 +33,8 @@ class GameStats: Store statistics for the current game """ - data_per_turn: [GameTurnMetadata] = [] - def __init__(self): - self.data_per_turn = [] + self.data_per_turn: List[GameTurnMetadata] = [] def update(self, game): """ diff --git a/game/operation/frontlineattack.py b/game/operation/frontlineattack.py index 48c5965c..19255247 100644 --- a/game/operation/frontlineattack.py +++ b/game/operation/frontlineattack.py @@ -1,7 +1,8 @@ -from game.db import assigned_units_split - -from .operation import * +from dcs.terrain.terrain import Terrain +from gen.conflictgen import Conflict +from .operation import Operation +from .. import db MAX_DISTANCE_BETWEEN_GROUPS = 12000 diff --git a/game/operation/operation.py b/game/operation/operation.py index 56c262e0..ecc82e51 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -1,13 +1,35 @@ -from typing import Set +import logging +import os +from pathlib import Path +from typing import List, Optional, Set -from gen import * -from gen.airfields import AIRFIELD_DATA -from gen.beacons import load_beacons_for_terrain -from gen.radios import RadioRegistry -from gen.tacan import TacanRegistry +from dcs import Mission +from dcs.action import DoScript, DoScriptFile +from dcs.coalition import Coalition from dcs.countries import country_dict from dcs.lua.parse import loads +from dcs.mapping import Point from dcs.terrain.terrain import Terrain +from dcs.translation import String +from dcs.triggers import TriggerStart +from dcs.unittype import UnitType + +from gen import Conflict, VisualGenerator +from gen.aircraft import AIRCRAFT_DATA, AircraftConflictGenerator, FlightData +from gen.airfields import AIRFIELD_DATA +from gen.airsupportgen import AirSupport, AirSupportConflictGenerator +from gen.armor import GroundConflictGenerator, JtacInfo +from gen.beacons import load_beacons_for_terrain +from gen.briefinggen import BriefingGenerator +from gen.environmentgen import EnviromentGenerator +from gen.forcedoptionsgen import ForcedOptionsGenerator +from gen.groundobjectsgen import GroundObjectsGenerator +from gen.kneeboard import KneeboardGenerator +from gen.radios import RadioFrequency, RadioRegistry +from gen.tacan import TacanRegistry +from gen.triggergen import TRIGGER_RADIUS_MEDIUM, TriggersGenerator +from theater import ControlPoint +from .. import db from ..debriefing import Debriefing @@ -15,16 +37,15 @@ class Operation: attackers_starting_position = None # type: db.StartingPosition defenders_starting_position = None # type: db.StartingPosition - current_mission = None # type: dcs.Mission - regular_mission = None # type: dcs.Mission - quick_mission = None # type: dcs.Mission + current_mission = None # type: Mission + regular_mission = None # type: Mission + quick_mission = None # type: Mission conflict = None # type: Conflict - armorgen = None # type: ArmorConflictGenerator airgen = None # type: AircraftConflictGenerator triggersgen = None # type: TriggersGenerator airsupportgen = None # type: AirSupportConflictGenerator visualgen = None # type: VisualGenerator - envgen = None # type: EnvironmentGenerator + envgen = None # type: EnviromentGenerator groundobjectgen = None # type: GroundObjectsGenerator briefinggen = None # type: BriefingGenerator forcedoptionsgen = None # type: ForcedOptionsGenerator @@ -43,7 +64,7 @@ class Operation: defender_name: str, from_cp: ControlPoint, departure_cp: ControlPoint, - to_cp: ControlPoint = None): + to_cp: ControlPoint): self.game = game self.attacker_name = attacker_name self.attacker_country = db.FACTIONS[attacker_name]["country"] @@ -55,7 +76,7 @@ class Operation: self.to_cp = to_cp self.is_quick = False - def units_of(self, country_name: str) -> typing.Collection[UnitType]: + def units_of(self, country_name: str) -> List[UnitType]: return [] def is_successfull(self, debriefing: Debriefing) -> bool: @@ -75,7 +96,7 @@ class Operation: with open("resources/default_options.lua", "r") as f: options_dict = loads(f.read())["options"] - self.current_mission = dcs.Mission(terrain) + self.current_mission = Mission(terrain) print(self.game.player_country) print(country_dict[db.country_id_from_name(self.game.player_country)]) @@ -106,7 +127,11 @@ class Operation: self.defenders_starting_position = None else: self.attackers_starting_position = self.departure_cp.at - self.defenders_starting_position = self.to_cp.at + # TODO: Is this possible? + if self.to_cp is not None: + self.defenders_starting_position = self.to_cp.at + else: + self.defenders_starting_position = None def generate(self): radio_registry = RadioRegistry() @@ -374,6 +399,7 @@ class Operation: logging.warning(f"No aircraft data for {airframe.id}") return - aircraft_data.channel_allocator.assign_channels_for_flight( - flight, air_support - ) + if aircraft_data.channel_allocator is not None: + aircraft_data.channel_allocator.assign_channels_for_flight( + flight, air_support + ) diff --git a/game/persistency.py b/game/persistency.py index 9e55dda0..4e0b216f 100644 --- a/game/persistency.py +++ b/game/persistency.py @@ -2,8 +2,9 @@ import logging import os import pickle import shutil +from typing import Optional -_dcs_saved_game_folder = None # type: str +_dcs_saved_game_folder: Optional[str] = None _file_abs_path = None def setup(user_folder: str): diff --git a/gen/__init__.py b/gen/__init__.py index ad11614f..6fd6547c 100644 --- a/gen/__init__.py +++ b/gen/__init__.py @@ -1,4 +1,3 @@ -from .aaa import * from .aircraft import * from .armor import * from .airsupportgen import * @@ -12,4 +11,3 @@ from .forcedoptionsgen import * from .kneeboard import * from . import naming - diff --git a/gen/aaa.py b/gen/aaa.py deleted file mode 100644 index d9822202..00000000 --- a/gen/aaa.py +++ /dev/null @@ -1,51 +0,0 @@ -from .conflictgen import * -from .naming import * - -from dcs.mission import * -from dcs.mission import * - -from .conflictgen import * -from .naming import * - -DISTANCE_FACTOR = 0.5, 1 -EXTRA_AA_MIN_DISTANCE = 50000 -EXTRA_AA_MAX_DISTANCE = 150000 -EXTRA_AA_POSITION_FROM_CP = 550 - -class ExtraAAConflictGenerator: - def __init__(self, mission: Mission, conflict: Conflict, game, player_country: Country, enemy_country: Country): - self.mission = mission - self.game = game - self.conflict = conflict - self.player_country = player_country - self.enemy_country = enemy_country - - def generate(self): - - for cp in self.game.theater.controlpoints: - if cp.is_global: - continue - - if cp.position.distance_to_point(self.conflict.position) < EXTRA_AA_MIN_DISTANCE: - continue - - if cp.position.distance_to_point(self.conflict.from_cp.position) < EXTRA_AA_MIN_DISTANCE: - continue - - if cp.position.distance_to_point(self.conflict.to_cp.position) < EXTRA_AA_MIN_DISTANCE: - continue - - if cp.position.distance_to_point(self.conflict.position) > EXTRA_AA_MAX_DISTANCE: - continue - - country_name = cp.captured and self.player_country or self.enemy_country - position = cp.position.point_from_heading(0, EXTRA_AA_POSITION_FROM_CP) - - self.mission.vehicle_group( - country=self.mission.country(country_name), - name=namegen.next_basedefense_name(), - _type=db.EXTRA_AA[country_name], - position=position, - group_size=1 - ) - diff --git a/gen/aircraft.py b/gen/aircraft.py index 9eeb1836..f9cd63f1 100644 --- a/gen/aircraft.py +++ b/gen/aircraft.py @@ -1,14 +1,67 @@ +import logging +import random from dataclasses import dataclass -from typing import Type +from typing import Dict, List, Optional, Tuple, Type, Union from dcs import helicopters -from dcs.action import ActivateGroup, AITaskPush, MessageToAll -from dcs.condition import TimeAfter, CoalitionHasAirdrome, PartOfCoalitionInZone +from dcs.action import AITaskPush, ActivateGroup, MessageToAll +from dcs.condition import CoalitionHasAirdrome, PartOfCoalitionInZone, TimeAfter +from dcs.country import Country from dcs.flyingunit import FlyingUnit -from dcs.helicopters import helicopter_map, UH_1H +from dcs.helicopters import UH_1H, helicopter_map +from dcs.mapping import Point +from dcs.mission import Mission, StartType +from dcs.planes import ( + AJS37, + B_17G, + Bf_109K_4, + FW_190A8, + FW_190D9, + F_14B, + I_16, + JF_17, + Ju_88A4, + P_47D_30, + P_51D, + P_51D_30_NA, + SpitfireLFMkIX, + SpitfireLFMkIXCW, + Su_33, +) +from dcs.point import PointAction +from dcs.task import ( + AntishipStrike, + AttackGroup, + Bombing, + CAP, + CAS, + ControlledTask, + EPLRS, + EngageTargets, + Escort, + GroundAttack, + MainTask, + NoTask, + OptROE, + OptRTBOnBingoFuel, + OptRTBOnOutOfAmmo, + OptReactOnThreat, + OptRestrictAfterburner, + OptRestrictJettison, + OrbitAction, + PinpointStrike, + SEAD, + StartCommand, + Targets, + Task, +) from dcs.terrain.terrain import Airport, NoParkingSlotError -from dcs.triggers import TriggerOnce, Event +from dcs.translation import String +from dcs.triggers import Event, TriggerOnce +from dcs.unitgroup import FlyingGroup, Group, ShipGroup, StaticGroup +from dcs.unittype import FlyingType, UnitType +from game import db from game.data.cap_capabilities_db import GUNFIGHTERS from game.settings import Settings from game.utils import nm_to_meter @@ -22,9 +75,10 @@ from gen.flights.flight import ( FlightWaypoint, FlightWaypointType, ) -from gen.radios import get_radio, MHz, Radio, RadioFrequency, RadioRegistry -from .conflictgen import * -from .naming import * +from gen.radios import MHz, Radio, RadioFrequency, RadioRegistry, get_radio +from theater.controlpoint import ControlPoint, ControlPointType +from .naming import namegen +from .conflictgen import Conflict WARM_START_HELI_AIRSPEED = 120 WARM_START_HELI_ALT = 500 @@ -264,8 +318,12 @@ class CommonRadioChannelAllocator(RadioChannelAllocator): def assign_channels_for_flight(self, flight: FlightData, air_support: AirSupport) -> None: - flight.assign_channel( - self.intra_flight_radio_index, 1, flight.intra_flight_channel) + if self.intra_flight_radio_index is not None: + flight.assign_channel( + self.intra_flight_radio_index, 1, flight.intra_flight_channel) + + if self.inter_flight_radio_index is None: + return # For cases where the inter-flight and intra-flight radios share presets # (the JF-17 only has one set of channels, even though it can use two @@ -335,8 +393,10 @@ class ViggenRadioChannelAllocator(RadioChannelAllocator): # the guard channel. radio_id = 1 flight.assign_channel(radio_id, 1, flight.intra_flight_channel) - flight.assign_channel(radio_id, 4, flight.departure.atc) - flight.assign_channel(radio_id, 5, flight.arrival.atc) + if flight.departure.atc is not None: + flight.assign_channel(radio_id, 4, flight.departure.atc) + if flight.arrival.atc is not None: + flight.assign_channel(radio_id, 5, flight.arrival.atc) # TODO: Assign divert to 6 when we support divert airfields. @@ -348,8 +408,10 @@ class SCR522RadioChannelAllocator(RadioChannelAllocator): air_support: AirSupport) -> None: radio_id = 1 flight.assign_channel(radio_id, 1, flight.intra_flight_channel) - flight.assign_channel(radio_id, 2, flight.departure.atc) - flight.assign_channel(radio_id, 3, flight.arrival.atc) + if flight.departure.atc is not None: + flight.assign_channel(radio_id, 2, flight.departure.atc) + if flight.arrival.atc is not None: + flight.assign_channel(radio_id, 3, flight.arrival.atc) # TODO : Some GCI on Channel 4 ? @@ -471,8 +533,6 @@ AIRCRAFT_DATA["P-47D-30"] = AIRCRAFT_DATA["P-51D"] class AircraftConflictGenerator: - escort_targets = [] # type: typing.List[typing.Tuple[FlyingGroup, int]] - def __init__(self, mission: Mission, conflict: Conflict, settings: Settings, game, radio_registry: RadioRegistry): self.m = mission @@ -480,7 +540,7 @@ class AircraftConflictGenerator: self.settings = settings self.conflict = conflict self.radio_registry = radio_registry - self.escort_targets = [] + self.escort_targets: List[Tuple[FlyingGroup, int]] = [] self.flights: List[FlightData] = [] def get_intra_flight_channel(self, airframe: UnitType) -> RadioFrequency: @@ -502,33 +562,23 @@ class AircraftConflictGenerator: def _start_type(self) -> StartType: return self.settings.cold_start and StartType.Cold or StartType.Warm - def _setup_group(self, group: FlyingGroup, for_task: typing.Type[Task], + def _setup_group(self, group: FlyingGroup, for_task: Type[Task], flight: Flight, dynamic_runways: Dict[str, RunwayData]): did_load_loadout = False unit_type = group.units[0].unit_type if unit_type in db.PLANE_PAYLOAD_OVERRIDES: override_loadout = db.PLANE_PAYLOAD_OVERRIDES[unit_type] - if type(override_loadout) == dict: + # Clear pylons + for p in group.units: + p.pylons.clear() - # Clear pylons - for p in group.units: - p.pylons.clear() - - # Now load loadout - if for_task in db.PLANE_PAYLOAD_OVERRIDES[unit_type]: - payload_name = db.PLANE_PAYLOAD_OVERRIDES[unit_type][for_task] - group.load_loadout(payload_name) - did_load_loadout = True - logging.info("Loaded overridden payload for {} - {} for task {}".format(unit_type, payload_name, for_task)) - elif "*" in db.PLANE_PAYLOAD_OVERRIDES[unit_type]: - payload_name = db.PLANE_PAYLOAD_OVERRIDES[unit_type]["*"] - group.load_loadout(payload_name) - did_load_loadout = True - logging.info("Loaded overridden payload for {} - {} for task {}".format(unit_type, payload_name, for_task)) - elif issubclass(override_loadout, MainTask): - group.load_task_default_loadout(override_loadout) + # Now load loadout + if for_task in db.PLANE_PAYLOAD_OVERRIDES[unit_type]: + payload_name = db.PLANE_PAYLOAD_OVERRIDES[unit_type][for_task] + group.load_loadout(payload_name) did_load_loadout = True + logging.info("Loaded overridden payload for {} - {} for task {}".format(unit_type, payload_name, for_task)) if not did_load_loadout: group.load_task_default_loadout(for_task) @@ -590,7 +640,7 @@ class AircraftConflictGenerator: # Special case so Su 33 carrier take off if unit_type is Su_33: - if task is not CAP: + if flight.flight_type is not CAP: for unit in group.units: unit.fuel = Su_33.fuel_max / 2.2 else: @@ -613,9 +663,12 @@ class AircraftConflictGenerator: # so just use the first runway. return runways[0] - def _generate_at_airport(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, airport: Airport = None, start_type = None) -> FlyingGroup: + def _generate_at_airport(self, name: str, side: Country, + unit_type: FlyingType, count: int, + client_count: int, + airport: Optional[Airport] = None, + start_type=None) -> FlyingGroup: assert count > 0 - assert unit is not None if start_type is None: start_type = self._start_type() @@ -633,7 +686,6 @@ class AircraftConflictGenerator: def _generate_inflight(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: Point) -> FlyingGroup: assert count > 0 - assert unit is not None if unit_type in helicopters.helicopter_map.values(): alt = WARM_START_HELI_ALT @@ -660,9 +712,11 @@ class AircraftConflictGenerator: group.points[0].alt_type = "RADIO" return group - def _generate_at_group(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: typing.Union[ShipGroup, StaticGroup], start_type=None) -> FlyingGroup: + def _generate_at_group(self, name: str, side: Country, + unit_type: FlyingType, count: int, client_count: int, + at: Union[ShipGroup, StaticGroup], + start_type=None) -> FlyingGroup: assert count > 0 - assert unit is not None if start_type is None: start_type = self._start_type() @@ -688,7 +742,7 @@ class AircraftConflictGenerator: return self._generate_at_group(name, side, unit_type, count, client_count, at) else: return self._generate_inflight(name, side, unit_type, count, client_count, at.position) - elif issubclass(at, Airport): + elif isinstance(at, Airport): takeoff_ban = unit_type in db.TAKEOFF_BAN ai_ban = client_count == 0 and self.settings.only_player_takeoff @@ -707,8 +761,9 @@ class AircraftConflictGenerator: point.alt_type = "RADIO" return point - def _rtb_for(self, group: FlyingGroup, cp: ControlPoint, at: db.StartingPosition = None): - if not at: + def _rtb_for(self, group: FlyingGroup, cp: ControlPoint, + at: Optional[db.StartingPosition] = None): + if at is None: at = cp.at position = at if isinstance(at, Point) else at.position diff --git a/gen/airfields.py b/gen/airfields.py index b7e08712..b3185158 100644 --- a/gen/airfields.py +++ b/gen/airfields.py @@ -195,10 +195,12 @@ AIRFIELD_DATA = { runway_length=8623, atc=AtcData(MHz(3, 750), MHz(121, 0), MHz(38, 400), MHz(250, 0)), outer_ndb={ - "22": ("AP", MHz(443, 0)), "4": "443.00 (AN)" + "22": ("AP", MHz(443, 0)), + "04": ("AN", MHz(443)), }, inner_ndb={ - "22": ("P", MHz(215, 0)), "4": "215.00 (N)" + "22": ("P", MHz(215, 0)), + "04": ("N", MHz(215)), }, ), diff --git a/gen/airsupportgen.py b/gen/airsupportgen.py index 791c80b6..ce00e9d5 100644 --- a/gen/airsupportgen.py +++ b/gen/airsupportgen.py @@ -1,8 +1,21 @@ from dataclasses import dataclass, field +from typing import List, Type +from dcs.mission import Mission, StartType +from dcs.planes import IL_78M +from dcs.task import ( + AWACS, + ActivateBeaconCommand, + MainTask, + Refueling, + SetImmortalCommand, + SetInvisibleCommand, +) + +from game import db +from .naming import namegen from .callsigns import callsign_for_support_unit -from .conflictgen import * -from .naming import * +from .conflictgen import Conflict from .radios import RadioFrequency, RadioRegistry from .tacan import TacanBand, TacanChannel, TacanRegistry @@ -49,7 +62,7 @@ class AirSupportConflictGenerator: self.tacan_registry = tacan_registry @classmethod - def support_tasks(cls) -> typing.Collection[typing.Type[MainTask]]: + def support_tasks(cls) -> List[Type[MainTask]]: return [Refueling, AWACS] def generate(self, is_awacs_enabled): diff --git a/gen/armor.py b/gen/armor.py index 463d7571..426dc05a 100644 --- a/gen/armor.py +++ b/gen/armor.py @@ -1,13 +1,39 @@ +import logging +import random from dataclasses import dataclass +from typing import List +from dcs import Mission from dcs.action import AITaskPush -from dcs.condition import TimeAfter, UnitDamaged, Or, GroupLifeLess -from dcs.triggers import TriggerOnce, Event +from dcs.condition import GroupLifeLess, Or, TimeAfter, UnitDamaged +from dcs.country import Country +from dcs.mapping import Point +from dcs.planes import MQ_9_Reaper +from dcs.point import PointAction +from dcs.task import ( + AttackGroup, + ControlledTask, + EPLRS, + FireAtPoint, + GoToWaypoint, + Hold, + OrbitAction, + SetImmortalCommand, + SetInvisibleCommand, +) +from dcs.triggers import Event, TriggerOnce +from dcs.unit import Vehicle +from dcs.unittype import VehicleType -from gen import namegen -from gen.ground_forces.ai_ground_planner import CombatGroupRole, DISTANCE_FROM_FRONTLINE +from game import db +from .naming import namegen +from gen.ground_forces.ai_ground_planner import ( + CombatGroupRole, + DISTANCE_FROM_FRONTLINE, +) from .callsigns import callsign_for_support_unit -from .conflictgen import * +from .conflictgen import Conflict +from .ground_forces.combat_stance import CombatStance SPREAD_DISTANCE_FACTOR = 0.1, 0.3 SPREAD_DISTANCE_SIZE_FACTOR = 0.1 @@ -48,7 +74,7 @@ class GroundConflictGenerator: self.jtacs: List[JtacInfo] = [] def _group_point(self, point) -> Point: - distance = randint( + distance = random.randint( int(self.conflict.size * SPREAD_DISTANCE_FACTOR[0]), int(self.conflict.size * SPREAD_DISTANCE_FACTOR[1]), ) @@ -165,7 +191,7 @@ class GroundConflictGenerator: heading=forward_heading, move_formation=PointAction.OffRoad) - for i in range(randint(3, 10)): + for i in range(random.randint(3, 10)): u = random.choice(possible_infantry_units) position = infantry_position.random_point_within(55, 5) self.mission.vehicle_group( diff --git a/gen/conflictgen.py b/gen/conflictgen.py index 9b83b51e..3c9eecfe 100644 --- a/gen/conflictgen.py +++ b/gen/conflictgen.py @@ -1,21 +1,11 @@ import logging -import typing -import pdb -import dcs +import random +from typing import Tuple -from random import randint -from dcs import Mission +from dcs.country import Country +from dcs.mapping import Point -from dcs.mission import * -from dcs.vehicles import * -from dcs.unitgroup import * -from dcs.unittype import * -from dcs.mapping import * -from dcs.point import * -from dcs.task import * -from dcs.country import * - -from theater import * +from theater import ConflictTheater, ControlPoint AIR_DISTANCE = 40000 @@ -65,24 +55,6 @@ def _heading_sum(h, a) -> int: class Conflict: - attackers_side = None # type: str - defenders_side = None # type: str - attackers_country = None # type: Country - defenders_country = None # type: Country - from_cp = None # type: ControlPoint - to_cp = None # type: ControlPoint - position = None # type: Point - size = None # type: int - radials = None # type: typing.List[int] - - heading = None # type: int - distance = None # type: int - - ground_attackers_location = None # type: Point - ground_defenders_location = None # type: Point - air_attackers_location = None # type: Point - air_defenders_location = None # type: Point - def __init__(self, theater: ConflictTheater, from_cp: ControlPoint, @@ -155,7 +127,7 @@ class Conflict: else: return self.position - def find_ground_position(self, at: Point, heading: int, max_distance: int = 40000) -> typing.Optional[Point]: + def find_ground_position(self, at: Point, heading: int, max_distance: int = 40000) -> Point: return Conflict._find_ground_position(at, max_distance, heading, self.theater) @classmethod @@ -163,7 +135,7 @@ class Conflict: return from_cp.has_frontline and to_cp.has_frontline @classmethod - def frontline_position(cls, theater: ConflictTheater, from_cp: ControlPoint, to_cp: ControlPoint) -> typing.Optional[typing.Tuple[Point, int]]: + def frontline_position(cls, theater: ConflictTheater, from_cp: ControlPoint, to_cp: ControlPoint) -> Tuple[Point, int]: attack_heading = from_cp.position.heading_between_point(to_cp.position) attack_distance = from_cp.position.distance_to_point(to_cp.position) middle_point = from_cp.position.point_from_heading(attack_heading, attack_distance / 2) @@ -174,9 +146,7 @@ class Conflict: @classmethod - def frontline_vector(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> typing.Optional[typing.Tuple[Point, int, int]]: - initial, heading = cls.frontline_position(theater, from_cp, to_cp) - + def frontline_vector(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> Tuple[Point, int, int]: """ probe_end_point = initial.point_from_heading(heading, FRONTLINE_LENGTH) probe = geometry.LineString([(initial.x, initial.y), (probe_end_point.x, probe_end_point.y) ]) @@ -193,9 +163,6 @@ class Conflict: return Point(*intersection.xy[0]), _heading_sum(heading, 90), intersection.length """ frontline = cls.frontline_position(theater, from_cp, to_cp) - if not frontline: - return None - center_position, heading = frontline left_position, right_position = None, None @@ -243,7 +210,7 @@ class Conflict: """ @classmethod - def _find_ground_position(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> typing.Optional[Point]: + def _find_ground_position(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> Point: pos = initial for _ in range(0, int(max_distance), 500): if theater.is_on_land(pos): @@ -302,10 +269,14 @@ class Conflict: distance = to_cp.size * GROUND_DISTANCE_FACTOR attackers_location = position.point_from_heading(attack_heading, distance) - attackers_location = Conflict._find_ground_position(attackers_location, distance * 2, _heading_sum(attack_heading, 180), theater) + attackers_location = Conflict._find_ground_position( + attackers_location, int(distance * 2), + _heading_sum(attack_heading, 180), theater) defenders_location = position.point_from_heading(defense_heading, distance) - defenders_location = Conflict._find_ground_position(defenders_location, distance * 2, _heading_sum(defense_heading, 180), theater) + defenders_location = Conflict._find_ground_position( + defenders_location, int(distance * 2), + _heading_sum(defense_heading, 180), theater) return cls( position=position, @@ -429,7 +400,7 @@ class Conflict: assert cls.has_frontline_between(from_cp, to_cp) position, heading, distance = cls.frontline_vector(from_cp, to_cp, theater) - attack_position = position.point_from_heading(heading, randint(0, int(distance))) + attack_position = position.point_from_heading(heading, random.randint(0, int(distance))) attackers_position = attack_position.point_from_heading(heading - 90, AIR_DISTANCE) defenders_position = attack_position.point_from_heading(heading + 90, random.randint(*CAP_CAS_DISTANCE)) @@ -456,7 +427,9 @@ class Conflict: distance = to_cp.size * GROUND_DISTANCE_FACTOR defenders_location = position.point_from_heading(defense_heading, distance) - defenders_location = Conflict._find_ground_position(defenders_location, distance * 2, _heading_sum(defense_heading, 180), theater) + defenders_location = Conflict._find_ground_position( + defenders_location, int(distance * 2), + _heading_sum(defense_heading, 180), theater) return cls( position=position, diff --git a/gen/environmentgen.py b/gen/environmentgen.py index 1d861842..57d70452 100644 --- a/gen/environmentgen.py +++ b/gen/environmentgen.py @@ -1,20 +1,11 @@ import logging -import typing import random -from datetime import datetime, timedelta, time +from datetime import timedelta from dcs.mission import Mission -from dcs.triggers import * -from dcs.condition import * -from dcs.action import * -from dcs.unit import Skill -from dcs.point import MovingPoint, PointProperties -from dcs.action import * -from dcs.weather import * +from dcs.weather import Weather, Wind -from game import db -from theater import * -from gen import * +from .conflictgen import Conflict WEATHER_CLOUD_BASE = 2000, 3000 WEATHER_CLOUD_DENSITY = 1, 8 diff --git a/gen/fleet/ship_group_generator.py b/gen/fleet/ship_group_generator.py index 455d9f27..db974d6c 100644 --- a/gen/fleet/ship_group_generator.py +++ b/gen/fleet/ship_group_generator.py @@ -28,13 +28,13 @@ SHIP_MAP = { } -def generate_ship_group(game, ground_object, faction:str): +def generate_ship_group(game, ground_object, faction_name: str): """ This generate a ship group :return: Nothing, but put the group reference inside the ground object """ - faction = db.FACTIONS[faction] - if "boat" in faction.keys(): + faction = db.FACTIONS[faction_name] + if "boat" in faction: generators = faction["boat"] if len(generators) > 0: gen = random.choice(generators) diff --git a/gen/flights/ai_flight_planner.py b/gen/flights/ai_flight_planner.py index 6b584e68..36b9d929 100644 --- a/gen/flights/ai_flight_planner.py +++ b/gen/flights/ai_flight_planner.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging import operator from dataclasses import dataclass -from typing import Dict, Iterator, List, Optional, Set, TYPE_CHECKING, Tuple +from typing import Iterator, List, Optional, Set, TYPE_CHECKING, Tuple from dcs.unittype import UnitType @@ -406,17 +406,18 @@ class CoalitionMissionPlanner: self.game.aircraft_inventory, self.is_player ) - for flight in mission.flights: - if not builder.plan_flight(flight): + for proposed_flight in mission.flights: + if not builder.plan_flight(proposed_flight): builder.release_planned_aircraft() self.message("Insufficient aircraft", f"Not enough aircraft in range for {mission}") return package = builder.build() - builder = FlightPlanBuilder(self.game, package, self.is_player) + flight_plan_builder = FlightPlanBuilder(self.game, package, + self.is_player) for flight in package.flights: - builder.populate_flight_plan(flight) + flight_plan_builder.populate_flight_plan(flight) self.ato.add_package(package) def message(self, title, text) -> None: diff --git a/gen/flights/ai_flight_planner_db.py b/gen/flights/ai_flight_planner_db.py index e1393a1a..dd51fd26 100644 --- a/gen/flights/ai_flight_planner_db.py +++ b/gen/flights/ai_flight_planner_db.py @@ -1,5 +1,78 @@ -from dcs.planes import * -from dcs.helicopters import * +from dcs.helicopters import ( + AH_1W, + AH_64A, + AH_64D, + Ka_50, + Mi_24V, + Mi_28N, + Mi_8MT, + OH_58D, + SA342L, + SA342M, + UH_1H, +) +from dcs.planes import ( + AJS37, + AV8BNA, + A_10A, + A_10C, + A_10C_2, + A_20G, + B_17G, + Bf_109K_4, + C_101CC, + FA_18C_hornet, + FW_190A8, + FW_190D9, + F_14B, + F_15C, + F_15E, + F_16A, + F_16C_50, + F_4E, + F_5E_3, + F_86F_Sabre, + F_A_18C, + JF_17, + J_11A, + Ju_88A4, + L_39ZA, + MQ_9_Reaper, + M_2000C, + MiG_15bis, + MiG_19P, + MiG_21Bis, + MiG_23MLD, + MiG_25PD, + MiG_27K, + MiG_29A, + MiG_29G, + MiG_29K, + MiG_29S, + MiG_31, + Mirage_2000_5, + P_47D_30, + P_47D_30bl1, + P_47D_40, + P_51D, + P_51D_30_NA, + RQ_1A_Predator, + SpitfireLFMkIX, + SpitfireLFMkIXCW, + Su_17M4, + Su_24M, + Su_24MR, + Su_25, + Su_25T, + Su_25TM, + Su_27, + Su_30, + Su_33, + Su_34, + Tornado_GR4, + Tornado_IDS, + WingLoong_I, +) # Interceptor are the aircraft prioritized for interception tasks # If none is available, the AI will use regular CAP-capable aircraft instead diff --git a/gen/flights/flight.py b/gen/flights/flight.py index 676b6bd8..90b27ccf 100644 --- a/gen/flights/flight.py +++ b/gen/flights/flight.py @@ -1,10 +1,10 @@ from enum import Enum -from typing import List +from typing import Dict, Optional from game import db from dcs.unittype import UnitType from dcs.point import MovingPoint, PointAction -from theater.controlpoint import ControlPoint +from theater.controlpoint import ControlPoint, MissionTarget class FlightType(Enum): @@ -73,8 +73,8 @@ class FlightWaypoint: self.alt_type = "BARO" self.name = "" self.description = "" - self.targets = [] - self.targetGroup = None + self.targets: List[MissionTarget] = [] + self.targetGroup: Optional[MissionTarget] = None self.obj_name = "" self.pretty_name = "" self.category: PredefinedWaypointCategory = PredefinedWaypointCategory.NOT_PREDEFINED @@ -110,15 +110,9 @@ class FlightWaypoint: class Flight: - unit_type: UnitType = None - from_cp = None - points: List[FlightWaypoint] = [] - flight_type: FlightType = None count: int = 0 client_count: int = 0 - targets = [] use_custom_loadout = False - loadout = {} preset_loadout_name = "" start_type = "Runway" group = False # Contains DCS Mission group data after mission has been generated @@ -126,14 +120,14 @@ class Flight: # How long before this flight should take off scheduled_in = 0 - def __init__(self, unit_type: UnitType, count: int, from_cp, flight_type: FlightType): + def __init__(self, unit_type: UnitType, count: int, from_cp: ControlPoint, flight_type: FlightType): self.unit_type = unit_type self.count = count self.from_cp = from_cp self.flight_type = flight_type - self.points = [] - self.targets = [] - self.loadout = {} + self.points: List[FlightWaypoint] = [] + self.targets: List[MissionTarget] = [] + self.loadout: Dict[str, str] = {} self.start_type = "Runway" def __repr__(self): @@ -143,10 +137,10 @@ class Flight: # Test if __name__ == '__main__': - from pydcs.dcs.planes import A_10C + from dcs.planes import A_10C from theater import ControlPoint, Point, List - from_cp = ControlPoint(0, "AA", Point(0, 0), None, [], 0, 0) + from_cp = ControlPoint(0, "AA", Point(0, 0), Point(0, 0), [], 0, 0) f = Flight(A_10C(), 4, from_cp, FlightType.CAS) f.scheduled_in = 50 print(f) diff --git a/gen/flights/flightplan.py b/gen/flights/flightplan.py index 2e595b31..5e5fefe2 100644 --- a/gen/flights/flightplan.py +++ b/gen/flights/flightplan.py @@ -388,12 +388,14 @@ class FlightPlanBuilder: def _join_point(self) -> Point: ingress_point = self.package.ingress_point + assert ingress_point is not None heading = self._heading_to_package_airfield(ingress_point) return ingress_point.point_from_heading(heading, -self.doctrine.join_distance) def _split_point(self) -> Point: egress_point = self.package.egress_point + assert egress_point is not None heading = self._heading_to_package_airfield(egress_point) return egress_point.point_from_heading(heading, -self.doctrine.split_distance) diff --git a/gen/flights/waypointbuilder.py b/gen/flights/waypointbuilder.py index 8481b6ba..6fc3fd85 100644 --- a/gen/flights/waypointbuilder.py +++ b/gen/flights/waypointbuilder.py @@ -153,14 +153,16 @@ class WaypointBuilder: self._target_point(target, name, f"STRIKE [{location.name}]: {name}", location) # TODO: Seems fishy. - self.ingress_point.targetGroup = location + if self.ingress_point is not None: + self.ingress_point.targetGroup = location def sead_point(self, target: Union[TheaterGroundObject, Unit], name: str, location: MissionTarget) -> None: self._target_point(target, name, f"STRIKE [{location.name}]: {name}", location) # TODO: Seems fishy. - self.ingress_point.targetGroup = location + if self.ingress_point is not None: + self.ingress_point.targetGroup = location def strike_point(self, target: Union[TheaterGroundObject, Unit], name: str, location: MissionTarget) -> None: @@ -191,12 +193,14 @@ class WaypointBuilder: def sead_area(self, target: MissionTarget) -> None: self._target_area(f"SEAD on {target.name}", target) # TODO: Seems fishy. - self.ingress_point.targetGroup = target + if self.ingress_point is not None: + self.ingress_point.targetGroup = target def dead_area(self, target: MissionTarget) -> None: self._target_area(f"DEAD on {target.name}", target) # TODO: Seems fishy. - self.ingress_point.targetGroup = target + if self.ingress_point is not None: + self.ingress_point.targetGroup = target def _target_area(self, name: str, location: MissionTarget) -> None: if self.ingress_point is None: diff --git a/gen/ground_forces/ai_ground_planner.py b/gen/ground_forces/ai_ground_planner.py index 877c9831..bda87407 100644 --- a/gen/ground_forces/ai_ground_planner.py +++ b/gen/ground_forces/ai_ground_planner.py @@ -1,13 +1,13 @@ import random from enum import Enum +from typing import Dict, List -from dcs.vehicles import * - -from gen import Conflict -from gen.ground_forces.combat_stance import CombatStance -from theater import ControlPoint +from dcs.vehicles import Armor, Artillery, Infantry, Unarmed +from dcs.unittype import VehicleType import pydcs_extensions.frenchpack.frenchpack as frenchpack +from gen.ground_forces.combat_stance import CombatStance +from theater import ControlPoint TYPE_TANKS = [ Armor.MBT_T_55, @@ -207,8 +207,8 @@ GROUP_SIZES_BY_COMBAT_STANCE = { class CombatGroup: - def __init__(self, role:CombatGroupRole): - self.units = [] + def __init__(self, role: CombatGroupRole): + self.units: List[VehicleType] = [] self.role = role self.assigned_enemy_cp = None self.start_position = None @@ -222,33 +222,22 @@ class CombatGroup: class GroundPlanner: - cp = None - combat_groups_dict = {} - connected_enemy_cp = [] - - tank_groups = [] - apc_group = [] - ifv_group = [] - art_group = [] - shorad_groups = [] - logi_groups = [] - def __init__(self, cp:ControlPoint, game): self.cp = cp self.game = game self.connected_enemy_cp = [cp for cp in self.cp.connected_points if cp.captured != self.cp.captured] - self.tank_groups = [] - self.apc_group = [] - self.ifv_group = [] - self.art_group = [] - self.atgm_group = [] - self.logi_groups = [] - self.shorad_groups = [] + self.tank_groups: List[CombatGroup] = [] + self.apc_group: List[CombatGroup] = [] + self.ifv_group: List[CombatGroup] = [] + self.art_group: List[CombatGroup] = [] + self.atgm_group: List[CombatGroup] = [] + self.logi_groups: List[CombatGroup] = [] + self.shorad_groups: List[CombatGroup] = [] - self.units_per_cp = {} + self.units_per_cp: Dict[int, List[CombatGroup]] = {} for cp in self.connected_enemy_cp: self.units_per_cp[cp.id] = [] - self.reserve = [] + self.reserve: List[CombatGroup] = [] def plan_groundwar(self): diff --git a/gen/groundobjectsgen.py b/gen/groundobjectsgen.py index ddf2706e..2d1894e8 100644 --- a/gen/groundobjectsgen.py +++ b/gen/groundobjectsgen.py @@ -1,11 +1,23 @@ -from dcs.statics import * -from dcs.unit import Ship, Vehicle +import logging +import random +from typing import Dict, Iterator -from game.data.building_data import FORTIFICATION_UNITS_ID, FORTIFICATION_UNITS +from dcs import Mission +from dcs.statics import fortification_map, warehouse_map +from dcs.task import ( + ActivateBeaconCommand, + ActivateICLSCommand, + EPLRS, + OptAlarmState, +) +from dcs.unit import Ship, Vehicle +from dcs.unitgroup import StaticGroup + +from game import db +from game.data.building_data import FORTIFICATION_UNITS, FORTIFICATION_UNITS_ID from game.db import unit_type_from_name from .airfields import RunwayData -from .conflictgen import * -from .naming import * +from .conflictgen import Conflict from .radios import RadioRegistry from .tacan import TacanBand, TacanRegistry @@ -26,7 +38,7 @@ class GroundObjectsGenerator: self.icls_alloc = iter(range(1, 21)) self.runways: Dict[str, RunwayData] = {} - def generate_farps(self, number_of_units=1) -> typing.Collection[StaticGroup]: + def generate_farps(self, number_of_units=1) -> Iterator[StaticGroup]: if self.conflict.is_vector: center = self.conflict.center heading = self.conflict.heading - 90 diff --git a/gen/kneeboard.py b/gen/kneeboard.py index 6843e395..e7a86bc5 100644 --- a/gen/kneeboard.py +++ b/gen/kneeboard.py @@ -82,6 +82,8 @@ class KneeboardPageWriter: def table(self, cells: List[List[str]], headers: Optional[List[str]] = None) -> None: + if headers is None: + headers = [] table = tabulate(cells, headers=headers, numalign="right") self.text(table, font=self.table_font) @@ -136,7 +138,7 @@ class FlightPlanBuilder: def add_waypoint_row(self, waypoint: NumberedWaypoint) -> None: self.rows.append([ - waypoint.number, + str(waypoint.number), waypoint.waypoint.pretty_name, str(int(units.meters_to_feet(waypoint.waypoint.alt))) ]) @@ -194,7 +196,7 @@ class BriefingPage(KneeboardPage): tankers.append([ tanker.callsign, tanker.variant, - tanker.tacan, + str(tanker.tacan), self.format_frequency(tanker.freq), ]) writer.table(tankers, headers=["Callsign", "Type", "TACAN", "UHF"]) @@ -225,12 +227,22 @@ class BriefingPage(KneeboardPage): atc = "" if runway.atc is not None: atc = self.format_frequency(runway.atc) + if runway.tacan is None: + tacan = "" + else: + tacan = str(runway.tacan) + if runway.ils is not None: + ils = str(runway.ils) + elif runway.icls is not None: + ils = str(runway.icls) + else: + ils = "" return [ row_title, runway.airfield_name, atc, - runway.tacan or "", - runway.ils or runway.icls or "", + tacan, + ils, runway.runway_name, ] diff --git a/gen/missiles/missiles_group_generator.py b/gen/missiles/missiles_group_generator.py index c63fcca9..4e2e9d73 100644 --- a/gen/missiles/missiles_group_generator.py +++ b/gen/missiles/missiles_group_generator.py @@ -8,13 +8,13 @@ MISSILES_MAP = { } -def generate_missile_group(game, ground_object, faction:str): +def generate_missile_group(game, ground_object, faction_name: str): """ This generate a ship group :return: Nothing, but put the group reference inside the ground object """ - faction = db.FACTIONS[faction] - if "missiles" in faction.keys(): + faction = db.FACTIONS[faction_name] + if "missiles" in faction: generators = faction["missiles"] if len(generators) > 0: gen = random.choice(generators) diff --git a/gen/triggergen.py b/gen/triggergen.py index fbd8062e..ba87bb3e 100644 --- a/gen/triggergen.py +++ b/gen/triggergen.py @@ -1,19 +1,12 @@ -import typing -import random -from datetime import datetime, timedelta, time - +from dcs.action import MarkToAll +from dcs.condition import TimeAfter from dcs.mission import Mission -from dcs.triggers import * -from dcs.condition import * -from dcs.action import * +from dcs.task import Option +from dcs.translation import String +from dcs.triggers import Event, TriggerOnce from dcs.unit import Skill -from dcs.point import MovingPoint, PointProperties -from dcs.action import * -from game import db -from theater import * -from gen.airsupportgen import AirSupportConflictGenerator -from gen import * +from .conflictgen import Conflict PUSH_TRIGGER_SIZE = 3000 PUSH_TRIGGER_ACTIVATION_AGL = 25 diff --git a/gen/visualgen.py b/gen/visualgen.py index c3be7cad..5bc315e5 100644 --- a/gen/visualgen.py +++ b/gen/visualgen.py @@ -1,18 +1,20 @@ -import typing +from __future__ import annotations + import random -from datetime import datetime, timedelta +from typing import TYPE_CHECKING +from dcs.mapping import Point from dcs.mission import Mission -from dcs.statics import * from dcs.unit import Static +from dcs.unittype import StaticType -from theater import * -from .conflictgen import * -#from game.game import Game -from game import db +if TYPE_CHECKING: + from game import Game + +from .conflictgen import Conflict, FRONTLINE_LENGTH -class MarkerSmoke(unittype.StaticType): +class MarkerSmoke(StaticType): id = "big_smoke" category = "Effects" name = "big_smoke" @@ -20,7 +22,7 @@ class MarkerSmoke(unittype.StaticType): rate = 0.1 -class Smoke(unittype.StaticType): +class Smoke(StaticType): id = "big_smoke" category = "Effects" name = "big_smoke" @@ -28,7 +30,7 @@ class Smoke(unittype.StaticType): rate = 1 -class BigSmoke(unittype.StaticType): +class BigSmoke(StaticType): id = "big_smoke" category = "Effects" name = "big_smoke" @@ -36,7 +38,7 @@ class BigSmoke(unittype.StaticType): rate = 1 -class MassiveSmoke(unittype.StaticType): +class MassiveSmoke(StaticType): id = "big_smoke" category = "Effects" name = "big_smoke" @@ -44,7 +46,7 @@ class MassiveSmoke(unittype.StaticType): rate = 1 -class Outpost(unittype.StaticType): +class Outpost(StaticType): id = "outpost" name = "outpost" category = "Fortifications" @@ -90,9 +92,7 @@ def turn_heading(heading, fac): class VisualGenerator: - game = None # type: Game - - def __init__(self, mission: Mission, conflict: Conflict, game): + def __init__(self, mission: Mission, conflict: Conflict, game: Game): self.mission = mission self.conflict = conflict self.game = game diff --git a/mypy.ini b/mypy.ini index 1f9f6f7d..045a50e6 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,6 +1,10 @@ [mypy] namespace_packages = True +[mypy-dcs.*] +follow_imports=silent +ignore_missing_imports = True + [mypy-PIL.*] ignore_missing_imports = True diff --git a/qt_ui/windows/QWaitingForMissionResultWindow.py b/qt_ui/windows/QWaitingForMissionResultWindow.py index b93d3256..c35a482e 100644 --- a/qt_ui/windows/QWaitingForMissionResultWindow.py +++ b/qt_ui/windows/QWaitingForMissionResultWindow.py @@ -172,7 +172,7 @@ class QWaitingForMissionResultWindow(QDialog): def process_debriefing(self): self.game.finish_event(event=self.gameEvent, debriefing=self.debriefing) - self.game.pass_turn(ignored_cps=[self.gameEvent.to_cp, ]) + self.game.pass_turn() GameUpdateSignal.get_instance().sendDebriefing(self.game, self.gameEvent, self.debriefing) self.close() diff --git a/qt_ui/windows/basemenu/QBaseMenu2.py b/qt_ui/windows/basemenu/QBaseMenu2.py index 597c2a32..cf5e1a34 100644 --- a/qt_ui/windows/basemenu/QBaseMenu2.py +++ b/qt_ui/windows/basemenu/QBaseMenu2.py @@ -2,13 +2,12 @@ from PySide2.QtCore import Qt from PySide2.QtGui import QCloseEvent, QPixmap from PySide2.QtWidgets import QDialog, QGridLayout, QHBoxLayout, QLabel, QWidget -from game.event import ControlPointType from qt_ui.models import GameModel from qt_ui.uiconstants import EVENT_ICONS from qt_ui.windows.GameUpdateSignal import GameUpdateSignal from qt_ui.windows.basemenu.QBaseMenuTabs import QBaseMenuTabs from qt_ui.windows.basemenu.QRecruitBehaviour import QRecruitBehaviour -from theater import ControlPoint +from theater import ControlPoint, ControlPointType class QBaseMenu2(QDialog): diff --git a/theater/base.py b/theater/base.py index b294dd38..4ca5dec7 100644 --- a/theater/base.py +++ b/theater/base.py @@ -1,14 +1,15 @@ -import logging -import typing -import math import itertools +import logging +import math +import typing +from typing import Dict, Type -from dcs.planes import * -from dcs.vehicles import * -from dcs.task import * +from dcs.planes import PlaneType +from dcs.task import CAP, CAS, Embarking, PinpointStrike, Task +from dcs.unittype import UnitType, VehicleType +from dcs.vehicles import AirDefence, Armor from game import db -from gen import aaa STRENGTH_AA_ASSEMBLE_MIN = 0.2 PLANES_SCRAMBLE_MIN_BASE = 2 @@ -21,16 +22,15 @@ BASE_MIN_STRENGTH = 0 class Base: aircraft = {} # type: typing.Dict[PlaneType, int] - armor = {} # type: typing.Dict[Armor, int] + armor = {} # type: typing.Dict[VehicleType, int] aa = {} # type: typing.Dict[AirDefence, int] strength = 1 # type: float - commision_points = {} def __init__(self): self.aircraft = {} self.armor = {} self.aa = {} - self.commision_points = {} + self.commision_points: Dict[Type, float] = {} self.strength = 1 @property @@ -55,17 +55,19 @@ class Base: def all_units(self): return itertools.chain(self.aircraft.items(), self.armor.items(), self.aa.items()) - def _find_best_unit(self, dict, for_type: Task, count: int) -> typing.Dict: + def _find_best_unit(self, available_units: Dict[UnitType, int], + for_type: Task, count: int) -> Dict[UnitType, int]: if count <= 0: logging.warning("{}: no units for {}".format(self, for_type)) return {} - sorted_units = [key for key in dict.keys() if key in db.UNIT_BY_TASK[for_type]] + sorted_units = [key for key in available_units if + key in db.UNIT_BY_TASK[for_type]] sorted_units.sort(key=lambda x: db.PRICES[x], reverse=True) - result = {} + result: Dict[UnitType, int] = {} for unit_type in sorted_units: - existing_count = dict[unit_type] # type: int + existing_count = available_units[unit_type] # type: int if not existing_count: continue diff --git a/theater/conflicttheater.py b/theater/conflicttheater.py index e21a4e6d..d92def90 100644 --- a/theater/conflicttheater.py +++ b/theater/conflicttheater.py @@ -1,12 +1,19 @@ import json -import typing +from typing import Dict, Iterator, List, Optional, Tuple -import dcs from dcs.mapping import Point -from dcs.terrain import caucasus, persiangulf, nevada, normandy, thechannel, syria +from dcs.terrain import ( + caucasus, + nevada, + normandy, + persiangulf, + syria, + thechannel, +) +from dcs.terrain.terrain import Terrain from .controlpoint import ControlPoint -from .landmap import poly_contains, load_landmap +from .landmap import Landmap, load_landmap, poly_contains SIZE_TINY = 150 SIZE_SMALL = 600 @@ -47,26 +54,28 @@ COAST_DR_W = [135, 180, 225, 315] class ConflictTheater: - terrain = None # type: dcs.terrain.Terrain - controlpoints = None # type: typing.List[ControlPoint] + terrain: Terrain - reference_points = None # type: typing.Dict - overview_image = None # type: str - landmap = None # type: landmap.Landmap + reference_points: Dict[Tuple[float, float], Tuple[float, float]] + overview_image: str + landmap: Optional[Landmap] """ land_poly = None # type: Polygon """ - daytime_map = None # type: typing.Dict[str, typing.Tuple[int, int]] + daytime_map: Dict[str, Tuple[int, int]] def __init__(self): - self.controlpoints = [] + self.controlpoints: List[ControlPoint] = [] """ self.land_poly = geometry.Polygon(self.landmap[0][0]) for x in self.landmap[1]: self.land_poly = self.land_poly.difference(geometry.Polygon(x)) """ - def add_controlpoint(self, point: ControlPoint, connected_to: [ControlPoint] = []): + def add_controlpoint(self, point: ControlPoint, + connected_to: Optional[List[ControlPoint]] = None): + if connected_to is None: + connected_to = [] for connected_point in connected_to: point.connect(to=connected_point) @@ -108,15 +117,15 @@ class ConflictTheater: return True - def player_points(self) -> typing.Collection[ControlPoint]: + def player_points(self) -> List[ControlPoint]: return [point for point in self.controlpoints if point.captured] - def conflicts(self, from_player=True) -> typing.Collection[typing.Tuple[ControlPoint, ControlPoint]]: + def conflicts(self, from_player=True) -> Iterator[Tuple[ControlPoint, ControlPoint]]: for cp in [x for x in self.controlpoints if x.captured == from_player]: for connected_point in [x for x in cp.connected_points if x.captured != from_player]: - yield (cp, connected_point) + yield cp, connected_point - def enemy_points(self) -> typing.Collection[ControlPoint]: + def enemy_points(self) -> List[ControlPoint]: return [point for point in self.controlpoints if not point.captured] def add_json_cp(self, theater, p: dict) -> ControlPoint: @@ -205,7 +214,7 @@ class CaucasusTheater(ConflictTheater): class PersianGulfTheater(ConflictTheater): - terrain = dcs.terrain.PersianGulf() + terrain = persiangulf.PersianGulf() overview_image = "persiangulf.gif" reference_points = { (persiangulf.Shiraz_International_Airport.position.x, persiangulf.Shiraz_International_Airport.position.y): ( @@ -221,7 +230,7 @@ class PersianGulfTheater(ConflictTheater): class NevadaTheater(ConflictTheater): - terrain = dcs.terrain.Nevada() + terrain = nevada.Nevada() overview_image = "nevada.gif" reference_points = {(nevada.Mina_Airport_3Q0.position.x, nevada.Mina_Airport_3Q0.position.y): (45 * 2, -360 * 2), (nevada.Laughlin_Airport.position.x, nevada.Laughlin_Airport.position.y): (440 * 2, 80 * 2), } @@ -235,7 +244,7 @@ class NevadaTheater(ConflictTheater): class NormandyTheater(ConflictTheater): - terrain = dcs.terrain.Normandy() + terrain = normandy.Normandy() overview_image = "normandy.gif" reference_points = {(normandy.Needs_Oar_Point.position.x, normandy.Needs_Oar_Point.position.y): (-170, -1000), (normandy.Evreux.position.x, normandy.Evreux.position.y): (2020, 500)} @@ -249,7 +258,7 @@ class NormandyTheater(ConflictTheater): class TheChannelTheater(ConflictTheater): - terrain = dcs.terrain.TheChannel() + terrain = thechannel.TheChannel() overview_image = "thechannel.gif" reference_points = {(thechannel.Abbeville_Drucat.position.x, thechannel.Abbeville_Drucat.position.y): (2400, 4100), (thechannel.Detling.position.x, thechannel.Detling.position.y): (1100, 2000)} @@ -263,7 +272,7 @@ class TheChannelTheater(ConflictTheater): class SyriaTheater(ConflictTheater): - terrain = dcs.terrain.Syria() + terrain = syria.Syria() overview_image = "syria.gif" reference_points = {(syria.Eyn_Shemer.position.x, syria.Eyn_Shemer.position.y): (1300, 1380), (syria.Tabqa.position.x, syria.Tabqa.position.y): (2060, 570)} diff --git a/theater/controlpoint.py b/theater/controlpoint.py index fa211f47..6f520bd1 100644 --- a/theater/controlpoint.py +++ b/theater/controlpoint.py @@ -1,8 +1,8 @@ import re -import typing +from typing import Dict, List from enum import Enum -from dcs.mapping import * +from dcs.mapping import Point from dcs.ships import ( CVN_74_John_C__Stennis, CV_1143_5_Admiral_Kuznetsov, @@ -13,6 +13,7 @@ from dcs.terrain.terrain import Airport from game import db from gen.ground_forces.combat_stance import CombatStance +from .base import Base from .missiontarget import MissionTarget from .theatergroundobject import TheaterGroundObject @@ -27,35 +28,26 @@ class ControlPointType(Enum): class ControlPoint(MissionTarget): - id = 0 position = None # type: Point name = None # type: str - full_name = None # type: str - base = None # type: theater.base.Base - at = None # type: db.StartPosition allow_sea_units = True - connected_points = None # type: typing.List[ControlPoint] - ground_objects = None # type: typing.List[TheaterGroundObject] - captured = False has_frontline = True frontline_offset = 0.0 - cptype: ControlPointType = None alt = 0 - def __init__(self, id: int, name: str, position: Point, at, radials: typing.Collection[int], size: int, importance: float, - has_frontline=True, cptype=ControlPointType.AIRBASE): - import theater.base - + def __init__(self, id: int, name: str, position: Point, + at: db.StartingPosition, radials: List[int], size: int, + importance: float, has_frontline=True, + cptype=ControlPointType.AIRBASE): self.id = id self.name = " ".join(re.split(r" |-", name)[:2]) self.full_name = name self.position: Point = position self.at = at - self.ground_objects = [] - self.ships = [] + self.ground_objects: List[TheaterGroundObject] = [] self.size = size self.importance = importance @@ -63,14 +55,14 @@ class ControlPoint(MissionTarget): self.captured_invert = False self.has_frontline = has_frontline self.radials = radials - self.connected_points = [] - self.base = theater.base.Base() + self.connected_points: List[ControlPoint] = [] + self.base: Base = Base() self.cptype = cptype - self.stances = {} + self.stances: Dict[int, CombatStance] = {} self.airport = None @classmethod - def from_airport(cls, airport: Airport, radials: typing.Collection[int], size: int, importance: float, has_frontline=True): + def from_airport(cls, airport: Airport, radials: List[int], size: int, importance: float, has_frontline=True): assert airport obj = cls(airport.id, airport.name, airport.position, airport, radials, size, importance, has_frontline, cptype=ControlPointType.AIRBASE) obj.airport = airport() @@ -128,7 +120,7 @@ class ControlPoint(MissionTarget): return self.cptype in [ControlPointType.LHA_GROUP] @property - def sea_radials(self) -> typing.Collection[int]: + def sea_radials(self) -> List[int]: # TODO: fix imports all_radials = [0, 45, 90, 135, 180, 225, 270, 315, ] result = [] @@ -195,11 +187,11 @@ class ControlPoint(MissionTarget): def is_connected(self, to) -> bool: return to in self.connected_points - def find_radial(self, heading: int, ignored_radial: int = None): + def find_radial(self, heading: int, ignored_radial: int = None) -> int: closest_radial = 0 closest_radial_delta = 360 for radial in [x for x in self.radials if x != ignored_radial]: - delta = math.fabs(radial - heading) + delta = abs(radial - heading) if delta < closest_radial_delta: closest_radial = radial closest_radial_delta = delta diff --git a/theater/landmap.py b/theater/landmap.py index c5384da7..6eaaf5fe 100644 --- a/theater/landmap.py +++ b/theater/landmap.py @@ -1,11 +1,11 @@ import pickle -import typing +from typing import Collection, Optional, Tuple -Zone = typing.Collection[typing.Tuple[float, float]] -Landmap = typing.Tuple[typing.Collection[Zone], typing.Collection[Zone]] +Zone = Collection[Tuple[float, float]] +Landmap = Tuple[Collection[Zone], Collection[Zone]] -def load_landmap(filename: str) -> Landmap: +def load_landmap(filename: str) -> Optional[Landmap]: try: with open(filename, "rb") as f: return pickle.load(f) @@ -30,7 +30,7 @@ def poly_contains(x, y, poly): p1x, p1y = p2x, p2y return inside -def poly_centroid(poly) -> typing.Tuple[float, float]: +def poly_centroid(poly) -> Tuple[float, float]: x_list = [vertex[0] for vertex in poly] y_list = [vertex[1] for vertex in poly] x = sum(x_list) / len(poly) diff --git a/theater/start_generator.py b/theater/start_generator.py index d459cbb1..b14f1b99 100644 --- a/theater/start_generator.py +++ b/theater/start_generator.py @@ -1,19 +1,35 @@ +import logging import math import pickle import random import typing -import logging +from dcs.mapping import Point +from dcs.task import CAP, CAS, PinpointStrike +from dcs.vehicles import AirDefence + +from game import db from game.data.building_data import DEFAULT_AVAILABLE_BUILDINGS from game.settings import Settings -from gen import namegen, TheaterGroundObject +from gen import namegen from gen.defenses.armor_group_generator import generate_armor_group -from gen.fleet.ship_group_generator import generate_carrier_group, generate_lha_group, generate_ship_group +from gen.fleet.ship_group_generator import ( + generate_carrier_group, + generate_lha_group, + generate_ship_group, +) from gen.missiles.missiles_group_generator import generate_missile_group -from gen.sam.sam_group_generator import generate_anti_air_group, generate_shorad_group -from theater import ControlPointType -from theater.base import * -from theater.conflicttheater import * +from gen.sam.sam_group_generator import ( + generate_anti_air_group, + generate_shorad_group, +) +from theater import ( + ConflictTheater, + ControlPoint, + ControlPointType, + TheaterGroundObject, +) +from theater.conflicttheater import IMPORTANCE_HIGH, IMPORTANCE_LOW UNIT_VARIETY = 3 UNIT_AMOUNT_FACTOR = 16 diff --git a/theater/theatergroundobject.py b/theater/theatergroundobject.py index 3ffa86f2..659e366e 100644 --- a/theater/theatergroundobject.py +++ b/theater/theatergroundobject.py @@ -1,7 +1,12 @@ import uuid +from typing import List, TYPE_CHECKING from dcs.mapping import Point +from dcs.unitgroup import Group +if TYPE_CHECKING: + from .conflicttheater import ConflictTheater + from .controlpoint import ControlPoint from .missiontarget import MissionTarget NAME_BY_CATEGORY = { @@ -71,7 +76,7 @@ class TheaterGroundObject(MissionTarget): airbase_group = False heading = 0 position = None # type: Point - groups = [] + groups: List[Group] = [] obj_name = "" sea_object = False uuid = uuid.uuid1()