Add EWR generation.

Fixes https://github.com/Khopa/dcs_liberation/issues/66
This commit is contained in:
Dan Albert 2020-11-07 15:00:05 -08:00
parent 18f9b38d25
commit e8feded4c3
50 changed files with 364 additions and 54 deletions

View File

@ -57,6 +57,9 @@ class Faction:
# Possible SAMS site generators for this faction
sams: List[str] = field(default_factory=list)
# Possible EWR generators for this faction.
ewrs: List[str] = field(default_factory=list)
# Possible Missile site generators for this faction
missiles: List[str] = field(default_factory=list)
@ -132,6 +135,7 @@ class Faction:
json.get("logistics_units", []))
faction.sams = json.get("sams", [])
faction.ewrs = json.get("ewrs", [])
faction.shorads = json.get("shorads", [])
faction.missiles = json.get("missiles", [])
faction.requirements = json.get("requirements", {})

98
gen/sam/ewrs.py Normal file
View File

@ -0,0 +1,98 @@
from dcs.vehicles import AirDefence
from dcs.unittype import VehicleType
from gen.sam.group_generator import GroupGenerator
class EwrGenerator(GroupGenerator):
@property
def unit_type(self) -> VehicleType:
raise NotImplementedError
def generate(self) -> None:
self.add_unit(self.unit_type, "EWR", self.position.x, self.position.y,
self.heading)
class BoxSpringGenerator(EwrGenerator):
"""1L13 "Box Spring" EWR."""
unit_type = AirDefence.EWR_1L13
class TallRackGenerator(EwrGenerator):
"""55G6 "Tall Rack" EWR."""
unit_type = AirDefence.EWR_55G6
class DogEarGenerator(EwrGenerator):
"""9S80M1 "Dog Ear" EWR.
This is the SA-8 search radar, but used as an early warning radar.
"""
unit_type = AirDefence.CP_9S80M1_Sborka
class RolandEwrGenerator(EwrGenerator):
"""Roland EWR.
This is the Roland search radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_Roland_EWR
class FlatFaceGenerator(EwrGenerator):
"""P-19 "Flat Face" EWR.
This is the SA-3 search radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_SR_P_19
class PatriotEwrGenerator(EwrGenerator):
"""Patriot EWR.
This is the Patriot search/track radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_Patriot_STR_AN_MPQ_53
class BigBirdGenerator(EwrGenerator):
"""64H6E "Big Bird" EWR.
This is the SA-10 track radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_SA_10_S_300PS_SR_64H6E
class SnowDriftGenerator(EwrGenerator):
"""9S18M1 "Snow Drift" EWR.
This is the SA-11 search radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_SA_11_Buk_SR_9S18M1
class StraightFlushGenerator(EwrGenerator):
"""1S91 "Straight Flush" EWR.
This is the SA-6 search/track radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_SA_6_Kub_STR_9S91
class HawkEwrGenerator(EwrGenerator):
"""Hawk EWR.
This is the Hawk search radar, but used as an early warning radar.
"""
unit_type = AirDefence.SAM_Hawk_SR_AN_MPQ_50

View File

