mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
FARPs for heli flights WIP
This commit is contained in:
parent
f21c515d5c
commit
ca521e7e51
20
game/db.py
20
game/db.py
@ -366,7 +366,7 @@ PLANE_PAYLOAD_OVERRIDES = {
|
||||
},
|
||||
|
||||
MiG_21Bis: {
|
||||
"*": "Patrol, medium range",
|
||||
CAP: "Patrol, medium range",
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,7 +392,11 @@ HeliDict = typing.Dict[HelicopterType, int]
|
||||
ArmorDict = typing.Dict[VehicleType, int]
|
||||
ShipDict = typing.Dict[ShipType, int]
|
||||
AirDefenseDict = typing.Dict[AirDefence, int]
|
||||
StartingPosition = typing.Optional[typing.Union[ShipGroup, Airport, Point]]
|
||||
|
||||
AssignedUnitsDict = typing.Dict[typing.Type[UnitType], typing.Tuple[int, int]]
|
||||
TaskForceDict = typing.Dict[typing.Type[Task], AssignedUnitsDict]
|
||||
|
||||
StartingPosition = typing.Optional[typing.Union[ShipGroup, StaticGroup, Airport, Point]]
|
||||
|
||||
|
||||
def unit_task(unit: UnitType) -> Task:
|
||||
@ -471,6 +475,18 @@ def unitdict_restrict_count(unit_dict: UnitsDict, total_count: int) -> UnitsDict
|
||||
return {}
|
||||
|
||||
|
||||
def assigned_units_split(fd: AssignedUnitsDict) -> typing.Tuple[PlaneDict, PlaneDict]:
|
||||
return {k: v1 for k, (v1, v2) in fd.items()}, {k: v2 for k, (v1, v2) in fd.items()},
|
||||
|
||||
|
||||
def assigned_units_from(d: PlaneDict) -> AssignedUnitsDict:
|
||||
return {k: (v, 0) for k, v in d.items()}
|
||||
|
||||
|
||||
def unitdict_from(fd: AssignedUnitsDict) -> Dict:
|
||||
return {k: v1 for k, (v1, v2) in fd.items()}
|
||||
|
||||
|
||||
def _validate_db():
|
||||
# check unit by task uniquity
|
||||
total_set = set()
|
||||
|
||||
@ -1,16 +1,7 @@
|
||||
import typing
|
||||
import math
|
||||
import random
|
||||
|
||||
from dcs.task import *
|
||||
from dcs.unittype import UnitType
|
||||
|
||||
from game import db
|
||||
from game.operation.baseattack import BaseAttackOperation
|
||||
from userdata.debriefing import Debriefing
|
||||
|
||||
from .event import *
|
||||
from ..operation.operation import flight_dict_from
|
||||
from game.db import assigned_units_from
|
||||
|
||||
|
||||
class BaseAttackEvent(Event):
|
||||
@ -60,7 +51,7 @@ class BaseAttackEvent(Event):
|
||||
if not self.is_player_attacking and self.to_cp.captured:
|
||||
self.to_cp.captured = False
|
||||
|
||||
def player_defending(self, flights: ScrambledFlightsDict):
|
||||
def player_defending(self, flights: db.TaskForceDict):
|
||||
assert CAP in flights and len(flights) == 1, "Invalid scrambled flights"
|
||||
|
||||
cas = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||
@ -73,8 +64,8 @@ class BaseAttackEvent(Event):
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
op.setup(cas=flight_dict_from(cas),
|
||||
escort=flight_dict_from(escort),
|
||||
op.setup(cas=assigned_units_from(cas),
|
||||
escort=assigned_units_from(escort),
|
||||
intercept=flights[CAP],
|
||||
attack=attackers,
|
||||
defense=self.to_cp.base.armor,
|
||||
@ -82,7 +73,7 @@ class BaseAttackEvent(Event):
|
||||
|
||||
self.operation = op
|
||||
|
||||
def player_attacking(self, flights: ScrambledFlightsDict):
|
||||
def player_attacking(self, flights: db.TaskForceDict):
|
||||
assert CAP in flights and CAS in flights and PinpointStrike in flights and len(flights) == 3, "Invalid flights"
|
||||
|
||||
op = BaseAttackOperation(game=self.game,
|
||||
@ -97,7 +88,7 @@ class BaseAttackEvent(Event):
|
||||
op.setup(cas=flights[CAS],
|
||||
escort=flights[CAP],
|
||||
attack=flights[PinpointStrike],
|
||||
intercept=flight_dict_from(defenders),
|
||||
intercept=assigned_units_from(defenders),
|
||||
defense=self.to_cp.base.armor,
|
||||
aa=self.to_cp.base.assemble_aa())
|
||||
|
||||
|
||||
@ -8,15 +8,13 @@ from dcs.unittype import UnitType
|
||||
from game import *
|
||||
from theater import *
|
||||
from gen.environmentgen import EnvironmentSettings
|
||||
from game.operation.operation import flight_dict_from, dict_from_flight
|
||||
from game.db import assigned_units_from, unitdict_from
|
||||
|
||||
from userdata.debriefing import Debriefing
|
||||
from userdata import persistency
|
||||
|
||||
DIFFICULTY_LOG_BASE = 1.1
|
||||
|
||||
ScrambledFlightsDict = typing.Dict[typing.Type[Task], typing.Dict[typing.Type[UnitType], typing.Tuple[int, int]]]
|
||||
|
||||
|
||||
class Event:
|
||||
silent = False
|
||||
@ -67,10 +65,10 @@ class Event:
|
||||
def is_successfull(self, debriefing: Debriefing) -> bool:
|
||||
return self.operation.is_successfull(debriefing)
|
||||
|
||||
def player_attacking(self, flights: ScrambledFlightsDict):
|
||||
def player_attacking(self, flights: db.TaskForceDict):
|
||||
assert False
|
||||
|
||||
def player_defending(self, flights: ScrambledFlightsDict):
|
||||
def player_defending(self, flights: db.TaskForceDict):
|
||||
assert False
|
||||
|
||||
def generate(self):
|
||||
|
||||
@ -1,10 +1,3 @@
|
||||
import math
|
||||
import random
|
||||
|
||||
from dcs.task import *
|
||||
from dcs.vehicles import AirDefence
|
||||
|
||||
from game import *
|
||||
from game.event import *
|
||||
from game.operation.frontlineattack import FrontlineAttackOperation
|
||||
from userdata.debriefing import Debriefing
|
||||
@ -69,7 +62,7 @@ class FrontlineAttackEvent(Event):
|
||||
if self.to_cp.captured:
|
||||
self.to_cp.base.affect_strength(-0.1)
|
||||
|
||||
def player_attacking(self, flights: ScrambledFlightsDict):
|
||||
def player_attacking(self, flights: db.TaskForceDict):
|
||||
assert CAS in flights and PinpointStrike in flights and len(flights) == 2, "Invalid flights"
|
||||
|
||||
self.defenders = self.to_cp.base.assemble_attack()
|
||||
@ -80,7 +73,7 @@ class FrontlineAttackEvent(Event):
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
armor = dict_from_flight(flights[PinpointStrike])
|
||||
armor = unitdict_from(flights[PinpointStrike])
|
||||
op.setup(target=self.defenders,
|
||||
attackers=db.unitdict_restrict_count(armor, sum(self.defenders.values())),
|
||||
strikegroup=flights[CAS])
|
||||
|
||||
@ -1,10 +1,3 @@
|
||||
import math
|
||||
import random
|
||||
|
||||
from dcs.task import *
|
||||
from dcs.vehicles import AirDefence
|
||||
|
||||
from game import *
|
||||
from game.event import *
|
||||
from game.operation.frontlinepatrol import FrontlinePatrolOperation
|
||||
from userdata.debriefing import Debriefing
|
||||
@ -61,7 +54,7 @@ class FrontlinePatrolEvent(Event):
|
||||
def skip(self):
|
||||
pass
|
||||
|
||||
def player_attacking(self, flights: ScrambledFlightsDict):
|
||||
def player_attacking(self, flights: db.TaskForceDict):
|
||||
assert CAP in flights and PinpointStrike in flights and len(flights) == 2, "Invalid flights"
|
||||
|
||||
self.cas = self.to_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||
@ -74,8 +67,8 @@ class FrontlinePatrolEvent(Event):
|
||||
to_cp=self.to_cp)
|
||||
|
||||
defenders = self.to_cp.base.assemble_attack()
|
||||
op.setup(cas=flight_dict_from(self.cas),
|
||||
escort=flight_dict_from(self.escort),
|
||||
op.setup(cas=assigned_units_from(self.cas),
|
||||
escort=assigned_units_from(self.escort),
|
||||
interceptors=flights[CAP],
|
||||
armor_attackers=db.unitdict_restrict_count(dict_from_flight(flights[PinpointStrike]), sum(defenders.values())),
|
||||
armor_defenders=defenders)
|
||||
|
||||
@ -37,7 +37,7 @@ class InfantryTransportEvent(Event):
|
||||
else:
|
||||
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
|
||||
|
||||
def player_attacking(self, flights: ScrambledFlightsDict):
|
||||
def player_attacking(self, flights: db.TaskForceDict):
|
||||
assert Embarking in flights and len(flights) == 1, "Invalid flights"
|
||||
|
||||
op = InfantryTransportOperation(
|
||||
|
||||
@ -40,7 +40,7 @@ class InsurgentAttackEvent(Event):
|
||||
else:
|
||||
return not attackers_success
|
||||
|
||||
def player_defending(self, flights: ScrambledFlightsDict):
|
||||
def player_defending(self, flights: db.TaskForceDict):
|
||||
assert CAS in flights and len(flights) == 1, "Invalid flights"
|
||||
|
||||
suitable_unittypes = db.find_unittype(Reconnaissance, self.attacker_name)
|
||||
|
||||
@ -1,13 +1,4 @@
|
||||
import math
|
||||
import random
|
||||
|
||||
from dcs.task import *
|
||||
from dcs.vehicles import *
|
||||
|
||||
from game import db
|
||||
from game.operation.intercept import InterceptOperation
|
||||
from theater.conflicttheater import *
|
||||
from userdata.debriefing import Debriefing
|
||||
|
||||
from .event import *
|
||||
|
||||
@ -68,7 +59,7 @@ class InterceptEvent(Event):
|
||||
if self.to_cp.captured:
|
||||
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
|
||||
|
||||
def player_attacking(self, flights: ScrambledFlightsDict):
|
||||
def player_attacking(self, flights: db.TaskForceDict):
|
||||
assert CAP in flights and len(flights) == 1, "Invalid flights"
|
||||
|
||||
escort = self.to_cp.base.scramble_sweep(self._enemy_scramble_multiplier())
|
||||
@ -83,14 +74,14 @@ class InterceptEvent(Event):
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
op.setup(escort=flight_dict_from(escort),
|
||||
op.setup(escort=assigned_units_from(escort),
|
||||
transport={self.transport_unit: 1},
|
||||
airdefense={airdefense_unit: self.AIRDEFENSE_COUNT},
|
||||
interceptors=flights[CAP])
|
||||
|
||||
self.operation = op
|
||||
|
||||
def player_defending(self, flights: ScrambledFlightsDict):
|
||||
def player_defending(self, flights: db.TaskForceDict):
|
||||
assert CAP in flights and len(flights) == 1, "Invalid flights"
|
||||
|
||||
interceptors = self.from_cp.base.scramble_interceptors(self.game.settings.multiplier)
|
||||
@ -106,7 +97,7 @@ class InterceptEvent(Event):
|
||||
|
||||
op.setup(escort=flights[CAP],
|
||||
transport={self.transport_unit: 1},
|
||||
interceptors=flight_dict_from(interceptors),
|
||||
interceptors=assigned_units_from(interceptors),
|
||||
airdefense={})
|
||||
|
||||
self.operation = op
|
||||
|
||||
@ -1,13 +1,4 @@
|
||||
import typing
|
||||
import math
|
||||
import random
|
||||
|
||||
from dcs.task import *
|
||||
from dcs.vehicles import *
|
||||
|
||||
from game import db
|
||||
from game.operation.navalintercept import NavalInterceptionOperation
|
||||
from userdata.debriefing import Debriefing
|
||||
|
||||
from .event import *
|
||||
|
||||
@ -19,7 +10,7 @@ class NavalInterceptEvent(Event):
|
||||
targets = None # type: db.ShipDict
|
||||
|
||||
def _targets_count(self) -> int:
|
||||
from gen.conflictgen import IMPORTANCE_LOW, IMPORTANCE_HIGH
|
||||
from gen.conflictgen import IMPORTANCE_LOW
|
||||
factor = (self.to_cp.importance - IMPORTANCE_LOW) * 10
|
||||
return max(int(factor), 1)
|
||||
|
||||
@ -77,7 +68,7 @@ class NavalInterceptEvent(Event):
|
||||
if self.to_cp.captured:
|
||||
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
|
||||
|
||||
def player_attacking(self, flights: ScrambledFlightsDict):
|
||||
def player_attacking(self, flights: db.TaskForceDict):
|
||||
assert CAS in flights and len(flights) == 1, "Invalid flights"
|
||||
|
||||
self.targets = {
|
||||
@ -98,7 +89,7 @@ class NavalInterceptEvent(Event):
|
||||
|
||||
self.operation = op
|
||||
|
||||
def player_defending(self, flights: ScrambledFlightsDict):
|
||||
def player_defending(self, flights: db.TaskForceDict):
|
||||
assert CAP in flights and len(flights) == 1, "Invalid flights"
|
||||
|
||||
self.targets = {
|
||||
@ -114,7 +105,7 @@ class NavalInterceptEvent(Event):
|
||||
)
|
||||
|
||||
strikegroup = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||
op.setup(strikegroup=flight_dict_from(strikegroup),
|
||||
op.setup(strikegroup=assigned_units_from(strikegroup),
|
||||
interceptors=flights[CAP],
|
||||
targets=self.targets)
|
||||
|
||||
|
||||
@ -1,13 +1,4 @@
|
||||
import math
|
||||
import random
|
||||
|
||||
from dcs.task import *
|
||||
from dcs.vehicles import *
|
||||
|
||||
from game import db
|
||||
from game.operation.strike import StrikeOperation
|
||||
from theater.conflicttheater import *
|
||||
from userdata.debriefing import Debriefing
|
||||
|
||||
from .event import *
|
||||
|
||||
@ -50,7 +41,7 @@ class StrikeEvent(Event):
|
||||
super(StrikeEvent, self).commit(debriefing)
|
||||
self.to_cp.base.affect_strength(-self.SINGLE_OBJECT_STRENGTH_INFLUENCE * len(debriefing.destroyed_objects))
|
||||
|
||||
def player_attacking(self, flights: ScrambledFlightsDict):
|
||||
def player_attacking(self, flights: db.TaskForceDict):
|
||||
assert CAP in flights and CAS in flights and len(flights) == 2, "Invalid flights"
|
||||
|
||||
op = StrikeOperation(
|
||||
@ -64,6 +55,6 @@ class StrikeEvent(Event):
|
||||
interceptors = self.to_cp.base.scramble_interceptors(self.game.settings.multiplier)
|
||||
op.setup(strikegroup=flights[CAS],
|
||||
escort=flights[CAP],
|
||||
interceptors=flight_dict_from(interceptors))
|
||||
interceptors=assigned_units_from(interceptors))
|
||||
|
||||
self.operation = op
|
||||
|
||||
@ -1,21 +1,14 @@
|
||||
from game import db
|
||||
from game.db import assigned_units_split
|
||||
|
||||
from gen.conflictgen import Conflict
|
||||
from gen.armor import *
|
||||
from gen.aircraft import *
|
||||
from gen.aaa import *
|
||||
from gen.shipgen import *
|
||||
from gen.triggergen import *
|
||||
from gen.airsupportgen import *
|
||||
from gen.visualgen import *
|
||||
|
||||
from .operation import *
|
||||
|
||||
|
||||
class BaseAttackOperation(Operation):
|
||||
cas = None # type: FlightDict
|
||||
escort = None # type: FlightDict
|
||||
intercept = None # type: FlightDict
|
||||
cas = None # type: db.AssignedUnitsDict
|
||||
escort = None # type: db.AssignedUnitsDict
|
||||
intercept = None # type: db.AssignedUnitsDict
|
||||
attack = None # type: db.ArmorDict
|
||||
defense = None # type: db.ArmorDict
|
||||
aa = None # type: db.AirDefenseDict
|
||||
@ -23,10 +16,10 @@ class BaseAttackOperation(Operation):
|
||||
trigger_radius = TRIGGER_RADIUS_SMALL
|
||||
|
||||
def setup(self,
|
||||
cas: FlightDict,
|
||||
escort: FlightDict,
|
||||
attack: FlightDict,
|
||||
intercept: FlightDict,
|
||||
cas: db.AssignedUnitsDict,
|
||||
escort: db.AssignedUnitsDict,
|
||||
attack: db.AssignedUnitsDict,
|
||||
intercept: db.AssignedUnitsDict,
|
||||
defense: db.ArmorDict,
|
||||
aa: db.AirDefenseDict):
|
||||
self.cas = cas
|
||||
@ -57,10 +50,10 @@ class BaseAttackOperation(Operation):
|
||||
self.armorgen.generate(self.attack, self.defense)
|
||||
self.aagen.generate(self.aa)
|
||||
|
||||
self.airgen.generate_defense(*flight_arguments(self.intercept), at=self.defenders_starting_position)
|
||||
self.airgen.generate_defense(*assigned_units_split(self.intercept), at=self.defenders_starting_position)
|
||||
|
||||
self.airgen.generate_cas_strikegroup(*flight_arguments(self.cas), at=self.attackers_starting_position)
|
||||
self.airgen.generate_attackers_escort(*flight_arguments(self.escort), at=self.attackers_starting_position)
|
||||
self.airgen.generate_cas_strikegroup(*assigned_units_split(self.cas), at=self.attackers_starting_position)
|
||||
self.airgen.generate_attackers_escort(*assigned_units_split(self.escort), at=self.attackers_starting_position)
|
||||
|
||||
self.visualgen.generate_target_smokes(self.to_cp)
|
||||
|
||||
|
||||
@ -1,16 +1,4 @@
|
||||
from itertools import zip_longest
|
||||
|
||||
from dcs.terrain import Terrain
|
||||
|
||||
from game import db
|
||||
from gen.armor import *
|
||||
from gen.aircraft import *
|
||||
from gen.aaa import *
|
||||
from gen.shipgen import *
|
||||
from gen.triggergen import *
|
||||
from gen.airsupportgen import *
|
||||
from gen.visualgen import *
|
||||
from gen.conflictgen import Conflict
|
||||
from game.db import assigned_units_split
|
||||
|
||||
from .operation import *
|
||||
|
||||
@ -19,14 +7,14 @@ MAX_DISTANCE_BETWEEN_GROUPS = 12000
|
||||
|
||||
|
||||
class FrontlineAttackOperation(Operation):
|
||||
strikegroup = None # type: FlightDict
|
||||
strikegroup = None # type: db.AssignedUnitsDict
|
||||
attackers = None # type: db.ArmorDict
|
||||
target = None # type: db.ArmorDict
|
||||
|
||||
def setup(self,
|
||||
target: db.ArmorDict,
|
||||
attackers: db.ArmorDict,
|
||||
strikegroup: FlightDict):
|
||||
strikegroup: db.AssignedUnitsDict):
|
||||
self.strikegroup = strikegroup
|
||||
self.target = target
|
||||
self.attackers = attackers
|
||||
@ -50,7 +38,13 @@ class FrontlineAttackOperation(Operation):
|
||||
|
||||
def generate(self):
|
||||
self.armorgen.generate_vec(self.attackers, self.target)
|
||||
self.airgen.generate_cas_strikegroup(*flight_arguments(self.strikegroup), at=self.attackers_starting_position)
|
||||
|
||||
planes_flights = {k: v for k, v in self.strikegroup.items() if k in plane_map}
|
||||
self.airgen.generate_cas_strikegroup(*assigned_units_split(planes_flights), at=self.attackers_starting_position)
|
||||
|
||||
heli_flights = {k: v for k, v in self.strikegroup.items() if k in helicopters.helicopter_map}
|
||||
if heli_flights:
|
||||
self.airgen.generate_cas_strikegroup(*assigned_units_split(heli_flights), at=self.groundobjectgen.generate_farp())
|
||||
|
||||
self.briefinggen.title = "Frontline CAS"
|
||||
self.briefinggen.description = "Provide CAS for the ground forces attacking enemy lines. Operation will be considered successful if total number of enemy units will be lower than your own by a factor of 1.5 (i.e. with 12 units from both sides, enemy forces need to be reduced to at least 8), meaning that you (and, probably, your wingmans) should concentrate on destroying the enemy units. Target base strength will be lowered as a result. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu."
|
||||
|
||||
@ -1,16 +1,4 @@
|
||||
from itertools import zip_longest
|
||||
|
||||
from dcs.terrain import Terrain
|
||||
|
||||
from game import db
|
||||
from gen.armor import *
|
||||
from gen.aircraft import *
|
||||
from gen.aaa import *
|
||||
from gen.shipgen import *
|
||||
from gen.triggergen import *
|
||||
from gen.airsupportgen import *
|
||||
from gen.visualgen import *
|
||||
from gen.conflictgen import Conflict
|
||||
from game.db import assigned_units_split
|
||||
|
||||
from .operation import *
|
||||
|
||||
@ -19,17 +7,17 @@ MAX_DISTANCE_BETWEEN_GROUPS = 12000
|
||||
|
||||
|
||||
class FrontlinePatrolOperation(Operation):
|
||||
cas = None # type: FlightDict
|
||||
escort = None # type: FlightDict
|
||||
interceptors = None # type: FlightDict
|
||||
cas = None # type: db.AssignedUnitsDict
|
||||
escort = None # type: db.AssignedUnitsDict
|
||||
interceptors = None # type: db.AssignedUnitsDict
|
||||
|
||||
armor_attackers = None # type: db.ArmorDict
|
||||
armor_defenders = None # type: db.ArmorDict
|
||||
|
||||
def setup(self,
|
||||
cas: FlightDict,
|
||||
escort: FlightDict,
|
||||
interceptors: FlightDict,
|
||||
cas: db.AssignedUnitsDict,
|
||||
escort: db.AssignedUnitsDict,
|
||||
interceptors: db.AssignedUnitsDict,
|
||||
armor_attackers: db.ArmorDict,
|
||||
armor_defenders: db.ArmorDict):
|
||||
self.cas = cas
|
||||
@ -55,9 +43,9 @@ class FrontlinePatrolOperation(Operation):
|
||||
conflict=conflict)
|
||||
|
||||
def generate(self):
|
||||
self.airgen.generate_defenders_cas(*flight_arguments(self.cas), at=self.defenders_starting_position)
|
||||
self.airgen.generate_defenders_escort(*flight_arguments(self.escort), at=self.defenders_starting_position)
|
||||
self.airgen.generate_migcap(*flight_arguments(self.interceptors), at=self.attackers_starting_position)
|
||||
self.airgen.generate_defenders_cas(*assigned_units_split(self.cas), at=self.defenders_starting_position)
|
||||
self.airgen.generate_defenders_escort(*assigned_units_split(self.escort), at=self.defenders_starting_position)
|
||||
self.airgen.generate_migcap(*assigned_units_split(self.interceptors), at=self.attackers_starting_position)
|
||||
|
||||
self.armorgen.generate_vec(self.armor_attackers, self.armor_defenders)
|
||||
|
||||
|
||||
@ -1,23 +1,13 @@
|
||||
from dcs.terrain import Terrain
|
||||
|
||||
from game import db
|
||||
from gen.armor import *
|
||||
from gen.aircraft import *
|
||||
from gen.aaa import *
|
||||
from gen.shipgen import *
|
||||
from gen.triggergen import *
|
||||
from gen.airsupportgen import *
|
||||
from gen.visualgen import *
|
||||
from gen.conflictgen import Conflict
|
||||
from game.db import assigned_units_split
|
||||
|
||||
from .operation import *
|
||||
|
||||
|
||||
class InfantryTransportOperation(Operation):
|
||||
transport = None # type: FlightDict
|
||||
transport = None # type: db.AssignedUnitsDict
|
||||
aa = None # type: db.AirDefenseDict
|
||||
|
||||
def setup(self, transport: FlightDict, aa: db.AirDefenseDict):
|
||||
def setup(self, transport: db.AssignedUnitsDict, aa: db.AirDefenseDict):
|
||||
self.transport = transport
|
||||
self.aa = aa
|
||||
|
||||
@ -36,7 +26,7 @@ class InfantryTransportOperation(Operation):
|
||||
conflict=conflict)
|
||||
|
||||
def generate(self):
|
||||
self.airgen.generate_passenger_transport(*flight_arguments(self.transport), at=self.attackers_starting_position)
|
||||
self.airgen.generate_passenger_transport(*assigned_units_split(self.transport), at=self.attackers_starting_position)
|
||||
|
||||
self.armorgen.generate_passengers(count=6)
|
||||
self.aagen.generate_at_defenders_location(self.aa)
|
||||
|
||||
@ -1,25 +1,15 @@
|
||||
from dcs.terrain import Terrain
|
||||
|
||||
from game import db
|
||||
from gen.armor import *
|
||||
from gen.aircraft import *
|
||||
from gen.aaa import *
|
||||
from gen.shipgen import *
|
||||
from gen.triggergen import *
|
||||
from gen.airsupportgen import *
|
||||
from gen.visualgen import *
|
||||
from gen.conflictgen import Conflict
|
||||
from game.db import assigned_units_split
|
||||
|
||||
from .operation import *
|
||||
|
||||
|
||||
class InsurgentAttackOperation(Operation):
|
||||
strikegroup = None # type: FlightDict
|
||||
strikegroup = None # type: db.AssignedUnitsDict
|
||||
target = None # type: db.ArmorDict
|
||||
|
||||
def setup(self,
|
||||
target: db.ArmorDict,
|
||||
strikegroup: FlightDict):
|
||||
strikegroup: db.AssignedUnitsDict):
|
||||
self.strikegroup = strikegroup
|
||||
self.target = target
|
||||
|
||||
@ -38,7 +28,7 @@ class InsurgentAttackOperation(Operation):
|
||||
conflict=conflict)
|
||||
|
||||
def generate(self):
|
||||
self.airgen.generate_defense(*flight_arguments(self.strikegroup), at=self.defenders_starting_position)
|
||||
self.airgen.generate_defense(*assigned_units_split(self.strikegroup), at=self.defenders_starting_position)
|
||||
self.armorgen.generate(self.target, {})
|
||||
|
||||
self.briefinggen.title = "Destroy insurgents"
|
||||
|
||||
@ -1,22 +1,21 @@
|
||||
from dcs.terrain import Terrain
|
||||
from game.db import assigned_units_split
|
||||
|
||||
from gen import *
|
||||
from .operation import *
|
||||
|
||||
|
||||
class InterceptOperation(Operation):
|
||||
escort = None # type: FlightDict
|
||||
escort = None # type: db.AssignedUnitsDict
|
||||
transport = None # type: db.PlaneDict
|
||||
interceptors = None # type: FlightDict
|
||||
interceptors = None # type: db.AssignedUnitsDict
|
||||
airdefense = None # type: db.AirDefenseDict
|
||||
|
||||
trigger_radius = TRIGGER_RADIUS_LARGE
|
||||
|
||||
def setup(self,
|
||||
escort: FlightDict,
|
||||
escort: db.AssignedUnitsDict,
|
||||
transport: db.PlaneDict,
|
||||
airdefense: db.AirDefenseDict,
|
||||
interceptors: FlightDict):
|
||||
interceptors: db.AssignedUnitsDict):
|
||||
self.escort = escort
|
||||
self.transport = transport
|
||||
self.airdefense = airdefense
|
||||
@ -52,9 +51,9 @@ class InterceptOperation(Operation):
|
||||
self.attackers_starting_position = ship
|
||||
|
||||
self.airgen.generate_transport(self.transport, self.to_cp.at)
|
||||
self.airgen.generate_defenders_escort(*flight_arguments(self.escort), at=self.defenders_starting_position)
|
||||
self.airgen.generate_defenders_escort(*assigned_units_split(self.escort), at=self.defenders_starting_position)
|
||||
|
||||
self.airgen.generate_interception(*flight_arguments(self.interceptors), at=self.attackers_starting_position)
|
||||
self.airgen.generate_interception(*assigned_units_split(self.interceptors), at=self.attackers_starting_position)
|
||||
|
||||
self.briefinggen.title = "Air Intercept"
|
||||
self.briefinggen.description = "Intercept enemy supply transport aircraft. Escort will also be present if there are available planes on the base. Operation will be considered successful if most of the targets are destroyed, lowering targets strength as a result"
|
||||
|
||||
@ -1,18 +1,17 @@
|
||||
from dcs.terrain import Terrain
|
||||
from game.db import assigned_units_split
|
||||
|
||||
from gen import *
|
||||
from .operation import *
|
||||
|
||||
|
||||
class NavalInterceptionOperation(Operation):
|
||||
strikegroup = None # type: FlightDict
|
||||
interceptors = None # type: FlightDict
|
||||
strikegroup = None # type: db.AssignedUnitsDict
|
||||
interceptors = None # type: db.AssignedUnitsDict
|
||||
targets = None # type: db.ShipDict
|
||||
trigger_radius = TRIGGER_RADIUS_LARGE
|
||||
|
||||
def setup(self,
|
||||
strikegroup: FlightDict,
|
||||
interceptors: FlightDict,
|
||||
strikegroup: db.AssignedUnitsDict,
|
||||
interceptors: db.AssignedUnitsDict,
|
||||
targets: db.ShipDict):
|
||||
self.strikegroup = strikegroup
|
||||
self.interceptors = interceptors
|
||||
@ -37,14 +36,14 @@ class NavalInterceptionOperation(Operation):
|
||||
target_groups = self.shipgen.generate_cargo(units=self.targets)
|
||||
|
||||
self.airgen.generate_ship_strikegroup(
|
||||
*flight_arguments(self.strikegroup),
|
||||
*assigned_units_split(self.strikegroup),
|
||||
target_groups=target_groups,
|
||||
at=self.attackers_starting_position
|
||||
)
|
||||
|
||||
if self.interceptors:
|
||||
self.airgen.generate_defense(
|
||||
*flight_arguments(self.interceptors),
|
||||
*assigned_units_split(self.interceptors),
|
||||
at=self.defenders_starting_position
|
||||
)
|
||||
|
||||
|
||||
@ -1,31 +1,14 @@
|
||||
import typing
|
||||
|
||||
from dcs.lua.parse import loads
|
||||
from dcs.unittype import UnitType
|
||||
|
||||
from userdata.debriefing import *
|
||||
|
||||
from theater import *
|
||||
from gen import *
|
||||
|
||||
FlightDict = typing.Dict[typing.Type[UnitType], typing.Tuple[int, int]]
|
||||
|
||||
|
||||
def flight_arguments(fd: FlightDict) -> typing.Tuple[db.PlaneDict, db.PlaneDict]:
|
||||
return {k: v1 for k, (v1, v2) in fd.items()}, {k: v2 for k, (v1, v2) in fd.items()},
|
||||
|
||||
|
||||
def flight_dict_from(d: db.PlaneDict) -> FlightDict:
|
||||
return {k: (v, 0) for k, v in d.items()}
|
||||
|
||||
|
||||
def dict_from_flight(fd: FlightDict) -> db.Dict:
|
||||
return {k: v1 for k, (v1, v2) in fd.items()}
|
||||
|
||||
|
||||
class Operation:
|
||||
attackers_starting_position = None # type: db.StartingPosition
|
||||
defenders_starting_position = None # type: db.StartingPosition
|
||||
|
||||
mission = None # type: dcs.Mission
|
||||
conflict = None # type: Conflict
|
||||
armorgen = None # type: ArmorConflictGenerator
|
||||
|
||||
@ -1,27 +1,17 @@
|
||||
from dcs.terrain import Terrain
|
||||
|
||||
from game import db
|
||||
from gen.armor import *
|
||||
from gen.aircraft import *
|
||||
from gen.aaa import *
|
||||
from gen.shipgen import *
|
||||
from gen.triggergen import *
|
||||
from gen.airsupportgen import *
|
||||
from gen.visualgen import *
|
||||
from gen.conflictgen import Conflict
|
||||
from game.db import assigned_units_split
|
||||
|
||||
from .operation import *
|
||||
|
||||
|
||||
class StrikeOperation(Operation):
|
||||
strikegroup = None # type: FlightDict
|
||||
escort = None # type: FlightDict
|
||||
interceptors = None # type: FlightDict
|
||||
strikegroup = None # type: db.AssignedUnitsDict
|
||||
escort = None # type: db.AssignedUnitsDict
|
||||
interceptors = None # type: db.AssignedUnitsDict
|
||||
|
||||
def setup(self,
|
||||
strikegroup: FlightDict,
|
||||
escort: FlightDict,
|
||||
interceptors: FlightDict):
|
||||
strikegroup: db.AssignedUnitsDict,
|
||||
escort: db.AssignedUnitsDict,
|
||||
interceptors: db.AssignedUnitsDict):
|
||||
self.strikegroup = strikegroup
|
||||
self.escort = escort
|
||||
self.interceptors = interceptors
|
||||
@ -61,13 +51,13 @@ class StrikeOperation(Operation):
|
||||
|
||||
targets.sort(key=lambda x: self.from_cp.position.distance_to_point(x[1]))
|
||||
|
||||
self.airgen.generate_ground_attack_strikegroup(*flight_arguments(self.strikegroup),
|
||||
self.airgen.generate_ground_attack_strikegroup(*assigned_units_split(self.strikegroup),
|
||||
targets=targets,
|
||||
at=self.attackers_starting_position)
|
||||
|
||||
self.airgen.generate_attackers_escort(*flight_arguments(self.escort), at=self.attackers_starting_position)
|
||||
self.airgen.generate_attackers_escort(*assigned_units_split(self.escort), at=self.attackers_starting_position)
|
||||
|
||||
self.airgen.generate_barcap(*flight_arguments(self.interceptors), at=self.defenders_starting_position)
|
||||
self.airgen.generate_barcap(*assigned_units_split(self.interceptors), at=self.defenders_starting_position)
|
||||
|
||||
self.briefinggen.title = "Strike"
|
||||
self.briefinggen.description = "Destroy infrastructure assets and military supplies in the region. Each building destroyed will lower targets strength."
|
||||
|
||||
@ -42,7 +42,7 @@ GROUP_VERTICAL_OFFSET = 300
|
||||
|
||||
|
||||
class AircraftConflictGenerator:
|
||||
escort_targets = [] # type: typing.List[typing.Tuple[PlaneGroup, int]]
|
||||
escort_targets = [] # type: typing.List[typing.Tuple[FlyingGroup, int]]
|
||||
vertical_offset = None # type: int
|
||||
|
||||
def __init__(self, mission: Mission, conflict: Conflict, settings: Settings):
|
||||
@ -77,7 +77,7 @@ class AircraftConflictGenerator:
|
||||
count -= group_size
|
||||
client_count -= client_size
|
||||
|
||||
def _setup_group(self, group: FlyingGroup, for_task: Task, client_count: int):
|
||||
def _setup_group(self, group: FlyingGroup, for_task: typing.Type[Task], client_count: int):
|
||||
did_load_loadout = False
|
||||
unit_type = group.units[0].unit_type
|
||||
if unit_type in db.PLANE_PAYLOAD_OVERRIDES:
|
||||
|
||||
@ -142,6 +142,9 @@ class Conflict:
|
||||
y = lerp * dy + self.tail.y
|
||||
return Point(x, y)
|
||||
|
||||
def find_ground_position(self, at: Point, heading: int, max_distance: int = 40000) -> typing.Optional[Point]:
|
||||
return Conflict._find_ground_position(at, max_distance, heading, self.theater)
|
||||
|
||||
@classmethod
|
||||
def has_frontline_between(cls, from_cp: ControlPoint, to_cp: ControlPoint) -> bool:
|
||||
return from_cp.has_frontline and to_cp.has_frontline
|
||||
@ -190,7 +193,7 @@ class Conflict:
|
||||
return pos
|
||||
|
||||
@classmethod
|
||||
def _find_ground_position(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> Point:
|
||||
def _find_ground_position(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> typing.Optional[Point]:
|
||||
pos = initial
|
||||
for _ in range(0, int(max_distance), 500):
|
||||
if theater.is_on_land(pos):
|
||||
|
||||
@ -7,6 +7,8 @@ from .naming import *
|
||||
from dcs.mission import *
|
||||
from dcs.statics import *
|
||||
|
||||
FARP_FRONTLINE_DISTANCE = 10000
|
||||
|
||||
|
||||
CATEGORY_MAPPING = {
|
||||
"power": [Fortification.Workshop_A],
|
||||
@ -25,6 +27,17 @@ class GroundObjectsGenerator:
|
||||
self.conflict = conflict
|
||||
self.game = game
|
||||
|
||||
def generate_farp(self) -> StaticGroup:
|
||||
assert self.conflict.is_vector, "FARP could be generated only on frontline conflicts!"
|
||||
|
||||
position = self.conflict.find_ground_position(self.conflict.center.point_from_heading(self.conflict.opposite_heading, FARP_FRONTLINE_DISTANCE))
|
||||
return self.m.static_group(
|
||||
country=self.m.country(self.game.player),
|
||||
name="",
|
||||
_type=Fortification.FARP_Command_Post,
|
||||
position=position
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
side = self.m.country(self.game.enemy)
|
||||
|
||||
|
||||
@ -140,7 +140,7 @@ class EventMenu(Menu):
|
||||
else:
|
||||
self.event.is_awacs_enabled = False
|
||||
|
||||
flights = {k: {} for k in self.event.tasks} # type: ScrambledFlightsDict
|
||||
flights = {k: {} for k in self.event.tasks} # type: db.TaskForceDict
|
||||
units_scramble_counts = {} # type: typing.Dict[typing.Type[UnitType], int]
|
||||
tasks_scramble_counts = {} # type: typing.Dict[typing.Type[Task], int]
|
||||
tasks_clients_counts = {} # type: typing.Dict[typing.Type[Task], int]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user