mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Merge branch 'master' of https://github.com/shdwp/dcs_pmcliberation
This commit is contained in:
87
game/db.py
Normal file
87
game/db.py
Normal file
@@ -0,0 +1,87 @@
|
||||
import typing
|
||||
|
||||
from dcs.vehicles import *
|
||||
from dcs.unitgroup import *
|
||||
from dcs.planes import *
|
||||
from dcs.task import *
|
||||
from dcs.unittype import *
|
||||
|
||||
PRICES = {
|
||||
# planes
|
||||
|
||||
Su_25T: 11,
|
||||
Su_25: 11,
|
||||
A_10A: 18,
|
||||
A_10C: 20,
|
||||
|
||||
F_A_18C: 18,
|
||||
AV8BNA: 15,
|
||||
|
||||
Su_27: 30,
|
||||
Su_33: 33,
|
||||
F_15C: 30,
|
||||
M_2000C: 11,
|
||||
|
||||
MiG_15bis: 6,
|
||||
MiG_21Bis: 13,
|
||||
MiG_29A: 23,
|
||||
|
||||
IL_76MD: 13,
|
||||
S_3B_Tanker: 13,
|
||||
|
||||
# armor
|
||||
|
||||
Armor.MBT_T_55: 4,
|
||||
Armor.MBT_T_80U: 8,
|
||||
Armor.MBT_T_90: 10,
|
||||
|
||||
Armor.MBT_M60A3_Patton: 6,
|
||||
Armor.MBT_M1A2_Abrams: 9,
|
||||
|
||||
Armor.ATGM_M1134_Stryker: 6,
|
||||
Armor.APC_BTR_80: 6,
|
||||
|
||||
AirDefence.AAA_ZU_23_on_Ural_375: 4,
|
||||
}
|
||||
|
||||
UNIT_BY_TASK = {
|
||||
FighterSweep: [Su_27, Su_33, Su_25, F_15C, MiG_15bis, MiG_21Bis, MiG_29A, F_A_18C, AV8BNA],
|
||||
CAS: [Su_25T, A_10A, A_10C, ],
|
||||
CAP: [Armor.MBT_T_90, Armor.MBT_T_80U, Armor.MBT_T_55, Armor.MBT_M1A2_Abrams, Armor.MBT_M60A3_Patton, Armor.ATGM_M1134_Stryker, Armor.APC_BTR_80, ],
|
||||
AirDefence: [AirDefence.AAA_ZU_23_on_Ural_375, ],
|
||||
Transport: [IL_76MD, S_3B_Tanker, ],
|
||||
}
|
||||
|
||||
UNIT_BY_COUNTRY = {
|
||||
"Russia": [Su_25T, Su_27, Su_33, Su_25, MiG_15bis, MiG_21Bis, MiG_29A, AirDefence.AAA_ZU_23_on_Ural_375, Armor.APC_BTR_80, Armor.MBT_T_90, Armor.MBT_T_80U, Armor.MBT_T_55, IL_76MD, ],
|
||||
"USA": [F_15C, A_10C, F_A_18C, AV8BNA, Armor.MBT_M1A2_Abrams, Armor.MBT_M60A3_Patton, Armor.ATGM_M1134_Stryker, S_3B_Tanker],
|
||||
}
|
||||
|
||||
UnitsDict = typing.Dict[UnitType, int]
|
||||
PlaneDict = typing.Dict[FlyingType, int]
|
||||
ArmorDict = typing.Dict[VehicleType, int]
|
||||
AirDefenseDict = typing.Dict[AirDefence, int]
|
||||
StartingPosition = typing.Optional[typing.Union[ShipGroup, Airport, Point]]
|
||||
|
||||
|
||||
def unit_task(unit: UnitType) -> Task:
|
||||
for task, units in UNIT_BY_TASK.items():
|
||||
if unit in units:
|
||||
return task
|
||||
|
||||
assert False
|
||||
|
||||
|
||||
def find_unittype(for_task: Task, country_name: str) -> typing.List[UnitType]:
|
||||
return [x for x in UNIT_BY_TASK[for_task] if x in UNIT_BY_COUNTRY[country_name]]
|
||||
|
||||
|
||||
def unit_type_name(unit_type) -> str:
|
||||
return unit_type.id and unit_type.id or unit_type.name
|
||||
|
||||
|
||||
def task_name(task) -> str:
|
||||
if task == AirDefence:
|
||||
return "AirDefence"
|
||||
else:
|
||||
return task.name
|
||||
175
game/event.py
175
game/event.py
@@ -1,11 +1,3 @@
|
||||
import typing
|
||||
import random
|
||||
import math
|
||||
|
||||
import dcs
|
||||
|
||||
from theater.controlpoint import *
|
||||
from userdata.debriefing_parser import *
|
||||
from game.operation import *
|
||||
|
||||
DIFFICULTY_LOG_BASE = 1.5
|
||||
@@ -18,12 +10,12 @@ class Event:
|
||||
difficulty = 1 # type: int
|
||||
BONUS_BASE = 0
|
||||
|
||||
def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint):
|
||||
self.mission = dcs.mission.Mission()
|
||||
self.attacker = self.mission.country(attacker_name)
|
||||
self.defender = self.mission.country(defender_name)
|
||||
def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||
self.attacker_name = attacker_name
|
||||
self.defender_name = defender_name
|
||||
self.to_cp = to_cp
|
||||
self.from_cp = from_cp
|
||||
self.theater = theater
|
||||
|
||||
def bonus(self) -> int:
|
||||
return math.ceil(math.log(self.difficulty, DIFFICULTY_LOG_BASE) * self.BONUS_BASE)
|
||||
@@ -31,10 +23,19 @@ class Event:
|
||||
def is_successfull(self, debriefing: Debriefing) -> bool:
|
||||
return self.operation.is_successfull(debriefing)
|
||||
|
||||
def generate(self):
|
||||
self.operation.prepare(is_quick=False)
|
||||
self.operation.generate()
|
||||
self.operation.mission.save("build/nextturn.miz")
|
||||
|
||||
self.operation.prepare(is_quick=True)
|
||||
self.operation.generate()
|
||||
self.operation.mission.save('build/nextturn_quick.miz')
|
||||
|
||||
def commit(self, debriefing: Debriefing):
|
||||
for country, losses in debriefing.destroyed_units.items():
|
||||
cp = None # type: ControlPoint
|
||||
if country == self.attacker.name:
|
||||
if country == self.attacker_name:
|
||||
cp = self.from_cp
|
||||
else:
|
||||
cp = self.to_cp
|
||||
@@ -84,27 +85,29 @@ class GroundInterceptEvent(Event):
|
||||
pass
|
||||
|
||||
def player_attacking(self, position: Point, strikegroup: db.PlaneDict, clients: db.PlaneDict):
|
||||
suitable_unittypes = db.find_unittype(CAP, self.defender.name)
|
||||
suitable_unittypes = db.find_unittype(CAP, self.defender_name)
|
||||
random.shuffle(suitable_unittypes)
|
||||
unittypes = suitable_unittypes[:self.TARGET_VARIETY]
|
||||
typecount = max(math.floor(self.difficulty * self.TARGET_AMOUNT_FACTOR), 1)
|
||||
|
||||
self.targets = {unittype: typecount for unittype in unittypes}
|
||||
self.operation = GroundInterceptOperation(mission=self.mission,
|
||||
attacker=self.attacker,
|
||||
defender=self.defender,
|
||||
attacker_clients=clients,
|
||||
defender_clients={},
|
||||
from_cp=self.from_cp,
|
||||
position=position,
|
||||
target=self.targets,
|
||||
strikegroup=strikegroup)
|
||||
|
||||
op = GroundInterceptOperation(attacker_name=self.attacker_name,
|
||||
defender_name=self.defender_name,
|
||||
attacker_clients=clients,
|
||||
defender_clients={},
|
||||
from_cp=self.from_cp)
|
||||
op.setup(position=position,
|
||||
target=self.targets,
|
||||
strikegroup=strikegroup)
|
||||
|
||||
self.operation = op
|
||||
|
||||
|
||||
class InterceptEvent(Event):
|
||||
ESCORT_AMOUNT_FACTOR = 2
|
||||
BONUS_BASE = 5
|
||||
STRENGTH_INFLUENCE = 0.25
|
||||
GLOBAL_STRENGTH_INFLUENCE = 0.05
|
||||
AIRDEFENSE_COUNT = 3
|
||||
|
||||
transport_unit = None # type: FlyingType
|
||||
@@ -123,7 +126,11 @@ class InterceptEvent(Event):
|
||||
super(InterceptEvent, self).commit(debriefing)
|
||||
|
||||
if self.is_successfull(debriefing):
|
||||
self.to_cp.base.affect_strength(self.STRENGTH_INFLUENCE * float(self.from_cp.captured and -1 or 1))
|
||||
if self.from_cp.is_global:
|
||||
for cp in self.theater.enemy_points():
|
||||
cp.base.affect_strength(-self.GLOBAL_STRENGTH_INFLUENCE)
|
||||
else:
|
||||
self.to_cp.base.affect_strength(self.STRENGTH_INFLUENCE * float(self.from_cp.captured and -1 or 1))
|
||||
else:
|
||||
self.to_cp.base.affect_strength(self.STRENGTH_INFLUENCE * float(self.from_cp.captured and 1 or -1))
|
||||
|
||||
@@ -133,39 +140,43 @@ class InterceptEvent(Event):
|
||||
|
||||
def player_attacking(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
|
||||
escort = self.to_cp.base.scramble_sweep(self.to_cp)
|
||||
self.transport_unit = random.choice(db.find_unittype(Transport, self.defender.name))
|
||||
self.transport_unit = random.choice(db.find_unittype(Transport, self.defender_name))
|
||||
assert self.transport_unit is not None
|
||||
|
||||
airdefense_unit = db.find_unittype(AirDefence, self.defender.name)[0]
|
||||
airdefense_unit = db.find_unittype(AirDefence, self.defender_name)[0]
|
||||
|
||||
self.operation = InterceptOperation(mission=self.mission,
|
||||
attacker=self.attacker,
|
||||
defender=self.defender,
|
||||
attacker_clients=clients,
|
||||
defender_clients={},
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp,
|
||||
escort=escort,
|
||||
transport={self.transport_unit: 1},
|
||||
airdefense={airdefense_unit: self.AIRDEFENSE_COUNT},
|
||||
interceptors=interceptors)
|
||||
op = InterceptOperation(attacker_name=self.attacker_name,
|
||||
defender_name=self.defender_name,
|
||||
attacker_clients=clients,
|
||||
defender_clients={},
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
op.setup(escort=escort,
|
||||
transport={self.transport_unit: 1},
|
||||
airdefense={airdefense_unit: self.AIRDEFENSE_COUNT},
|
||||
interceptors=interceptors)
|
||||
|
||||
self.operation = op
|
||||
|
||||
def player_defending(self, escort: db.PlaneDict, clients: db.PlaneDict):
|
||||
interceptors = self.from_cp.base.scramble_interceptors_count(self.difficulty * self.ESCORT_AMOUNT_FACTOR)
|
||||
self.transport_unit = random.choice(db.find_unittype(Transport, self.defender.name))
|
||||
self.transport_unit = random.choice(db.find_unittype(Transport, self.defender_name))
|
||||
assert self.transport_unit is not None
|
||||
|
||||
self.operation = InterceptOperation(mission=self.mission,
|
||||
attacker=self.attacker,
|
||||
defender=self.defender,
|
||||
attacker_clients={},
|
||||
defender_clients=clients,
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp,
|
||||
escort=escort,
|
||||
transport={self.transport_unit: 1},
|
||||
interceptors=interceptors,
|
||||
airdefense={})
|
||||
op = InterceptOperation(attacker_name=self.attacker_name,
|
||||
defender_name=self.defender_name,
|
||||
attacker_clients={},
|
||||
defender_clients=clients,
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
op.setup(escort=escort,
|
||||
transport={self.transport_unit: 1},
|
||||
interceptors=interceptors,
|
||||
airdefense={})
|
||||
|
||||
self.operation = op
|
||||
|
||||
|
||||
class CaptureEvent(Event):
|
||||
@@ -188,6 +199,9 @@ class CaptureEvent(Event):
|
||||
if self.is_successfull(debriefing):
|
||||
if self.from_cp.captured:
|
||||
self.to_cp.captured = True
|
||||
self.to_cp.base.filter_units(db.UNIT_BY_COUNTRY[self.attacker_name])
|
||||
|
||||
self.to_cp.base.affect_strength(+self.STRENGTH_RECOVERY)
|
||||
else:
|
||||
if not self.from_cp.captured:
|
||||
self.to_cp.captured = False
|
||||
@@ -202,47 +216,52 @@ class CaptureEvent(Event):
|
||||
escort = self.from_cp.base.scramble_sweep(self.to_cp)
|
||||
attackers = self.from_cp.base.assemble_cap(self.to_cp)
|
||||
|
||||
self.operation = CaptureOperation(mission=self.mission,
|
||||
attacker=self.attacker,
|
||||
defender=self.defender,
|
||||
attacker_clients={},
|
||||
defender_clients=clients,
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp,
|
||||
cas=cas,
|
||||
escort=escort,
|
||||
attack=attackers,
|
||||
intercept=interceptors,
|
||||
defense=self.to_cp.base.armor,
|
||||
aa=self.to_cp.base.aa)
|
||||
op = CaptureOperation(attacker_name=self.attacker_name,
|
||||
defender_name=self.defender_name,
|
||||
attacker_clients={},
|
||||
defender_clients=clients,
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
op.setup(cas=cas,
|
||||
escort=escort,
|
||||
attack=attackers,
|
||||
intercept=interceptors,
|
||||
defense=self.to_cp.base.armor,
|
||||
aa=self.to_cp.base.aa)
|
||||
|
||||
self.operation = op
|
||||
|
||||
def player_attacking(self, cas: db.PlaneDict, escort: db.PlaneDict, armor: db.ArmorDict, clients: db.PlaneDict):
|
||||
interceptors = self.to_cp.base.scramble_sweep(for_target=self.to_cp)
|
||||
|
||||
self.operation = CaptureOperation(mission=self.mission,
|
||||
attacker=self.attacker,
|
||||
defender=self.defender,
|
||||
attacker_clients=clients,
|
||||
defender_clients={},
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp,
|
||||
cas=cas,
|
||||
escort=escort,
|
||||
attack=armor,
|
||||
intercept=interceptors,
|
||||
defense=self.to_cp.base.armor,
|
||||
aa=self.to_cp.base.aa)
|
||||
op = CaptureOperation(attacker_name=self.attacker_name,
|
||||
defender_name=self.defender_name,
|
||||
attacker_clients=clients,
|
||||
defender_clients={},
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
op.setup(cas=cas,
|
||||
escort=escort,
|
||||
attack=armor,
|
||||
intercept=interceptors,
|
||||
defense=self.to_cp.base.armor,
|
||||
aa=self.to_cp.base.aa)
|
||||
|
||||
self.operation = op
|
||||
|
||||
|
||||
class UnitsDeliveryEvent(Event):
|
||||
informational = True
|
||||
units = None # type: typing.Dict[UnitType, int]
|
||||
|
||||
def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint):
|
||||
def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||
super(UnitsDeliveryEvent, self).__init__(attacker_name=attacker_name,
|
||||
defender_name=defender_name,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp)
|
||||
to_cp=to_cp,
|
||||
theater=theater)
|
||||
|
||||
self.units = {}
|
||||
|
||||
|
||||
69
game/game.py
69
game/game.py
@@ -1,9 +1,3 @@
|
||||
import typing
|
||||
import random
|
||||
|
||||
from theater.conflicttheater import *
|
||||
from theater.controlpoint import *
|
||||
from userdata.debriefing_parser import *
|
||||
from game.event import *
|
||||
|
||||
COMMISION_LIMITS_SCALE = 2
|
||||
@@ -24,12 +18,16 @@ COMMISION_AMOUNTS_FACTORS = {
|
||||
|
||||
|
||||
ENEMY_INTERCEPT_PROBABILITY_BASE = 10
|
||||
ENEMY_INTERCEPT_GLOBAL_PROBABILITY_BASE = 1
|
||||
ENEMY_CAPTURE_PROBABILITY_BASE = 3
|
||||
|
||||
PLAYER_INTERCEPT_PROBABILITY_BASE = 30
|
||||
PLAYER_GROUNDINTERCEPT_PROBABILITY_BASE = 30
|
||||
PLAYER_GLOBALINTERCEPT_PROBABILITY_BASE = 100
|
||||
|
||||
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 50
|
||||
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG = 2
|
||||
|
||||
PLAYER_BUDGET_BASE = 25
|
||||
PLAYER_BUDGET_IMPORTANCE_LOG = 2
|
||||
|
||||
@@ -54,7 +52,8 @@ class Game:
|
||||
self.events.append(CaptureEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp))
|
||||
to_cp=to_cp,
|
||||
theater=self.theater))
|
||||
|
||||
def _generate_enemy_caps(self):
|
||||
for from_cp, to_cp in self.theater.conflicts(False):
|
||||
@@ -65,10 +64,12 @@ class Game:
|
||||
self.events.append(CaptureEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp))
|
||||
to_cp=to_cp,
|
||||
theater=self.theater))
|
||||
break
|
||||
|
||||
def _generate_interceptions(self):
|
||||
enemy_interception = False
|
||||
for from_cp, to_cp in self.theater.conflicts(False):
|
||||
if from_cp.base.total_units(FighterSweep) == 0:
|
||||
continue
|
||||
@@ -77,15 +78,36 @@ class Game:
|
||||
self.events.append(InterceptEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp))
|
||||
to_cp=to_cp,
|
||||
theater=self.theater))
|
||||
enemy_interception = True
|
||||
break
|
||||
|
||||
for to_cp in self.theater.player_points():
|
||||
if enemy_interception:
|
||||
break
|
||||
|
||||
if to_cp in self.theater.conflicts(False):
|
||||
continue
|
||||
|
||||
if self._roll(ENEMY_INTERCEPT_GLOBAL_PROBABILITY_BASE, 1):
|
||||
for from_cp, _ in self.theater.conflicts(False):
|
||||
if from_cp.base.total_units(FighterSweep) > 0:
|
||||
self.events.append(InterceptEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
theater=self.theater))
|
||||
enemy_interception = True
|
||||
break
|
||||
|
||||
for from_cp, to_cp in self.theater.conflicts(True):
|
||||
if self._roll(PLAYER_INTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(InterceptEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp))
|
||||
to_cp=to_cp,
|
||||
theater=self.theater))
|
||||
break
|
||||
|
||||
def _generate_groundinterceptions(self):
|
||||
@@ -94,7 +116,20 @@ class Game:
|
||||
self.events.append(GroundInterceptEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp))
|
||||
to_cp=to_cp,
|
||||
theater=self.theater))
|
||||
break
|
||||
|
||||
def _generate_globalinterceptions(self):
|
||||
for from_cp in [x for x in self.theater.player_points() if x.is_global]:
|
||||
probability = PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE * math.log(len(self.theater.player_points()) + 1, PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG)
|
||||
if self._roll(probability, from_cp.base.strength):
|
||||
to_cp = random.choice([x for x in self.theater.enemy_points() if x not in self.theater.conflicts()])
|
||||
self.events.append(InterceptEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
theater=self.theater))
|
||||
break
|
||||
|
||||
def _generate_global(self):
|
||||
@@ -134,7 +169,8 @@ class Game:
|
||||
event = UnitsDeliveryEvent(attacker_name=self.player,
|
||||
defender_name=self.player,
|
||||
from_cp=to_cp,
|
||||
to_cp=to_cp)
|
||||
to_cp=to_cp,
|
||||
theater=self.theater)
|
||||
self.events.append(event)
|
||||
return event
|
||||
|
||||
@@ -143,8 +179,8 @@ class Game:
|
||||
self.events.remove(event)
|
||||
|
||||
def initiate_event(self, event: Event):
|
||||
event.operation.generate()
|
||||
event.mission.save("build/next_mission.miz")
|
||||
assert event in self.events
|
||||
event.generate()
|
||||
|
||||
def finish_event(self, event: Event, debriefing: Debriefing):
|
||||
event.commit(debriefing)
|
||||
@@ -154,7 +190,7 @@ class Game:
|
||||
self.events.remove(event)
|
||||
|
||||
def is_player_attack(self, event: Event):
|
||||
return event.attacker.name == self.player
|
||||
return event.attacker_name == self.player
|
||||
|
||||
def pass_turn(self, no_action=False):
|
||||
for event in self.events:
|
||||
@@ -162,13 +198,14 @@ class Game:
|
||||
|
||||
if not no_action:
|
||||
self._budget_player()
|
||||
for cp in self.theater.enemy_bases():
|
||||
for cp in self.theater.enemy_points():
|
||||
self._commision_units(cp)
|
||||
|
||||
self.events = [] # type: typing.List[Event]
|
||||
self._fill_cap_events()
|
||||
self._generate_enemy_caps()
|
||||
self._generate_interceptions()
|
||||
self._generate_globalinterceptions()
|
||||
self._generate_groundinterceptions()
|
||||
self._generate_global()
|
||||
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
import typing
|
||||
|
||||
from globals import *
|
||||
from userdata.debriefing_parser import *
|
||||
from dcs.mission import *
|
||||
from dcs.unitgroup import *
|
||||
from dcs.vehicles import *
|
||||
from theater.controlpoint import *
|
||||
from userdata.debriefing import *
|
||||
from theater.conflicttheater import *
|
||||
from theater.base import *
|
||||
from shop import *
|
||||
|
||||
from gen.armor import *
|
||||
from gen.aircraft import *
|
||||
@@ -18,13 +10,42 @@ from gen.conflictgen import *
|
||||
|
||||
|
||||
class Operation:
|
||||
def __init__(self, mission: Mission, conflict: Conflict):
|
||||
starting_position = None # type: db.StartingPosition
|
||||
mission = None # type: dcs.Mission
|
||||
conflict = None # type: Conflict
|
||||
armorgen = None # type: ArmorConflictGenerator
|
||||
airgen = None # type: AircraftConflictGenerator
|
||||
aagen = None # type: AAConflictGenerator
|
||||
shipgen = None # type: ShipGenerator
|
||||
|
||||
def __init__(self,
|
||||
attacker_name: str,
|
||||
defender_name: str,
|
||||
attacker_clients: db.PlaneDict,
|
||||
defender_clients: db.PlaneDict,
|
||||
from_cp: ControlPoint,
|
||||
to_cp: ControlPoint = None):
|
||||
self.attacker_name = attacker_name
|
||||
self.defender_name = defender_name
|
||||
self.attacker_clients = attacker_clients
|
||||
self.defender_clients = defender_clients
|
||||
self.from_cp = from_cp
|
||||
self.to_cp = to_cp
|
||||
|
||||
def initialize(self, mission: Mission, conflict: Conflict):
|
||||
self.mission = mission
|
||||
self.conflict = conflict
|
||||
self.armorgen = ArmorConflictGenerator(self.mission, self.conflict)
|
||||
self.airgen = AircraftConflictGenerator(self.mission, self.conflict)
|
||||
self.aagen = AAConflictGenerator(self.mission, self.conflict)
|
||||
self.shipgen = ShipGenerator(self.mission, self.conflict)
|
||||
|
||||
self.armorgen = ArmorConflictGenerator(mission, conflict)
|
||||
self.airgen = AircraftConflictGenerator(mission, conflict)
|
||||
self.aagen = AAConflictGenerator(mission, conflict)
|
||||
self.shipgen = ShipGenerator(mission, conflict)
|
||||
|
||||
def prepare(self, is_quick: bool):
|
||||
self.starting_position = is_quick and self.from_cp.at or None
|
||||
|
||||
def generate(self):
|
||||
pass
|
||||
|
||||
def units_of(self, country_name: str) -> typing.Collection[UnitType]:
|
||||
return []
|
||||
@@ -32,85 +53,81 @@ class Operation:
|
||||
def is_successfull(self, debriefing: Debriefing) -> bool:
|
||||
return True
|
||||
|
||||
def generate(self):
|
||||
pass
|
||||
|
||||
|
||||
class CaptureOperation(Operation):
|
||||
def __init__(self,
|
||||
mission: Mission,
|
||||
attacker: Country,
|
||||
defender: Country,
|
||||
attacker_clients: db.PlaneDict,
|
||||
defender_clients: db.PlaneDict,
|
||||
from_cp: ControlPoint,
|
||||
to_cp: ControlPoint,
|
||||
cas: db.PlaneDict,
|
||||
escort: db.PlaneDict,
|
||||
attack: db.ArmorDict,
|
||||
intercept: db.PlaneDict,
|
||||
defense: db.ArmorDict,
|
||||
aa: db.AirDefenseDict):
|
||||
conflict = to_cp.conflict_attack(from_cp, attacker, defender)
|
||||
cas = None # type: db.PlaneDict
|
||||
escort = None # type: db.PlaneDict
|
||||
intercept = None # type: db.PlaneDict
|
||||
attack = None # type: db.ArmorDict
|
||||
defense = None # type: db.ArmorDict
|
||||
aa = None # type: db.AirDefenseDict
|
||||
|
||||
super(CaptureOperation, self).__init__(mission, conflict)
|
||||
self.from_cp = from_cp
|
||||
self.to_cp = to_cp
|
||||
self.attacker_clients = attacker_clients
|
||||
self.defender_clients = defender_clients
|
||||
self.cas = cas
|
||||
self.escort = escort
|
||||
self.intercept = intercept
|
||||
def setup(self,
|
||||
cas: db.PlaneDict,
|
||||
escort: db.PlaneDict,
|
||||
attack: db.ArmorDict,
|
||||
intercept: db.PlaneDict,
|
||||
defense: db.ArmorDict,
|
||||
aa: db.AirDefenseDict):
|
||||
self.cas = cas
|
||||
self.escort = escort
|
||||
self.intercept = intercept
|
||||
self.attack = attack
|
||||
self.defense = defense
|
||||
self.aa = aa
|
||||
|
||||
self.attack = attack
|
||||
self.defense = defense
|
||||
def prepare(self, is_quick: bool):
|
||||
super(CaptureOperation, self).prepare(is_quick)
|
||||
mission = dcs.Mission()
|
||||
|
||||
self.aa = aa
|
||||
self.initialize(mission=mission,
|
||||
conflict=self.to_cp.conflict_attack(self.from_cp,
|
||||
mission.country(self.attacker_name),
|
||||
mission.country(self.defender_name)))
|
||||
|
||||
def generate(self):
|
||||
self.armorgen.generate(self.attack, self.defense)
|
||||
self.aagen.generate(self.aa)
|
||||
self.airgen.generate_defense(self.intercept, clients=self.defender_clients)
|
||||
|
||||
self.airgen.generate_cas(self.cas, clients=self.attacker_clients, at=self.from_cp.at)
|
||||
self.airgen.generate_cas_escort(self.escort, clients=self.attacker_clients, at=self.from_cp.at)
|
||||
self.airgen.generate_cas(self.cas, clients=self.attacker_clients, at=self.starting_position)
|
||||
self.airgen.generate_cas_escort(self.escort, clients=self.attacker_clients, at=self.starting_position)
|
||||
|
||||
|
||||
class InterceptOperation(Operation):
|
||||
def __init__(self,
|
||||
mission: Mission,
|
||||
attacker: Country,
|
||||
defender: Country,
|
||||
attacker_clients: db.PlaneDict,
|
||||
defender_clients: db.PlaneDict,
|
||||
from_cp: ControlPoint,
|
||||
to_cp: ControlPoint,
|
||||
escort: db.PlaneDict,
|
||||
transport: db.PlaneDict,
|
||||
airdefense: db.AirDefenseDict,
|
||||
interceptors: db.PlaneDict):
|
||||
heading = from_cp.position.heading_between_point(to_cp.position)
|
||||
distance = from_cp.position.distance_to_point(to_cp.position)
|
||||
position = from_cp.position.point_from_heading(heading, distance/2)
|
||||
|
||||
conflict = Conflict.intercept_conflict(
|
||||
attacker=attacker,
|
||||
defender=defender,
|
||||
position=position,
|
||||
heading=heading,
|
||||
radials=ALL_RADIALS
|
||||
)
|
||||
escort = None # type: db.PlaneDict
|
||||
transport = None # type: db.PlaneDict
|
||||
interceptors = None # type: db.PlaneDict
|
||||
airdefense = None # type: db.AirDefenseDict
|
||||
|
||||
super(InterceptOperation, self).__init__(mission, conflict)
|
||||
self.to_cp = to_cp
|
||||
self.from_cp = from_cp
|
||||
self.attacker_clients = attacker_clients
|
||||
self.defender_clients = defender_clients
|
||||
def setup(self,
|
||||
escort: db.PlaneDict,
|
||||
transport: db.PlaneDict,
|
||||
airdefense: db.AirDefenseDict,
|
||||
interceptors: db.PlaneDict):
|
||||
self.escort = escort
|
||||
self.transport = transport
|
||||
self.airdefense = airdefense
|
||||
self.interceptors = interceptors
|
||||
|
||||
def prepare(self, is_quick: bool):
|
||||
super(InterceptOperation, self).prepare(is_quick)
|
||||
mission = dcs.Mission()
|
||||
|
||||
heading = self.from_cp.position.heading_between_point(self.to_cp.position)
|
||||
distance = self.from_cp.position.distance_to_point(self.to_cp.position)
|
||||
position = self.from_cp.position.point_from_heading(heading, distance/2)
|
||||
conflict = Conflict.intercept_conflict(
|
||||
attacker=mission.country(self.attacker_name),
|
||||
defender=mission.country(self.defender_name),
|
||||
position=position,
|
||||
heading=randint(0, 360),
|
||||
radials=ALL_RADIALS
|
||||
)
|
||||
|
||||
self.initialize(mission=mission,
|
||||
conflict=conflict)
|
||||
|
||||
def generate(self):
|
||||
self.airgen.generate_transport(self.transport, self.to_cp.at)
|
||||
self.airgen.generate_transport_escort(self.escort, clients=self.defender_clients)
|
||||
@@ -119,35 +136,31 @@ class InterceptOperation(Operation):
|
||||
if self.from_cp.is_global:
|
||||
self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.shipgen.generate(self.from_cp.at))
|
||||
else:
|
||||
self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.from_cp.at)
|
||||
self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.starting_position)
|
||||
|
||||
|
||||
class GroundInterceptOperation(Operation):
|
||||
def __init__(self,
|
||||
mission: Mission,
|
||||
attacker: Country,
|
||||
defender: Country,
|
||||
from_cp: ControlPoint,
|
||||
attacker_clients: db.PlaneDict,
|
||||
defender_clients: db.PlaneDict,
|
||||
position: Point,
|
||||
target: db.ArmorDict,
|
||||
strikegroup: db.PlaneDict):
|
||||
def setup(self,
|
||||
position: Point,
|
||||
target: db.ArmorDict,
|
||||
strikegroup: db.PlaneDict):
|
||||
self.position = position
|
||||
self.strikegroup = strikegroup
|
||||
self.target = target
|
||||
|
||||
def prepare(self, is_quick: bool):
|
||||
super(GroundInterceptOperation, self).prepare(is_quick)
|
||||
mission = dcs.Mission()
|
||||
conflict = Conflict.ground_intercept_conflict(
|
||||
attacker=attacker,
|
||||
defender=defender,
|
||||
position=position,
|
||||
attacker=mission.country(self.defender_name),
|
||||
defender=mission.country(self.defender_name),
|
||||
position=self.position,
|
||||
heading=randint(0, 360),
|
||||
radials=ALL_RADIALS
|
||||
)
|
||||
|
||||
super(GroundInterceptOperation, self).__init__(mission, conflict)
|
||||
self.attacker_clients = attacker_clients
|
||||
self.defender_clients = defender_clients
|
||||
self.from_cp = from_cp
|
||||
self.strikegroup = strikegroup
|
||||
self.target = target
|
||||
|
||||
def generate(self):
|
||||
self.airgen.generate_cas(self.strikegroup, clients=self.attacker_clients, at=self.from_cp.at)
|
||||
self.airgen.generate_cas(self.strikegroup, clients=self.attacker_clients, at=self.starting_position)
|
||||
self.armorgen.generate({}, self.target)
|
||||
|
||||
Reference in New Issue
Block a user