@ -11,6 +11,20 @@ from gen.sam.aaa_flak18 import Flak18Generator
from gen.sam.aaa_ww2_ally_flak import AllyWW2FlakGenerator
from gen.sam.aaa_zu23_insurgent import ZU23InsurgentGenerator
from gen.sam.cold_war_flak import EarlyColdWarFlakGenerator, ColdWarFlakGenerator
from gen.sam.ewrs import (
BigBirdGenerator,
BoxSpringGenerator,
DogEarGenerator,
FlatFaceGenerator,
HawkEwrGenerator,
PatriotEwrGenerator,
RolandEwrGenerator,
SnowDriftGenerator,
StraightFlushGenerator,
TallRackGenerator,
)
from gen.sam.group_generator import GroupGenerator
from gen.sam.sam_avenger import AvengerGenerator
from gen.sam.sam_chaparral import ChaparralGenerator
@ -109,13 +123,34 @@ SAM_PRICES = {
AirDefence.HQ_7_Self_Propelled_LN: 35
}
EWR_MAP = {
"BoxSpringGenerator": BoxSpringGenerator,
"TallRackGenerator": TallRackGenerator,
"DogEarGenerator": DogEarGenerator,
"RolandEwrGenerator": RolandEwrGenerator,
"FlatFaceGenerator": FlatFaceGenerator,
"PatriotEwrGenerator": PatriotEwrGenerator,
"BigBirdGenerator": BigBirdGenerator,
"SnowDriftGenerator": SnowDriftGenerator,
"StraightFlushGenerator": StraightFlushGenerator,
"HawkEwrGenerator": HawkEwrGenerator,
}
def get_faction_possible_sams_generator(faction: str) -> List[Type[GroupGenerator]]:
"""
Return the list of possible SAM generator for the given faction
:param faction: Faction name to search units for
"""
return [SAM_MAP[s] for s in db.FACTIONS[faction].sams if s in SAM_MAP.keys()]
return [SAM_MAP[s] for s in db.FACTIONS[faction].sams if s in SAM_MAP]
def get_faction_possible_ewrs_generator(faction: str) -> List[Type[GroupGenerator]]:
"""
Return the list of possible SAM generator for the given faction
:param faction: Faction name to search units for
"""
return [EWR_MAP[s] for s in db.FACTIONS[faction].ewrs if s in EWR_MAP]
def generate_anti_air_group(game: Game, ground_object: TheaterGroundObject,
@ -136,6 +171,24 @@ def generate_anti_air_group(game: Game, ground_object: TheaterGroundObject,
return None
def generate_ewr_group(game: Game, ground_object: TheaterGroundObject,
faction: str) -> Optional[VehicleGroup]:
"""Generates an early warning radar group.
:param game: The Game.
:param ground_object: The ground object which will own the EWR group.
:param faction: Owner faction.
:return: The generated group, or None if one could not be generated.
"""
generators = get_faction_possible_ewrs_generator(faction)
if len(generators) > 0:
generator_class = random.choice(generators)
generator = generator_class(game, ground_object)
generator.generate()
return generator.get_generated_group()
return None
def generate_shorad_group(game: Game, ground_object: SamGroundObject,
faction_name: str) -> Optional[VehicleGroup]:
faction = db.FACTIONS[faction_name]

View File

@ -41,6 +41,7 @@ from qt_ui.widgets.map.QMapControlPoint import QMapControlPoint
from qt_ui.widgets.map.QMapGroundObject import QMapGroundObject
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from theater import ControlPoint, FrontLine
from theater.theatergroundobject import EwrGroundObject
class QLiberationMap(QGraphicsView):
@ -215,7 +216,8 @@ class QLiberationMap(QGraphicsView):
buildings = self.game.theater.find_ground_objects_by_obj_name(ground_object.obj_name)
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 14, 12, cp, ground_object, self.game, buildings))
is_aa = ground_object.category == "aa"
is_ewr = isinstance(ground_object, EwrGroundObject)
is_aa = ground_object.category == "aa" or is_ewr
should_display = ((DisplayOptions.sam_ranges and cp.captured)
or
(DisplayOptions.enemy_sam_ranges and not cp.captured))

View File

@ -38,6 +38,9 @@
"HawkGenerator",
"RapierGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -44,6 +44,9 @@
"HawkGenerator",
"ChaparralGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
"CVN_74_John_C__Stennis"
],

View File

@ -45,6 +45,9 @@
"HawkGenerator",
"ChaparralGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
"CVN_74_John_C__Stennis"
],

View File

@ -46,6 +46,9 @@
"HawkGenerator",
"ChaparralGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
"CVN_74_John_C__Stennis"
],

View File

@ -63,6 +63,9 @@
"HawkGenerator",
"PatriotGenerator"
],
"ewrs": [
"PatriotEwrGenerator"
],
"aircraft_carrier": [
"CVN_74_John_C__Stennis"
],

View File

