mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Flesh out typing information, enforce.
(cherry picked from commit fb9a0fe833)
This commit is contained in:
@@ -536,7 +536,11 @@ class AircraftConflictGenerator:
|
||||
)
|
||||
|
||||
def _add_radio_waypoint(
|
||||
self, group: FlyingGroup, position, altitude: Distance, airspeed: int = 600
|
||||
self,
|
||||
group: FlyingGroup,
|
||||
position: Point,
|
||||
altitude: Distance,
|
||||
airspeed: int = 600,
|
||||
) -> MovingPoint:
|
||||
point = group.add_waypoint(position, altitude.meters, airspeed)
|
||||
point.alt_type = "RADIO"
|
||||
@@ -547,7 +551,7 @@ class AircraftConflictGenerator:
|
||||
group: FlyingGroup,
|
||||
cp: ControlPoint,
|
||||
at: Optional[db.StartingPosition] = None,
|
||||
):
|
||||
) -> MovingPoint:
|
||||
if at is None:
|
||||
at = cp.at
|
||||
position = at if isinstance(at, Point) else at.position
|
||||
@@ -563,7 +567,8 @@ class AircraftConflictGenerator:
|
||||
group.land_at(at)
|
||||
return destination_waypoint
|
||||
|
||||
def _at_position(self, at) -> Point:
|
||||
@staticmethod
|
||||
def _at_position(at: Union[Point, ShipGroup, Type[Airport]]) -> Point:
|
||||
if isinstance(at, Point):
|
||||
return at
|
||||
elif isinstance(at, ShipGroup):
|
||||
@@ -593,7 +598,10 @@ class AircraftConflictGenerator:
|
||||
parking_slot.unit_id = None
|
||||
|
||||
def generate_flights(
|
||||
self, country, ato: AirTaskingOrder, dynamic_runways: Dict[str, RunwayData]
|
||||
self,
|
||||
country: Country,
|
||||
ato: AirTaskingOrder,
|
||||
dynamic_runways: Dict[str, RunwayData],
|
||||
) -> None:
|
||||
|
||||
for package in ato.packages:
|
||||
@@ -719,7 +727,9 @@ class AircraftConflictGenerator:
|
||||
|
||||
trigger.add_condition(CoalitionHasAirdrome(coalition, flight.from_cp.id))
|
||||
|
||||
def generate_planned_flight(self, cp, country, flight: Flight):
|
||||
def generate_planned_flight(
|
||||
self, cp: ControlPoint, country: Country, flight: Flight
|
||||
) -> FlyingGroup:
|
||||
name = namegen.next_aircraft_name(country, cp.id, flight)
|
||||
try:
|
||||
if flight.start_type == "In Flight":
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import timedelta
|
||||
from typing import List, Type, Tuple, Optional
|
||||
from typing import List, Type, Tuple, Optional, TYPE_CHECKING
|
||||
|
||||
from dcs.mission import Mission, StartType
|
||||
from dcs.planes import IL_78M, KC130, KC135MPRS, KC_135
|
||||
from dcs.unittype import UnitType
|
||||
from dcs.task import (
|
||||
AWACS,
|
||||
ActivateBeaconCommand,
|
||||
@@ -14,15 +15,17 @@ from dcs.task import (
|
||||
SetImmortalCommand,
|
||||
SetInvisibleCommand,
|
||||
)
|
||||
from dcs.unittype import UnitType
|
||||
|
||||
from game import db
|
||||
from .flights.ai_flight_planner_db import AEWC_CAPABLE
|
||||
from .naming import namegen
|
||||
from .callsigns import callsign_for_support_unit
|
||||
from .conflictgen import Conflict
|
||||
from .flights.ai_flight_planner_db import AEWC_CAPABLE
|
||||
from .naming import namegen
|
||||
from .radios import RadioFrequency, RadioRegistry
|
||||
from .tacan import TacanBand, TacanChannel, TacanRegistry
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
|
||||
TANKER_DISTANCE = 15000
|
||||
TANKER_ALT = 4572
|
||||
@@ -70,7 +73,7 @@ class AirSupportConflictGenerator:
|
||||
self,
|
||||
mission: Mission,
|
||||
conflict: Conflict,
|
||||
game,
|
||||
game: Game,
|
||||
radio_registry: RadioRegistry,
|
||||
tacan_registry: TacanRegistry,
|
||||
) -> None:
|
||||
@@ -95,7 +98,7 @@ class AirSupportConflictGenerator:
|
||||
return (TANKER_ALT + 500, 596)
|
||||
return (TANKER_ALT, 574)
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
player_cp = (
|
||||
self.conflict.blue_cp
|
||||
if self.conflict.blue_cp.captured
|
||||
|
||||
18
gen/armor.py
18
gen/armor.py
@@ -97,7 +97,7 @@ class GroundConflictGenerator:
|
||||
self.unit_map = unit_map
|
||||
self.jtacs: List[JtacInfo] = []
|
||||
|
||||
def _enemy_stance(self):
|
||||
def _enemy_stance(self) -> CombatStance:
|
||||
"""Picks the enemy stance according to the number of planned groups on the frontline for each side"""
|
||||
if len(self.enemy_planned_combat_groups) > len(
|
||||
self.player_planned_combat_groups
|
||||
@@ -122,17 +122,7 @@ class GroundConflictGenerator:
|
||||
]
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _group_point(point: Point, base_distance) -> Point:
|
||||
distance = random.randint(
|
||||
int(base_distance * SPREAD_DISTANCE_FACTOR[0]),
|
||||
int(base_distance * SPREAD_DISTANCE_FACTOR[1]),
|
||||
)
|
||||
return point.random_point_within(
|
||||
distance, base_distance * SPREAD_DISTANCE_SIZE_FACTOR
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
position = Conflict.frontline_position(
|
||||
self.conflict.front_line, self.game.theater
|
||||
)
|
||||
@@ -724,7 +714,7 @@ class GroundConflictGenerator:
|
||||
distance_from_frontline: int,
|
||||
heading: int,
|
||||
spawn_heading: int,
|
||||
):
|
||||
) -> Point:
|
||||
shifted = conflict_position.point_from_heading(
|
||||
heading, random.randint(0, combat_width)
|
||||
)
|
||||
@@ -798,7 +788,7 @@ class GroundConflictGenerator:
|
||||
count: int,
|
||||
at: Point,
|
||||
move_formation: PointAction = PointAction.OffRoad,
|
||||
heading=0,
|
||||
heading: int = 0,
|
||||
) -> VehicleGroup:
|
||||
|
||||
if side == self.conflict.attackers_country:
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import logging
|
||||
import random
|
||||
from game import db
|
||||
from typing import Optional
|
||||
|
||||
from dcs.unitgroup import VehicleGroup
|
||||
|
||||
from game import db, Game
|
||||
from game.theater.theatergroundobject import CoastalSiteGroundObject
|
||||
from gen.coastal.silkworm import SilkwormGenerator
|
||||
|
||||
COASTAL_MAP = {
|
||||
@@ -8,10 +13,13 @@ COASTAL_MAP = {
|
||||
}
|
||||
|
||||
|
||||
def generate_coastal_group(game, ground_object, faction_name: str):
|
||||
def generate_coastal_group(
|
||||
game: Game, ground_object: CoastalSiteGroundObject, faction_name: str
|
||||
) -> Optional[VehicleGroup]:
|
||||
"""
|
||||
This generate a coastal defenses group
|
||||
:return: Nothing, but put the group reference inside the ground object
|
||||
:return: The generated group, or None if this faction does not support coastal
|
||||
defenses.
|
||||
"""
|
||||
faction = db.FACTIONS[faction_name]
|
||||
if len(faction.coastal_defenses) > 0:
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
from dcs.unitgroup import VehicleGroup
|
||||
from dcs.vehicles import MissilesSS, Unarmed, AirDefence
|
||||
|
||||
from game import Game
|
||||
from game.factions.faction import Faction
|
||||
from game.theater.theatergroundobject import CoastalSiteGroundObject
|
||||
from gen.sam.group_generator import GroupGenerator
|
||||
|
||||
|
||||
class SilkwormGenerator(GroupGenerator):
|
||||
def __init__(self, game, ground_object, faction):
|
||||
class SilkwormGenerator(GroupGenerator[VehicleGroup]):
|
||||
def __init__(
|
||||
self, game: Game, ground_object: CoastalSiteGroundObject, faction: Faction
|
||||
) -> None:
|
||||
super(SilkwormGenerator, self).__init__(game, ground_object)
|
||||
self.faction = faction
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
positions = self.get_circular_position(5, launcher_distance=120, coverage=180)
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Tuple, Optional
|
||||
|
||||
@@ -54,7 +56,7 @@ class Conflict:
|
||||
def frontline_position(
|
||||
cls, frontline: FrontLine, theater: ConflictTheater
|
||||
) -> Tuple[Point, int]:
|
||||
attack_heading = frontline.attack_heading
|
||||
attack_heading = int(frontline.attack_heading)
|
||||
position = cls.find_ground_position(
|
||||
frontline.position,
|
||||
FRONTLINE_LENGTH,
|
||||
@@ -91,7 +93,7 @@ class Conflict:
|
||||
defender: Country,
|
||||
front_line: FrontLine,
|
||||
theater: ConflictTheater,
|
||||
):
|
||||
) -> Conflict:
|
||||
assert cls.has_frontline_between(front_line.blue_cp, front_line.red_cp)
|
||||
position, heading, distance = cls.frontline_vector(front_line, theater)
|
||||
conflict = cls(
|
||||
@@ -138,7 +140,7 @@ class Conflict:
|
||||
max_distance: int,
|
||||
heading: int,
|
||||
theater: ConflictTheater,
|
||||
coerce=True,
|
||||
coerce: bool = True,
|
||||
) -> Optional[Point]:
|
||||
"""
|
||||
Finds the nearest valid ground position along a provided heading and it's inverse up to max_distance.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import random
|
||||
from typing import Optional
|
||||
|
||||
from dcs.unitgroup import VehicleGroup
|
||||
|
||||
@@ -12,7 +13,9 @@ from gen.defenses.armored_group_generator import (
|
||||
)
|
||||
|
||||
|
||||
def generate_armor_group(faction: str, game, ground_object):
|
||||
def generate_armor_group(
|
||||
faction: str, game: Game, ground_object: VehicleGroupGroundObject
|
||||
) -> Optional[VehicleGroup]:
|
||||
"""
|
||||
This generate a group of ground units
|
||||
:return: Generated group
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import random
|
||||
|
||||
from dcs.unitgroup import VehicleGroup
|
||||
|
||||
from game import Game
|
||||
from game.dcs.groundunittype import GroundUnitType
|
||||
from game.theater.theatergroundobject import VehicleGroupGroundObject
|
||||
from gen.sam.group_generator import GroupGenerator
|
||||
|
||||
|
||||
class ArmoredGroupGenerator(GroupGenerator):
|
||||
class ArmoredGroupGenerator(GroupGenerator[VehicleGroup]):
|
||||
def __init__(
|
||||
self,
|
||||
game: Game,
|
||||
@@ -35,7 +37,7 @@ class ArmoredGroupGenerator(GroupGenerator):
|
||||
)
|
||||
|
||||
|
||||
class FixedSizeArmorGroupGenerator(GroupGenerator):
|
||||
class FixedSizeArmorGroupGenerator(GroupGenerator[VehicleGroup]):
|
||||
def __init__(
|
||||
self,
|
||||
game: Game,
|
||||
@@ -47,7 +49,7 @@ class FixedSizeArmorGroupGenerator(GroupGenerator):
|
||||
self.unit_type = unit_type
|
||||
self.size = size
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
spacing = random.randint(20, 70)
|
||||
|
||||
index = 0
|
||||
|
||||
@@ -30,7 +30,7 @@ class EnvironmentGenerator:
|
||||
self.mission.weather.wind_at_2000 = wind.at_2000m
|
||||
self.mission.weather.wind_at_8000 = wind.at_8000m
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.mission.start_time = self.conditions.start_time
|
||||
self.set_clouds(self.conditions.weather.clouds)
|
||||
self.set_fog(self.conditions.weather.fog)
|
||||
|
||||
@@ -6,7 +6,7 @@ from dcs.ships import USS_Arleigh_Burke_IIa, TICONDEROG
|
||||
|
||||
|
||||
class CarrierGroupGenerator(ShipGroupGenerator):
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
# Carrier Strike Group 8
|
||||
if self.faction.carrier_names[0] == "Carrier Strike Group 8":
|
||||
|
||||
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class ChineseNavyGroupGenerator(ShipGroupGenerator):
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
include_frigate = random.choice([True, True, False])
|
||||
include_dd = random.choice([True, False])
|
||||
|
||||
@@ -23,7 +23,7 @@ class DDGroupGenerator(ShipGroupGenerator):
|
||||
super(DDGroupGenerator, self).__init__(game, ground_object, faction)
|
||||
self.ddtype = ddtype
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
self.ddtype,
|
||||
"DD1",
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
from dcs.ships import La_Combattante_II
|
||||
|
||||
from game import Game
|
||||
from game.factions.faction import Faction
|
||||
from game.theater import TheaterGroundObject
|
||||
from gen.fleet.dd_group import DDGroupGenerator
|
||||
|
||||
|
||||
class LaCombattanteIIGroupGenerator(DDGroupGenerator):
|
||||
def __init__(self, game, ground_object: TheaterGroundObject, faction: Faction):
|
||||
def __init__(
|
||||
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
|
||||
):
|
||||
super(LaCombattanteIIGroupGenerator, self).__init__(
|
||||
game, ground_object, faction, La_Combattante_II
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ from gen.sam.group_generator import ShipGroupGenerator
|
||||
|
||||
|
||||
class LHAGroupGenerator(ShipGroupGenerator):
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
# Add carrier
|
||||
if len(self.faction.helicopter_carrier) > 0:
|
||||
|
||||
@@ -23,7 +23,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class RussianNavyGroupGenerator(ShipGroupGenerator):
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
include_frigate = random.choice([True, True, False])
|
||||
include_dd = random.choice([True, False])
|
||||
|
||||
@@ -6,7 +6,7 @@ from gen.sam.group_generator import ShipGroupGenerator
|
||||
|
||||
|
||||
class SchnellbootGroupGenerator(ShipGroupGenerator):
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
for i in range(random.randint(2, 4)):
|
||||
self.add_unit(
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import random
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from dcs.unitgroup import ShipGroup
|
||||
|
||||
from game import db
|
||||
from game.theater.theatergroundobject import (
|
||||
LhaGroundObject,
|
||||
CarrierGroundObject,
|
||||
ShipGroundObject,
|
||||
)
|
||||
from gen.fleet.carrier_group import CarrierGroupGenerator
|
||||
from gen.fleet.cn_dd_group import ChineseNavyGroupGenerator, Type54GroupGenerator
|
||||
from gen.fleet.dd_group import (
|
||||
@@ -21,6 +31,9 @@ from gen.fleet.schnellboot import SchnellbootGroupGenerator
|
||||
from gen.fleet.uboat import UBoatGroupGenerator
|
||||
from gen.fleet.ww2lst import WW2LSTGroupGenerator
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
|
||||
|
||||
SHIP_MAP = {
|
||||
"SchnellbootGroupGenerator": SchnellbootGroupGenerator,
|
||||
@@ -39,10 +52,12 @@ SHIP_MAP = {
|
||||
}
|
||||
|
||||
|
||||
def generate_ship_group(game, ground_object, faction_name: str):
|
||||
def generate_ship_group(
|
||||
game: Game, ground_object: ShipGroundObject, faction_name: str
|
||||
) -> Optional[ShipGroup]:
|
||||
"""
|
||||
This generate a ship group
|
||||
:return: Nothing, but put the group reference inside the ground object
|
||||
:return: The generated group, or None if this faction does not support ships.
|
||||
"""
|
||||
faction = db.FACTIONS[faction_name]
|
||||
if len(faction.navy_generators) > 0:
|
||||
@@ -61,26 +76,30 @@ def generate_ship_group(game, ground_object, faction_name: str):
|
||||
return None
|
||||
|
||||
|
||||
def generate_carrier_group(faction: str, game, ground_object):
|
||||
"""
|
||||
This generate a carrier group
|
||||
:param parentCp: The parent control point
|
||||
def generate_carrier_group(
|
||||
faction: str, game: Game, ground_object: CarrierGroundObject
|
||||
) -> ShipGroup:
|
||||
"""Generates a carrier group.
|
||||
|
||||
:param faction: The faction the TGO belongs to.
|
||||
:param game: The Game the group is being generated for.
|
||||
:param ground_object: The ground object which will own the ship group
|
||||
:param country: Owner country
|
||||
:return: Nothing, but put the group reference inside the ground object
|
||||
:return: The generated group.
|
||||
"""
|
||||
generator = CarrierGroupGenerator(game, ground_object, db.FACTIONS[faction])
|
||||
generator.generate()
|
||||
return generator.get_generated_group()
|
||||
|
||||
|
||||
def generate_lha_group(faction: str, game, ground_object):
|
||||
"""
|
||||
This generate a lha carrier group
|
||||
:param parentCp: The parent control point
|
||||
def generate_lha_group(
|
||||
faction: str, game: Game, ground_object: LhaGroundObject
|
||||
) -> ShipGroup:
|
||||
"""Generate an LHA group.
|
||||
|
||||
:param faction: The faction the TGO belongs to.
|
||||
:param game: The Game the group is being generated for.
|
||||
:param ground_object: The ground object which will own the ship group
|
||||
:param country: Owner country
|
||||
:return: Nothing, but put the group reference inside the ground object
|
||||
:return: The generated group.
|
||||
"""
|
||||
generator = LHAGroupGenerator(game, ground_object, db.FACTIONS[faction])
|
||||
generator.generate()
|
||||
|
||||
@@ -6,7 +6,7 @@ from gen.sam.group_generator import ShipGroupGenerator
|
||||
|
||||
|
||||
class UBoatGroupGenerator(ShipGroupGenerator):
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
for i in range(random.randint(1, 4)):
|
||||
self.add_unit(
|
||||
|
||||
@@ -6,7 +6,7 @@ from gen.sam.group_generator import ShipGroupGenerator
|
||||
|
||||
|
||||
class WW2LSTGroupGenerator(ShipGroupGenerator):
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
# Add LS Samuel Chase
|
||||
self.add_unit(
|
||||
|
||||
@@ -1057,7 +1057,7 @@ class CoalitionMissionPlanner:
|
||||
# delayed until their takeoff time by AirConflictGenerator.
|
||||
package.time_over_target = next(start_time) + tot
|
||||
|
||||
def message(self, title, text) -> None:
|
||||
def message(self, title: str, text: str) -> None:
|
||||
"""Emits a planning message to the player.
|
||||
|
||||
If the mission planner belongs to the players coalition, this emits a
|
||||
|
||||
@@ -8,7 +8,6 @@ from dcs.mapping import Point
|
||||
from dcs.point import MovingPoint, PointAction
|
||||
from dcs.unit import Unit
|
||||
|
||||
from game import db
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
from game.squadrons import Pilot, Squadron
|
||||
from game.theater.controlpoint import ControlPoint, MissionTarget
|
||||
@@ -323,12 +322,12 @@ class Flight:
|
||||
def clear_roster(self) -> None:
|
||||
self.roster.clear()
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
if self.custom_name:
|
||||
return f"{self.custom_name} {self.count} x {self.unit_type}"
|
||||
return f"[{self.flight_type}] {self.count} x {self.unit_type}"
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
if self.custom_name:
|
||||
return f"{self.custom_name} {self.count} x {self.unit_type}"
|
||||
return f"[{self.flight_type}] {self.count} x {self.unit_type}"
|
||||
|
||||
@@ -43,7 +43,7 @@ class ForcedOptionsGenerator:
|
||||
if blue.unrestricted_satnav or red.unrestricted_satnav:
|
||||
self.mission.forced_options.unrestricted_satnav = True
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self._set_options_view()
|
||||
self._set_external_views()
|
||||
self._set_labels()
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import random
|
||||
from enum import Enum
|
||||
from typing import Dict, List
|
||||
from typing import Dict, List, TYPE_CHECKING
|
||||
|
||||
from game.data.groundunitclass import GroundUnitClass
|
||||
from game.dcs.groundunittype import GroundUnitType
|
||||
from game.theater import ControlPoint
|
||||
from gen.ground_forces.combat_stance import CombatStance
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
|
||||
MAX_COMBAT_GROUP_PER_CP = 10
|
||||
|
||||
|
||||
@@ -54,7 +59,7 @@ class CombatGroup:
|
||||
self.role = role
|
||||
self.start_position = None
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
s = f"ROLE : {self.role}\n"
|
||||
if self.size:
|
||||
s += f"UNITS {self.unit_type} * {self.size}"
|
||||
@@ -62,7 +67,7 @@ class CombatGroup:
|
||||
|
||||
|
||||
class GroundPlanner:
|
||||
def __init__(self, cp: ControlPoint, game):
|
||||
def __init__(self, cp: ControlPoint, game: Game) -> None:
|
||||
self.cp = cp
|
||||
self.game = game
|
||||
self.connected_enemy_cp = [
|
||||
@@ -82,7 +87,7 @@ class GroundPlanner:
|
||||
self.units_per_cp[cp.id] = []
|
||||
self.reserve: List[CombatGroup] = []
|
||||
|
||||
def plan_groundwar(self):
|
||||
def plan_groundwar(self) -> None:
|
||||
|
||||
ground_unit_limit = self.cp.frontline_unit_count_limit
|
||||
|
||||
|
||||
@@ -624,7 +624,7 @@ class GroundObjectsGenerator:
|
||||
self.icls_alloc = iter(range(1, 21))
|
||||
self.runways: Dict[str, RunwayData] = {}
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
for cp in self.game.theater.controlpoints:
|
||||
if cp.captured:
|
||||
country_name = self.game.player_country
|
||||
|
||||
@@ -91,7 +91,10 @@ class KneeboardPageWriter:
|
||||
return self.x, self.y
|
||||
|
||||
def text(
|
||||
self, text: str, font=None, fill: Tuple[int, int, int] = (0, 0, 0)
|
||||
self,
|
||||
text: str,
|
||||
font: Optional[ImageFont.ImageFont] = None,
|
||||
fill: Tuple[int, int, int] = (0, 0, 0),
|
||||
) -> None:
|
||||
if font is None:
|
||||
font = self.content_font
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from typing import List
|
||||
|
||||
from gen.locations.preset_locations import PresetLocation
|
||||
|
||||
|
||||
@dataclass
|
||||
class PresetControlPointLocations:
|
||||
"""A repository of preset locations for a given control point"""
|
||||
|
||||
# List of possible ashore locations to generate objects (Represented in miz file by an APC_AAV_7_Amphibious)
|
||||
ashore_locations: List[PresetLocation] = field(default_factory=list)
|
||||
|
||||
# List of possible offshore locations to generate ship groups (Represented in miz file by an Oliver Hazard Perry)
|
||||
offshore_locations: List[PresetLocation] = field(default_factory=list)
|
||||
|
||||
# Possible antiship missiles sites locations (Represented in miz file by Iranian Silkworm missiles)
|
||||
antiship_locations: List[PresetLocation] = field(default_factory=list)
|
||||
|
||||
# List of possible powerplants locations (Represented in miz file by static Workshop A object, USA)
|
||||
powerplant_locations: List[PresetLocation] = field(default_factory=list)
|
||||
@@ -1,21 +0,0 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
from dcs import Point
|
||||
|
||||
|
||||
@dataclass
|
||||
class PresetLocation:
|
||||
"""A preset location"""
|
||||
|
||||
position: Point
|
||||
heading: int
|
||||
id: str
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
"-" * 10
|
||||
+ "X: {}\n Y: {}\nHdg: {}°\nId: {}".format(
|
||||
self.position.x, self.position.y, self.heading, self.id
|
||||
)
|
||||
+ "-" * 10
|
||||
)
|
||||
@@ -1,13 +1,20 @@
|
||||
import logging
|
||||
import random
|
||||
from game import db
|
||||
from typing import Optional
|
||||
|
||||
from dcs.unitgroup import VehicleGroup
|
||||
|
||||
from game import db, Game
|
||||
from game.theater.theatergroundobject import MissileSiteGroundObject
|
||||
from gen.missiles.scud_site import ScudGenerator
|
||||
from gen.missiles.v1_group import V1GroupGenerator
|
||||
|
||||
MISSILES_MAP = {"V1GroupGenerator": V1GroupGenerator, "ScudGenerator": ScudGenerator}
|
||||
|
||||
|
||||
def generate_missile_group(game, ground_object, faction_name: str):
|
||||
def generate_missile_group(
|
||||
game: Game, ground_object: MissileSiteGroundObject, faction_name: str
|
||||
) -> Optional[VehicleGroup]:
|
||||
"""
|
||||
This generate a missiles group
|
||||
:return: Nothing, but put the group reference inside the ground object
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
import random
|
||||
|
||||
from dcs.unitgroup import VehicleGroup
|
||||
from dcs.vehicles import Unarmed, MissilesSS, AirDefence
|
||||
|
||||
from game import Game
|
||||
from game.factions.faction import Faction
|
||||
from game.theater.theatergroundobject import MissileSiteGroundObject
|
||||
from gen.sam.group_generator import GroupGenerator
|
||||
|
||||
|
||||
class ScudGenerator(GroupGenerator):
|
||||
def __init__(self, game, ground_object, faction):
|
||||
class ScudGenerator(GroupGenerator[VehicleGroup]):
|
||||
def __init__(
|
||||
self, game: Game, ground_object: MissileSiteGroundObject, faction: Faction
|
||||
) -> None:
|
||||
super(ScudGenerator, self).__init__(game, ground_object)
|
||||
self.faction = faction
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
# Scuds
|
||||
self.add_unit(
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
import random
|
||||
|
||||
from dcs.unitgroup import VehicleGroup
|
||||
from dcs.vehicles import Unarmed, MissilesSS, AirDefence
|
||||
|
||||
from game import Game
|
||||
from game.factions.faction import Faction
|
||||
from game.theater.theatergroundobject import MissileSiteGroundObject
|
||||
from gen.sam.group_generator import GroupGenerator
|
||||
|
||||
|
||||
class V1GroupGenerator(GroupGenerator):
|
||||
def __init__(self, game, ground_object, faction):
|
||||
class V1GroupGenerator(GroupGenerator[VehicleGroup]):
|
||||
def __init__(
|
||||
self, game: Game, ground_object: MissileSiteGroundObject, faction: Faction
|
||||
) -> None:
|
||||
super(V1GroupGenerator, self).__init__(game, ground_object)
|
||||
self.faction = faction
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
# Ramps
|
||||
self.add_unit(
|
||||
|
||||
@@ -257,7 +257,7 @@ class NameGenerator:
|
||||
existing_alphas: List[str] = []
|
||||
|
||||
@classmethod
|
||||
def reset(cls):
|
||||
def reset(cls) -> None:
|
||||
cls.number = 0
|
||||
cls.infantry_number = 0
|
||||
cls.convoy_number = 0
|
||||
@@ -266,7 +266,7 @@ class NameGenerator:
|
||||
cls.existing_alphas = []
|
||||
|
||||
@classmethod
|
||||
def reset_numbers(cls):
|
||||
def reset_numbers(cls) -> None:
|
||||
cls.number = 0
|
||||
cls.infantry_number = 0
|
||||
cls.aircraft_number = 0
|
||||
@@ -274,7 +274,9 @@ class NameGenerator:
|
||||
cls.cargo_ship_number = 0
|
||||
|
||||
@classmethod
|
||||
def next_aircraft_name(cls, country: Country, parent_base_id: int, flight: Flight):
|
||||
def next_aircraft_name(
|
||||
cls, country: Country, parent_base_id: int, flight: Flight
|
||||
) -> str:
|
||||
cls.aircraft_number += 1
|
||||
try:
|
||||
if flight.custom_name:
|
||||
@@ -315,17 +317,17 @@ class NameGenerator:
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def next_awacs_name(cls, country: Country):
|
||||
def next_awacs_name(cls, country: Country) -> str:
|
||||
cls.number += 1
|
||||
return "awacs|{}|{}|0|".format(country.id, cls.number)
|
||||
|
||||
@classmethod
|
||||
def next_tanker_name(cls, country: Country, unit_type: AircraftType):
|
||||
def next_tanker_name(cls, country: Country, unit_type: AircraftType) -> str:
|
||||
cls.number += 1
|
||||
return "tanker|{}|{}|0|{}".format(country.id, cls.number, unit_type.name)
|
||||
|
||||
@classmethod
|
||||
def next_carrier_name(cls, country: Country):
|
||||
def next_carrier_name(cls, country: Country) -> str:
|
||||
cls.number += 1
|
||||
return "carrier|{}|{}|0|".format(country.id, cls.number)
|
||||
|
||||
@@ -340,7 +342,7 @@ class NameGenerator:
|
||||
return f"Cargo Ship {cls.cargo_ship_number:03}"
|
||||
|
||||
@classmethod
|
||||
def random_objective_name(cls):
|
||||
def random_objective_name(cls) -> str:
|
||||
if cls.animals:
|
||||
animal = random.choice(cls.animals)
|
||||
cls.animals.remove(animal)
|
||||
|
||||
@@ -15,7 +15,7 @@ class RadioFrequency:
|
||||
#: The frequency in kilohertz.
|
||||
hertz: int
|
||||
|
||||
def __str__(self):
|
||||
def __str__(self) -> str:
|
||||
if self.hertz >= 1000000:
|
||||
return self.format("MHz", 1000000)
|
||||
return self.format("kHz", 1000)
|
||||
|
||||
@@ -15,7 +15,7 @@ class BoforsGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Bofors AAA"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
index = 0
|
||||
for i in range(4):
|
||||
|
||||
@@ -24,7 +24,7 @@ class FlakGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Flak Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
index = 0
|
||||
mixed = random.choice([True, False])
|
||||
unit_type = random.choice(GFLAK)
|
||||
|
||||
@@ -15,7 +15,7 @@ class Flak18Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "WW2 Flak Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
spacing = random.randint(30, 60)
|
||||
index = 0
|
||||
|
||||
@@ -14,7 +14,7 @@ class KS19Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "KS-19 AAA Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
highdigitsams.AAA_SON_9_Fire_Can,
|
||||
"TR",
|
||||
|
||||
@@ -15,7 +15,7 @@ class AllyWW2FlakGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "WW2 Ally Flak Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
positions = self.get_circular_position(4, launcher_distance=30, coverage=360)
|
||||
for i, position in enumerate(positions):
|
||||
|
||||
@@ -13,7 +13,7 @@ class ZSU57Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "ZSU-57-2 Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 4
|
||||
positions = self.get_circular_position(
|
||||
num_launchers, launcher_distance=110, coverage=360
|
||||
|
||||
@@ -15,7 +15,7 @@ class ZU23InsurgentGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Zu-23 Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
index = 0
|
||||
for i in range(4):
|
||||
index = index + 1
|
||||
|
||||
@@ -38,7 +38,7 @@ class AirDefenseRange(Enum):
|
||||
self.default_role = default_role
|
||||
|
||||
|
||||
class AirDefenseGroupGenerator(GroupGenerator, ABC):
|
||||
class AirDefenseGroupGenerator(GroupGenerator[VehicleGroup], ABC):
|
||||
"""
|
||||
This is the base for all SAM group generators
|
||||
"""
|
||||
|
||||
@@ -18,7 +18,7 @@ class EarlyColdWarFlakGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Early Cold War Flak Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
spacing = random.randint(30, 60)
|
||||
index = 0
|
||||
@@ -90,7 +90,7 @@ class ColdWarFlakGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Cold War Flak Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
spacing = random.randint(30, 60)
|
||||
index = 0
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
from typing import Type
|
||||
|
||||
from dcs.unitgroup import VehicleGroup
|
||||
from dcs.vehicles import AirDefence
|
||||
from dcs.unittype import VehicleType
|
||||
|
||||
from gen.sam.group_generator import GroupGenerator
|
||||
|
||||
|
||||
class EwrGenerator(GroupGenerator):
|
||||
class EwrGenerator(GroupGenerator[VehicleGroup]):
|
||||
unit_type: Type[VehicleType]
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -13,7 +13,7 @@ class FreyaGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Freya EWR Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
|
||||
# TODO : would be better with the Concrete structure that is supposed to protect it
|
||||
self.add_unit(
|
||||
|
||||
@@ -3,13 +3,15 @@ from __future__ import annotations
|
||||
import logging
|
||||
import math
|
||||
import random
|
||||
from typing import TYPE_CHECKING, Type
|
||||
from collections import Iterable
|
||||
from typing import TYPE_CHECKING, Type, TypeVar, Generic
|
||||
|
||||
from dcs import unitgroup
|
||||
from dcs.mapping import Point
|
||||
from dcs.point import PointAction
|
||||
from dcs.unit import Ship, Vehicle
|
||||
from dcs.unittype import VehicleType
|
||||
from dcs.unitgroup import MovingGroup, ShipGroup
|
||||
from dcs.unittype import VehicleType, UnitType
|
||||
|
||||
from game.dcs.groundunittype import GroundUnitType
|
||||
from game.factions.faction import Faction
|
||||
@@ -19,12 +21,15 @@ if TYPE_CHECKING:
|
||||
from game.game import Game
|
||||
|
||||
|
||||
GroupType = TypeVar("GroupType", bound=MovingGroup)
|
||||
|
||||
|
||||
# TODO: Generate a group description rather than a pydcs group.
|
||||
# It appears that all of this work gets redone at miz generation time (see
|
||||
# groundobjectsgen for an example). We can do less work and include the data we
|
||||
# care about in the format we want if we just generate our own group description
|
||||
# types rather than pydcs groups.
|
||||
class GroupGenerator:
|
||||
class GroupGenerator(Generic[GroupType]):
|
||||
|
||||
price: int
|
||||
|
||||
@@ -38,10 +43,10 @@ class GroupGenerator:
|
||||
wp = self.vg.add_waypoint(self.position, PointAction.OffRoad, 0)
|
||||
wp.ETA_locked = True
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def get_generated_group(self) -> unitgroup.VehicleGroup:
|
||||
def get_generated_group(self) -> GroupType:
|
||||
return self.vg
|
||||
|
||||
def add_unit(
|
||||
@@ -58,7 +63,7 @@ class GroupGenerator:
|
||||
|
||||
def add_unit_to_group(
|
||||
self,
|
||||
group: unitgroup.VehicleGroup,
|
||||
group: GroupType,
|
||||
unit_type: Type[VehicleType],
|
||||
name: str,
|
||||
position: Point,
|
||||
@@ -78,7 +83,9 @@ class GroupGenerator:
|
||||
|
||||
return unit
|
||||
|
||||
def get_circular_position(self, num_units, launcher_distance, coverage=90):
|
||||
def get_circular_position(
|
||||
self, num_units: int, launcher_distance: int, coverage: int = 90
|
||||
) -> Iterable[tuple[float, float, int]]:
|
||||
"""
|
||||
Given a position on the map, array a group of units in a circle a uniform distance from the unit
|
||||
:param num_units:
|
||||
@@ -104,21 +111,20 @@ class GroupGenerator:
|
||||
else:
|
||||
current_offset = self.heading
|
||||
current_offset -= outer_offset * (math.ceil(num_units / 2) - 1)
|
||||
for x in range(1, num_units + 1):
|
||||
positions.append(
|
||||
(
|
||||
self.position.x
|
||||
+ launcher_distance * math.cos(math.radians(current_offset)),
|
||||
self.position.y
|
||||
+ launcher_distance * math.sin(math.radians(current_offset)),
|
||||
current_offset,
|
||||
)
|
||||
for _ in range(1, num_units + 1):
|
||||
x: float = self.position.x + launcher_distance * math.cos(
|
||||
math.radians(current_offset)
|
||||
)
|
||||
y: float = self.position.y + launcher_distance * math.sin(
|
||||
math.radians(current_offset)
|
||||
)
|
||||
heading = current_offset
|
||||
positions.append((x, y, int(heading)))
|
||||
current_offset += outer_offset
|
||||
return positions
|
||||
|
||||
|
||||
class ShipGroupGenerator(GroupGenerator):
|
||||
class ShipGroupGenerator(GroupGenerator[ShipGroup]):
|
||||
"""Abstract class for other ship generator classes"""
|
||||
|
||||
def __init__(
|
||||
@@ -133,7 +139,14 @@ class ShipGroupGenerator(GroupGenerator):
|
||||
wp = self.vg.add_waypoint(self.position, 0)
|
||||
wp.ETA_locked = True
|
||||
|
||||
def add_unit(self, unit_type, name, pos_x, pos_y, heading) -> Ship:
|
||||
def add_unit(
|
||||
self,
|
||||
unit_type: Type[UnitType],
|
||||
name: str,
|
||||
pos_x: float,
|
||||
pos_y: float,
|
||||
heading: int,
|
||||
) -> Ship:
|
||||
unit = Ship(self.game.next_unit_id(), f"{self.go.group_name}|{name}", unit_type)
|
||||
unit.position.x = pos_x
|
||||
unit.position.y = pos_y
|
||||
|
||||
@@ -15,7 +15,7 @@ class AvengerGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Avenger Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 2
|
||||
|
||||
self.add_unit(
|
||||
|
||||
@@ -15,7 +15,7 @@ class ChaparralGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Chaparral Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 2
|
||||
|
||||
self.add_unit(
|
||||
|
||||
@@ -15,7 +15,7 @@ class GepardGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Gepard Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 2
|
||||
|
||||
positions = self.get_circular_position(
|
||||
|
||||
@@ -17,7 +17,7 @@ class HawkGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Hawk Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
AirDefence.Hawk_sr,
|
||||
"SR",
|
||||
|
||||
@@ -17,7 +17,7 @@ class HQ7Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "HQ-7 Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
AirDefence.HQ_7_STR_SP,
|
||||
"STR",
|
||||
|
||||
@@ -15,7 +15,7 @@ class LinebackerGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Linebacker Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 2
|
||||
|
||||
self.add_unit(
|
||||
|
||||
@@ -15,7 +15,7 @@ class PatriotGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Patriot Battery"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
# Command Post
|
||||
self.add_unit(
|
||||
AirDefence.Patriot_str,
|
||||
|
||||
@@ -16,7 +16,7 @@ class RapierGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Rapier AA Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
AirDefence.Rapier_fsa_blindfire_radar,
|
||||
"BT",
|
||||
|
||||
@@ -14,7 +14,7 @@ class RolandGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Roland Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 2
|
||||
self.add_unit(
|
||||
AirDefence.Roland_Radar,
|
||||
|
||||
@@ -28,7 +28,7 @@ class SA10Generator(AirDefenseGroupGenerator):
|
||||
self.ln1 = AirDefence.S_300PS_5P85C_ln
|
||||
self.ln2 = AirDefence.S_300PS_5P85D_ln
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
# Search Radar
|
||||
self.add_unit(
|
||||
self.sr1, "SR1", self.position.x, self.position.y + 40, self.heading
|
||||
|
||||
@@ -15,7 +15,7 @@ class SA11Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-11 Buk Battery"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
AirDefence.SA_11_Buk_SR_9S18M1,
|
||||
"SR",
|
||||
|
||||
@@ -15,7 +15,7 @@ class SA13Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-13 Strela Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
Unarmed.UAZ_469,
|
||||
"UAZ",
|
||||
|
||||
@@ -13,7 +13,7 @@ class SA15Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-15 Tor Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 2
|
||||
positions = self.get_circular_position(
|
||||
num_launchers, launcher_distance=120, coverage=360
|
||||
|
||||
@@ -14,7 +14,7 @@ class SA17Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-17 Grizzly Battery"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
AirDefence.SA_11_Buk_SR_9S18M1,
|
||||
"SR",
|
||||
|
||||
@@ -15,7 +15,7 @@ class SA19Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-19 Tunguska Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 2
|
||||
|
||||
if num_launchers == 1:
|
||||
|
||||
@@ -15,7 +15,7 @@ class SA2Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-2/S-75 Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
AirDefence.P_19_s_125_sr,
|
||||
"SR",
|
||||
|
||||
@@ -15,7 +15,7 @@ class SA3Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-3/S-125 Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
AirDefence.P_19_s_125_sr,
|
||||
"SR",
|
||||
|
||||
@@ -15,7 +15,7 @@ class SA6Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-6 Kub Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
AirDefence.Kub_1S91_str,
|
||||
"STR",
|
||||
|
||||
@@ -13,7 +13,7 @@ class SA8Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-8 OSA Site"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 2
|
||||
positions = self.get_circular_position(
|
||||
num_launchers, launcher_distance=120, coverage=180
|
||||
|
||||
@@ -15,7 +15,7 @@ class SA9Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "SA-9 Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self.add_unit(
|
||||
Unarmed.UAZ_469,
|
||||
"UAZ",
|
||||
|
||||
@@ -15,7 +15,7 @@ class VulcanGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "Vulcan Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 2
|
||||
|
||||
positions = self.get_circular_position(
|
||||
|
||||
@@ -15,7 +15,7 @@ class ZSU23Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "ZSU-23 Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 4
|
||||
|
||||
positions = self.get_circular_position(
|
||||
|
||||
@@ -15,7 +15,7 @@ class ZU23Generator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "ZU-23 Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
index = 0
|
||||
for i in range(4):
|
||||
index = index + 1
|
||||
|
||||
@@ -15,7 +15,7 @@ class ZU23UralGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "ZU-23 Ural Group"
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
num_launchers = 4
|
||||
|
||||
positions = self.get_circular_position(
|
||||
|
||||
@@ -15,7 +15,11 @@ class ZU23UralInsurgentGenerator(AirDefenseGroupGenerator):
|
||||
|
||||
name = "ZU-23 Ural Insurgent Group"
|
||||
|
||||
def generate(self):
|
||||
@classmethod
|
||||
def range(cls) -> AirDefenseRange:
|
||||
return AirDefenseRange.AAA
|
||||
|
||||
def generate(self) -> None:
|
||||
num_launchers = 4
|
||||
|
||||
positions = self.get_circular_position(
|
||||
@@ -29,7 +33,3 @@ class ZU23UralInsurgentGenerator(AirDefenseGroupGenerator):
|
||||
position[1],
|
||||
position[2],
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def range(cls) -> AirDefenseRange:
|
||||
return AirDefenseRange.AAA
|
||||
|
||||
@@ -51,11 +51,11 @@ class TriggersGenerator:
|
||||
capture_zone_types = (Fob,)
|
||||
capture_zone_flag = 600
|
||||
|
||||
def __init__(self, mission: Mission, game: Game):
|
||||
def __init__(self, mission: Mission, game: Game) -> None:
|
||||
self.mission = mission
|
||||
self.game = game
|
||||
|
||||
def _set_allegiances(self, player_coalition: str, enemy_coalition: str):
|
||||
def _set_allegiances(self, player_coalition: str, enemy_coalition: str) -> None:
|
||||
"""
|
||||
Set airbase initial coalition
|
||||
"""
|
||||
@@ -87,7 +87,7 @@ class TriggersGenerator:
|
||||
cp.captured and player_coalition or enemy_coalition
|
||||
)
|
||||
|
||||
def _set_skill(self, player_coalition: str, enemy_coalition: str):
|
||||
def _set_skill(self, player_coalition: str, enemy_coalition: str) -> None:
|
||||
"""
|
||||
Set skill level for all aircraft in the mission
|
||||
"""
|
||||
@@ -103,7 +103,7 @@ class TriggersGenerator:
|
||||
for vehicle_group in country.vehicle_group:
|
||||
vehicle_group.set_skill(skill_level)
|
||||
|
||||
def _gen_markers(self):
|
||||
def _gen_markers(self) -> None:
|
||||
"""
|
||||
Generate markers on F10 map for each existing objective
|
||||
"""
|
||||
@@ -188,7 +188,7 @@ class TriggersGenerator:
|
||||
recapture_trigger.add_action(ClearFlag(flag=flag))
|
||||
self.mission.triggerrules.triggers.append(recapture_trigger)
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
player_coalition = "blue"
|
||||
enemy_coalition = "red"
|
||||
|
||||
@@ -198,7 +198,7 @@ class TriggersGenerator:
|
||||
self._generate_capture_triggers(player_coalition, enemy_coalition)
|
||||
|
||||
@classmethod
|
||||
def get_capture_zone_flag(cls):
|
||||
def get_capture_zone_flag(cls) -> int:
|
||||
flag = cls.capture_zone_flag
|
||||
cls.capture_zone_flag += 1
|
||||
return flag
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from dcs.mapping import Point
|
||||
from dcs.mission import Mission
|
||||
from dcs.unit import Static
|
||||
from dcs.unittype import StaticType
|
||||
@@ -11,7 +10,7 @@ from dcs.unittype import StaticType
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
|
||||
from .conflictgen import Conflict, FRONTLINE_LENGTH
|
||||
from .conflictgen import Conflict
|
||||
|
||||
|
||||
class MarkerSmoke(StaticType):
|
||||
@@ -46,13 +45,7 @@ class MassiveSmoke(StaticType):
|
||||
rate = 1
|
||||
|
||||
|
||||
class Outpost(StaticType):
|
||||
id = "outpost"
|
||||
name = "outpost"
|
||||
category = "Fortifications"
|
||||
|
||||
|
||||
def __monkey_static_dict(self: Static):
|
||||
def __monkey_static_dict(self: Static) -> dict[str, Any]:
|
||||
global __original_static_dict
|
||||
|
||||
d = __original_static_dict(self)
|
||||
@@ -65,7 +58,6 @@ def __monkey_static_dict(self: Static):
|
||||
__original_static_dict = Static.dict
|
||||
Static.dict = __monkey_static_dict
|
||||
|
||||
FRONT_SMOKE_SPACING = 800
|
||||
FRONT_SMOKE_RANDOM_SPREAD = 4000
|
||||
FRONT_SMOKE_TYPE_CHANCES = {
|
||||
2: MassiveSmoke,
|
||||
@@ -74,29 +66,13 @@ FRONT_SMOKE_TYPE_CHANCES = {
|
||||
100: Smoke,
|
||||
}
|
||||
|
||||
DESTINATION_SMOKE_AMOUNT_FACTOR = 0.03
|
||||
DESTINATION_SMOKE_DISTANCE_FACTOR = 1
|
||||
DESTINATION_SMOKE_TYPE_CHANCES = {
|
||||
5: BigSmoke,
|
||||
100: Smoke,
|
||||
}
|
||||
|
||||
|
||||
def turn_heading(heading, fac):
|
||||
heading += fac
|
||||
if heading > 359:
|
||||
heading = heading - 359
|
||||
if heading < 0:
|
||||
heading = 359 + heading
|
||||
return heading
|
||||
|
||||
|
||||
class VisualGenerator:
|
||||
def __init__(self, mission: Mission, game: Game):
|
||||
def __init__(self, mission: Mission, game: Game) -> None:
|
||||
self.mission = mission
|
||||
self.game = game
|
||||
|
||||
def _generate_frontline_smokes(self):
|
||||
def _generate_frontline_smokes(self) -> None:
|
||||
for front_line in self.game.theater.conflicts():
|
||||
from_cp = front_line.blue_cp
|
||||
to_cp = front_line.red_cp
|
||||
@@ -128,61 +104,5 @@ class VisualGenerator:
|
||||
)
|
||||
break
|
||||
|
||||
def _generate_stub_planes(self):
|
||||
pass
|
||||
"""
|
||||
mission_units = set()
|
||||
for coalition_name, coalition in self.mission.coalition.items():
|
||||
for country in coalition.countries.values():
|
||||
for group in country.plane_group + country.helicopter_group + country.vehicle_group:
|
||||
for unit in group.units:
|
||||
mission_units.add(db.unit_type_of(unit))
|
||||
|
||||
for unit_type in mission_units:
|
||||
self.mission.static_group(self.mission.country(self.game.player_country), "a", unit_type, Point(0, 300000), hidden=True)"""
|
||||
|
||||
def generate_target_smokes(self, target):
|
||||
spread = target.size * DESTINATION_SMOKE_DISTANCE_FACTOR
|
||||
for _ in range(
|
||||
0,
|
||||
int(
|
||||
target.size
|
||||
* DESTINATION_SMOKE_AMOUNT_FACTOR
|
||||
* (1.1 - target.base.strength)
|
||||
),
|
||||
):
|
||||
for k, v in DESTINATION_SMOKE_TYPE_CHANCES.items():
|
||||
if random.randint(0, 100) <= k:
|
||||
position = target.position.random_point_within(0, spread)
|
||||
if not self.game.theater.is_on_land(position):
|
||||
break
|
||||
|
||||
self.mission.static_group(
|
||||
self.mission.country(self.game.enemy_country),
|
||||
"",
|
||||
_type=v,
|
||||
position=position,
|
||||
hidden=True,
|
||||
)
|
||||
break
|
||||
|
||||
def generate_transportation_marker(self, at: Point):
|
||||
self.mission.static_group(
|
||||
self.mission.country(self.game.player_country),
|
||||
"",
|
||||
_type=MarkerSmoke,
|
||||
position=at,
|
||||
)
|
||||
|
||||
def generate_transportation_destination(self, at: Point):
|
||||
self.generate_transportation_marker(at.point_from_heading(0, 20))
|
||||
self.mission.static_group(
|
||||
self.mission.country(self.game.player_country),
|
||||
"",
|
||||
_type=Outpost,
|
||||
position=at,
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
def generate(self) -> None:
|
||||
self._generate_frontline_smokes()
|
||||
self._generate_stub_planes()
|
||||
|
||||
Reference in New Issue
Block a user