@ -38,6 +38,9 @@
"HawkGenerator",
"AvengerGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -48,6 +48,9 @@
"SA10Generator",
"SA6Generator"
],
"ewrs": [
"BigBirdGenerator"
],
"aircraft_carrier": [
"CV_1143_5_Admiral_Kuznetsov"
],

View File

@ -45,6 +45,9 @@
"RolandGenerator",
"HawkGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -54,6 +54,9 @@
"RolandGenerator",
"HawkGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
"CVN_74_John_C__Stennis"
],

View File

@ -40,6 +40,9 @@
"HawkGenerator",
"RolandGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -46,6 +46,9 @@
"SA6Generator",
"SA3Generator"
],
"ewrs": [
"StraightFlushGenerator"
],
"aircraft_carrier": [
"CV_1143_5_Admiral_Kuznetsov"
],

View File

@ -53,6 +53,9 @@
"HawkGenerator",
"HQ7Generator"
],
"ewrs": [
"SnowDriftGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -37,6 +37,9 @@
"HawkGenerator",
"ChaparralGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -40,6 +40,9 @@
"HawkGenerator",
"ChaparralGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -43,6 +43,9 @@
"HawkGenerator",
"ChaparralGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -37,6 +37,9 @@
"HawkGenerator",
"AvengerGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -38,6 +38,9 @@
"HawkGenerator",
"AvengerGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -43,6 +43,9 @@
"HawkGenerator",
"PatriotGenerator"
],
"ewrs": [
"PatriotEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -43,6 +43,9 @@
"SA3Generator",
"SA6Generator"
],
"ewrs": [
"StraightFlushGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -34,6 +34,9 @@
"sams": [
"HawkGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -51,6 +51,9 @@
"SA3Generator",
"SA6Generator"
],
"ewrs": [
"StraightFlushGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -47,6 +47,9 @@
"SA10Generator",
"SA2Generator"
],
"ewrs": [
"BigBirdGenerator"
],
"aircraft_carrier": [
],
"carrier_names": [

View File

@ -44,6 +44,9 @@
"SA3Generator",
"SA6Generator"
],
"ewrs": [
"StraightFlushGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -49,6 +49,9 @@
"SA3Generator",
"SA6Generator"
],
"ewrs": [
"SnowDriftGenerator"
],
"aircraft_carrier": [
],
"helicopter_carrier": [

View File

@ -52,6 +52,9 @@
"SA6Generator",
"SA11Generator"
],
"ewrs": [
"SnowDriftGenerator"
],
"aircraft_carrier": [
"CV_1143_5_Admiral_Kuznetsov"
],

View File

@ -58,6 +58,9 @@
"SA6Generator",
"SA19Generator"
],
"ewrs": [
"BigBirdGenerator"
],
"aircraft_carrier": [
"CV_1143_5_Admiral_Kuznetsov"
],

View File

@ -55,6 +55,9 @@
"SA10Generator",
"SA19Generator"
],
"ewrs": [
"BigBirdGenerator"
],
"aircraft_carrier": [
"CV_1143_5_Admiral_Kuznetsov"
],

View File

@ -37,6 +37,9 @@
"sams": [
"HawkGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
"CVN_74_John_C__Stennis"
],

View File

@ -34,6 +34,9 @@
"sams": [
"HawkGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"navy_generators": [
"OliverHazardPerryGroupGenerator"
],

View File

@ -42,6 +42,9 @@
"SA3Generator",
"SA6Generator"
],
"ewrs": [
"StraightFlushGenerator"
],
"missiles": [
"ScudGenerator"
],

View File

@ -45,6 +45,9 @@
"SA3Generator",
"SA6Generator"
],
"ewrs": [
"StraightFlushGenerator"
],
"missiles": [
"ScudGenerator"
],

View File

@ -63,6 +63,9 @@
"SA10Generator",
"SA11Generator"
],
"ewrs": [
"BigBirdGenerator"
],
"missiles": [
"ScudGenerator"
],

View File

@ -41,6 +41,9 @@
"sams": [
"HawkGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"navy_generators": [
"OliverHazardPerryGroupGenerator"
],

View File

@ -36,6 +36,9 @@
"sams": [
"HawkGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"requirements": {},
"carrier_names": [
],

View File

@ -41,6 +41,9 @@
"sams": [
"HawkGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
"CVN_74_John_C__Stennis"
],

View File

@ -48,6 +48,9 @@
"SA10Generator",
"SA11Generator"
],
"ewrs": [
"BigBirdGenerator"
],
"requirements": {},
"carrier_names": [
"Admiral Kuznetov",

View File

@ -53,6 +53,9 @@
"HawkGenerator",
"PatriotGenerator"
],
"ewrs": [
"PatriotEwrGenerator"
],
"requirements": {},
"navy_generators": [
"OliverHazardPerryGroupGenerator"

View File

@ -32,6 +32,9 @@
"HawkGenerator",
"ChaparralGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"requirements": {},
"doctrine": "coldwar"
}

View File

@ -33,6 +33,9 @@
"HawkGenerator",
"ChaparralGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"navy_generators": [
"OliverHazardPerryGroupGenerator"
],

View File

@ -50,6 +50,9 @@
"sams": [
"HawkGenerator"
],
"ewrs": [
"HawkEwrGenerator"
],
"aircraft_carrier": [
"CVN_74_John_C__Stennis"
],

View File

@ -52,6 +52,9 @@
"HawkGenerator",
"PatriotGenerator"
],
"ewrs": [
"PatriotEwrGenerator"
],
"aircraft_carrier": [
"CVN_74_John_C__Stennis"
],

View File

@ -13,16 +13,6 @@
"mnemonic": "createBlueIADS",
"defaultValue": true
},
{
"nameInUI": "Long-range SAM act as EWR for RED coalition",
"mnemonic": "actAsEwrRED",
"defaultValue": true
},
{
"nameInUI": "Long-range SAM act as EWR for BLUE coalition",
"mnemonic": "actAsEwrBLUE",
"defaultValue": true
},
{
"nameInUI": "Include RED IADS in radio menu",
"mnemonic": "includeRedInRadio",

View File

@ -14,8 +14,6 @@ if dcsLiberation and SkynetIADS then
-- specific options
local createRedIADS = false
local createBlueIADS = false
local actAsEwrRED = false
local actAsEwrBLUE = false
local includeRedInRadio = false
local includeBlueInRadio = false
local debugRED = false
@ -26,8 +24,6 @@ if dcsLiberation and SkynetIADS then
if dcsLiberation.plugins.skynetiads then
createRedIADS = dcsLiberation.plugins.skynetiads.createRedIADS
createBlueIADS = dcsLiberation.plugins.skynetiads.createBlueIADS
actAsEwrRED = dcsLiberation.plugins.skynetiads.actAsEwrRED
actAsEwrBLUE = dcsLiberation.plugins.skynetiads.actAsEwrBLUE
includeRedInRadio = dcsLiberation.plugins.skynetiads.includeRedInRadio
includeBlueInRadio = dcsLiberation.plugins.skynetiads.includeBlueInRadio
debugRED = dcsLiberation.plugins.skynetiads.debugRED
@ -37,8 +33,6 @@ if dcsLiberation and SkynetIADS then
env.info(string.format("DCSLiberation|Skynet-IADS plugin - createRedIADS=%s",tostring(createRedIADS)))
env.info(string.format("DCSLiberation|Skynet-IADS plugin - createBlueIADS=%s",tostring(createBlueIADS)))
env.info(string.format("DCSLiberation|Skynet-IADS plugin - actAsEwrRED=%s",tostring(actAsEwrRED)))
env.info(string.format("DCSLiberation|Skynet-IADS plugin - actAsEwrBLUE=%s",tostring(actAsEwrBLUE)))
env.info(string.format("DCSLiberation|Skynet-IADS plugin - includeRedInRadio=%s",tostring(includeRedInRadio)))
env.info(string.format("DCSLiberation|Skynet-IADS plugin - includeBlueInRadio=%s",tostring(includeBlueInRadio)))
env.info(string.format("DCSLiberation|Skynet-IADS plugin - debugRED=%s",tostring(debugRED)))
@ -46,7 +40,7 @@ if dcsLiberation and SkynetIADS then
-- actual configuration code
local function initializeIADS(iads, coalition, actAsEwr, inRadio, debug)
local function initializeIADS(iads, coalition, inRadio, debug)
local coalitionPrefix = "BLUE"
if coalition == 1 then
@ -60,12 +54,12 @@ if dcsLiberation and SkynetIADS then
iadsDebug.samWentDark = true
iadsDebug.contacts = true
iadsDebug.radarWentLive = true
iadsDebug.noWorkingCommmandCenter = false
iadsDebug.ewRadarNoConnection = false
iadsDebug.samNoConnection = false
iadsDebug.noWorkingCommmandCenter = true
iadsDebug.ewRadarNoConnection = true
iadsDebug.samNoConnection = true
iadsDebug.jammerProbability = true
iadsDebug.addedEWRadar = false
iadsDebug.hasNoPower = false
iadsDebug.addedEWRadar = true
iadsDebug.hasNoPower = true
iadsDebug.harmDefence = true
iadsDebug.samSiteStatusEnvOutput = true
iadsDebug.earlyWarningRadarStatusEnvOutput = true
@ -77,13 +71,6 @@ if dcsLiberation and SkynetIADS then
--add SAM groups to the IADS:
iads:addSAMSitesByPrefix(coalitionPrefix .. "|SAM|")
-- specific configurations, for each SAM type
if actAsEwr then
iads:getSAMSitesByNatoName('SA-10'):setActAsEW(true)
iads:getSAMSitesByNatoName('SA-6'):setActAsEW(true)
iads:getSAMSitesByNatoName('Patriot'):setActAsEW(true)
end
-- add the AWACS
if dcsLiberation.AWACs then
for _, data in pairs(dcsLiberation.AWACs) do
@ -102,6 +89,8 @@ if dcsLiberation and SkynetIADS then
end
end
-- TODO: Add ships.
if inRadio then
--activate the radio menu to toggle IADS Status output
env.info("DCSLiberation|Skynet-IADS plugin - adding in radio menu")
@ -118,13 +107,13 @@ if dcsLiberation and SkynetIADS then
if createRedIADS then
env.info("DCSLiberation|Skynet-IADS plugin - creating red IADS")
redIADS = SkynetIADS:create("IADS")
initializeIADS(redIADS, 1, actAsEwrRED, includeRedInRadio, debugRED) -- RED
initializeIADS(redIADS, 1, includeRedInRadio, debugRED) -- RED
end
if createBlueIADS then
env.info("DCSLiberation|Skynet-IADS plugin - creating blue IADS")
blueIADS = SkynetIADS:create("IADS")
initializeIADS(blueIADS, 2, actAsEwrBLUE, includeBlueInRadio, debugBLUE) -- BLUE
initializeIADS(blueIADS, 2, includeBlueInRadio, debugBLUE) -- BLUE
end
end

View File

@ -221,10 +221,8 @@ class ControlPoint(MissionTarget):
def capture(self, game: Game, for_player: bool) -> None:
if for_player:
self.captured = True
faction_name = game.player_name
else:
self.captured = False
faction_name = game.enemy_name
self.base.set_strength_to_minimum()
@ -234,4 +232,4 @@ class ControlPoint(MissionTarget):
# Handle cyclic dependency.
from .start_generator import BaseDefenseGenerator
self.base_defenses = []
BaseDefenseGenerator(game, self, faction_name).generate()
BaseDefenseGenerator(game, self).generate()

View File

@ -24,7 +24,7 @@ from gen.fleet.ship_group_generator import (
from gen.missiles.missiles_group_generator import generate_missile_group
from gen.sam.sam_group_generator import (
generate_anti_air_group,
generate_shorad_group,
generate_ewr_group, generate_shorad_group,
)
from theater import (
ConflictTheater,
@ -34,7 +34,7 @@ from theater import (
)
from theater.conflicttheater import IMPORTANCE_HIGH, IMPORTANCE_LOW
from theater.theatergroundobject import (
SamGroundObject, BuildingGroundObject, CarrierGroundObject,
EwrGroundObject, SamGroundObject, BuildingGroundObject, CarrierGroundObject,
LhaGroundObject,
MissileSiteGroundObject, ShipGroundObject,
)
@ -269,29 +269,47 @@ class LhaGroundObjectGenerator(ControlPointGroundObjectGenerator):
class BaseDefenseGenerator:
def __init__(self, game: Game, control_point: ControlPoint,
faction_name: str) -> None:
def __init__(self, game: Game, control_point: ControlPoint) -> None:
self.game = game
self.control_point = control_point
self.faction_name = faction_name
@property
def faction_name(self) -> str:
if self.control_point.captured:
return self.game.player_name
else:
return self.game.enemy_name
@property
def faction(self) -> Faction:
return db.FACTIONS[self.faction_name]
def generate(self) -> None:
self.generate_ewr()
for i in range(random.randint(3, 6)):
self.generate_base_defense(i)
def generate_base_defense(self, index: int) -> None:
position = find_location(True, self.control_point.position,
self.game.theater, 400, 3200, [], True)
# Retry once, searching a bit further (On some big airbase, 3200 is too short (Ex : Incirlik))
# But searching farther on every base would be problematic, as some base defense units
# would end up very far away from small airfields.
# (I know it's not good for performance, but this is only done on campaign generation)
# TODO : Make the whole process less stupid with preset possible positions for each airbase
def generate_ewr(self) -> None:
position = self._find_location()
if position is None:
position = find_location(True, self.control_point.position,
self.game.theater, 3200, 4800, [], True)
logging.error("Could not find position for "
f"{self.control_point} EWR")
return
group_id = self.game.next_group_id()
g = EwrGroundObject(namegen.random_objective_name(), group_id,
position, self.control_point)
group = generate_ewr_group(self.game, g, self.faction_name)
if group is None:
return
g.groups = [group]
self.control_point.base_defenses.append(g)
def generate_base_defense(self, index: int) -> None:
position = self._find_location()
if position is None:
logging.error("Could not find position for "
f"{self.control_point} base defense")
@ -306,6 +324,20 @@ class BaseDefenseGenerator:
self.game)
self.control_point.base_defenses.append(g)
def _find_location(self) -> Optional[Point]:
position = find_location(True, self.control_point.position,
self.game.theater, 400, 3200, [], True)
# Retry once, searching a bit further (On some big airbase, 3200 is too short (Ex : Incirlik))
# But searching farther on every base would be problematic, as some base defense units
# would end up very far away from small airfields.
# (I know it's not good for performance, but this is only done on campaign generation)
# TODO : Make the whole process less stupid with preset possible positions for each airbase
if position is None:
position = find_location(True, self.control_point.position,
self.game.theater, 3200, 4800, [], True)
return position
class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
def __init__(self, game: Game, control_point: ControlPoint,
@ -317,8 +349,7 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
if not super().generate():
return False
BaseDefenseGenerator(self.game, self.control_point,
self.faction_name).generate()
BaseDefenseGenerator(self.game, self.control_point).generate()
self.generate_ground_points()
if self.faction.missiles:

View File

@ -218,6 +218,28 @@ class SamGroundObject(TheaterGroundObject):
return super().group_name
class EwrGroundObject(TheaterGroundObject):
def __init__(self, name: str, group_id: int, position: Point,
control_point: ControlPoint) -> None:
super().__init__(
name=name,
category="EWR",
group_id=group_id,
position=position,
heading=0,
control_point=control_point,
dcs_identifier="EWR",
airbase_group=True,
sea_object=False
)
@property
def group_name(self) -> str:
# Prefix the group names with the side color so Skynet can find them.
color = "BLUE" if self.control_point.captured else "RED"
return f"{color}|{super().group_name}"
class ShipGroundObject(TheaterGroundObject):
def __init__(self, name: str, group_id: int, position: Point,
control_point: ControlPoint) -> None: