mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12853feec3 | ||
|
|
d31876b65e | ||
|
|
ca521e7e51 | ||
|
|
f21c515d5c |
16
__init__.py
16
__init__.py
@@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import dcs
|
import dcs
|
||||||
import logging
|
import logging
|
||||||
@@ -33,13 +34,19 @@ def proceed_to_main_menu(game: Game):
|
|||||||
|
|
||||||
|
|
||||||
def is_version_compatible(save_version):
|
def is_version_compatible(save_version):
|
||||||
current_version = VERSION_STRING.split(".")
|
current_version_components = re.split(r"[\._]", VERSION_STRING)
|
||||||
save_version = save_version.split(".")
|
save_version_components = re.split(r"[\._]", save_version)
|
||||||
|
|
||||||
if "--ignore-save" in sys.argv:
|
if "--ignore-save" in sys.argv:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if current_version[:2] == save_version[:2]:
|
if current_version_components == save_version_components:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if save_version == "1.4_rc1":
|
||||||
|
return False
|
||||||
|
|
||||||
|
if current_version_components[:2] == save_version_components[:2]:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
@@ -80,9 +87,10 @@ try:
|
|||||||
new_game_menu = ui.newgamemenu.NewGameMenu(w, start_new_game)
|
new_game_menu = ui.newgamemenu.NewGameMenu(w, start_new_game)
|
||||||
new_game_menu.display()
|
new_game_menu.display()
|
||||||
else:
|
else:
|
||||||
|
game.settings.version = VERSION_STRING
|
||||||
proceed_to_main_menu(game)
|
proceed_to_main_menu(game)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
logging.exception(e)
|
||||||
ui.corruptedsavemenu.CorruptedSaveMenu(w).display()
|
ui.corruptedsavemenu.CorruptedSaveMenu(w).display()
|
||||||
|
|
||||||
w.run()
|
w.run()
|
||||||
|
|||||||
44
game/db.py
44
game/db.py
@@ -358,7 +358,8 @@ PLANE_PAYLOAD_OVERRIDES = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
Ka_50: {
|
Ka_50: {
|
||||||
"*": "12x9A4172, 40xS-8",
|
CAS: "12x9A4172, 40xS-8",
|
||||||
|
GroundAttack: "12x9A4172, 40xS-8",
|
||||||
},
|
},
|
||||||
|
|
||||||
M_2000C: {
|
M_2000C: {
|
||||||
@@ -366,7 +367,7 @@ PLANE_PAYLOAD_OVERRIDES = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
MiG_21Bis: {
|
MiG_21Bis: {
|
||||||
"*": "Patrol, medium range",
|
CAP: "Patrol, medium range",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,7 +393,11 @@ HeliDict = typing.Dict[HelicopterType, int]
|
|||||||
ArmorDict = typing.Dict[VehicleType, int]
|
ArmorDict = typing.Dict[VehicleType, int]
|
||||||
ShipDict = typing.Dict[ShipType, int]
|
ShipDict = typing.Dict[ShipType, int]
|
||||||
AirDefenseDict = typing.Dict[AirDefence, 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:
|
def unit_task(unit: UnitType) -> Task:
|
||||||
@@ -471,6 +476,39 @@ def unitdict_restrict_count(unit_dict: UnitsDict, total_count: int) -> UnitsDict
|
|||||||
return {}
|
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 assignedunits_split_to_count(dict: AssignedUnitsDict, count: int):
|
||||||
|
buffer_dict = {}
|
||||||
|
for unit_type, (unit_count, client_count) in dict.items():
|
||||||
|
for _ in range(unit_count):
|
||||||
|
new_count, new_client_count = buffer_dict.get(unit_type, (0, 0))
|
||||||
|
|
||||||
|
new_count += 1
|
||||||
|
|
||||||
|
if client_count > 0:
|
||||||
|
new_client_count += 1
|
||||||
|
client_count -= 1
|
||||||
|
|
||||||
|
buffer_dict[unit_type] = new_count, new_client_count
|
||||||
|
if new_count >= count:
|
||||||
|
yield buffer_dict
|
||||||
|
buffer_dict = {}
|
||||||
|
|
||||||
|
if len(buffer_dict):
|
||||||
|
yield buffer_dict
|
||||||
|
|
||||||
|
|
||||||
|
def unitdict_from(fd: AssignedUnitsDict) -> Dict:
|
||||||
|
return {k: v1 for k, (v1, v2) in fd.items()}
|
||||||
|
|
||||||
|
|
||||||
def _validate_db():
|
def _validate_db():
|
||||||
# check unit by task uniquity
|
# check unit by task uniquity
|
||||||
total_set = set()
|
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 game.operation.baseattack import BaseAttackOperation
|
||||||
from userdata.debriefing import Debriefing
|
|
||||||
|
|
||||||
from .event import *
|
from .event import *
|
||||||
from ..operation.operation import flight_dict_from
|
from game.db import assigned_units_from
|
||||||
|
|
||||||
|
|
||||||
class BaseAttackEvent(Event):
|
class BaseAttackEvent(Event):
|
||||||
@@ -60,7 +51,7 @@ class BaseAttackEvent(Event):
|
|||||||
if not self.is_player_attacking and self.to_cp.captured:
|
if not self.is_player_attacking and self.to_cp.captured:
|
||||||
self.to_cp.captured = False
|
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"
|
assert CAP in flights and len(flights) == 1, "Invalid scrambled flights"
|
||||||
|
|
||||||
cas = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
|
cas = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||||
@@ -73,8 +64,8 @@ class BaseAttackEvent(Event):
|
|||||||
from_cp=self.from_cp,
|
from_cp=self.from_cp,
|
||||||
to_cp=self.to_cp)
|
to_cp=self.to_cp)
|
||||||
|
|
||||||
op.setup(cas=flight_dict_from(cas),
|
op.setup(cas=assigned_units_from(cas),
|
||||||
escort=flight_dict_from(escort),
|
escort=assigned_units_from(escort),
|
||||||
intercept=flights[CAP],
|
intercept=flights[CAP],
|
||||||
attack=attackers,
|
attack=attackers,
|
||||||
defense=self.to_cp.base.armor,
|
defense=self.to_cp.base.armor,
|
||||||
@@ -82,7 +73,7 @@ class BaseAttackEvent(Event):
|
|||||||
|
|
||||||
self.operation = op
|
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"
|
assert CAP in flights and CAS in flights and PinpointStrike in flights and len(flights) == 3, "Invalid flights"
|
||||||
|
|
||||||
op = BaseAttackOperation(game=self.game,
|
op = BaseAttackOperation(game=self.game,
|
||||||
@@ -97,7 +88,7 @@ class BaseAttackEvent(Event):
|
|||||||
op.setup(cas=flights[CAS],
|
op.setup(cas=flights[CAS],
|
||||||
escort=flights[CAP],
|
escort=flights[CAP],
|
||||||
attack=flights[PinpointStrike],
|
attack=flights[PinpointStrike],
|
||||||
intercept=flight_dict_from(defenders),
|
intercept=assigned_units_from(defenders),
|
||||||
defense=self.to_cp.base.armor,
|
defense=self.to_cp.base.armor,
|
||||||
aa=self.to_cp.base.assemble_aa())
|
aa=self.to_cp.base.assemble_aa())
|
||||||
|
|
||||||
|
|||||||
@@ -2,21 +2,19 @@ import typing
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from dcs.unittype import UnitType
|
from dcs.unittype import UnitType
|
||||||
from dcs.task import Task
|
from dcs.task import *
|
||||||
from dcs.unittype import UnitType
|
from dcs.unittype import UnitType
|
||||||
|
|
||||||
from game import *
|
from game import *
|
||||||
from theater import *
|
from theater import *
|
||||||
from gen.environmentgen import EnvironmentSettings
|
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.debriefing import Debriefing
|
||||||
from userdata import persistency
|
from userdata import persistency
|
||||||
|
|
||||||
DIFFICULTY_LOG_BASE = 1.1
|
DIFFICULTY_LOG_BASE = 1.1
|
||||||
|
|
||||||
ScrambledFlightsDict = typing.Dict[typing.Type[Task], typing.Dict[typing.Type[UnitType], typing.Tuple[int, int]]]
|
|
||||||
|
|
||||||
|
|
||||||
class Event:
|
class Event:
|
||||||
silent = False
|
silent = False
|
||||||
@@ -67,10 +65,10 @@ class Event:
|
|||||||
def is_successfull(self, debriefing: Debriefing) -> bool:
|
def is_successfull(self, debriefing: Debriefing) -> bool:
|
||||||
return self.operation.is_successfull(debriefing)
|
return self.operation.is_successfull(debriefing)
|
||||||
|
|
||||||
def player_attacking(self, flights: ScrambledFlightsDict):
|
def player_attacking(self, flights: db.TaskForceDict):
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
def player_defending(self, flights: ScrambledFlightsDict):
|
def player_defending(self, flights: db.TaskForceDict):
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
def generate(self):
|
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.event import *
|
||||||
from game.operation.frontlineattack import FrontlineAttackOperation
|
from game.operation.frontlineattack import FrontlineAttackOperation
|
||||||
from userdata.debriefing import Debriefing
|
from userdata.debriefing import Debriefing
|
||||||
@@ -69,7 +62,7 @@ class FrontlineAttackEvent(Event):
|
|||||||
if self.to_cp.captured:
|
if self.to_cp.captured:
|
||||||
self.to_cp.base.affect_strength(-0.1)
|
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"
|
assert CAS in flights and PinpointStrike in flights and len(flights) == 2, "Invalid flights"
|
||||||
|
|
||||||
self.defenders = self.to_cp.base.assemble_attack()
|
self.defenders = self.to_cp.base.assemble_attack()
|
||||||
@@ -80,7 +73,7 @@ class FrontlineAttackEvent(Event):
|
|||||||
from_cp=self.from_cp,
|
from_cp=self.from_cp,
|
||||||
to_cp=self.to_cp)
|
to_cp=self.to_cp)
|
||||||
|
|
||||||
armor = dict_from_flight(flights[PinpointStrike])
|
armor = unitdict_from(flights[PinpointStrike])
|
||||||
op.setup(target=self.defenders,
|
op.setup(target=self.defenders,
|
||||||
attackers=db.unitdict_restrict_count(armor, sum(self.defenders.values())),
|
attackers=db.unitdict_restrict_count(armor, sum(self.defenders.values())),
|
||||||
strikegroup=flights[CAS])
|
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.event import *
|
||||||
from game.operation.frontlinepatrol import FrontlinePatrolOperation
|
from game.operation.frontlinepatrol import FrontlinePatrolOperation
|
||||||
from userdata.debriefing import Debriefing
|
from userdata.debriefing import Debriefing
|
||||||
@@ -61,7 +54,7 @@ class FrontlinePatrolEvent(Event):
|
|||||||
def skip(self):
|
def skip(self):
|
||||||
pass
|
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"
|
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)
|
self.cas = self.to_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||||
@@ -74,8 +67,8 @@ class FrontlinePatrolEvent(Event):
|
|||||||
to_cp=self.to_cp)
|
to_cp=self.to_cp)
|
||||||
|
|
||||||
defenders = self.to_cp.base.assemble_attack()
|
defenders = self.to_cp.base.assemble_attack()
|
||||||
op.setup(cas=flight_dict_from(self.cas),
|
op.setup(cas=assigned_units_from(self.cas),
|
||||||
escort=flight_dict_from(self.escort),
|
escort=assigned_units_from(self.escort),
|
||||||
interceptors=flights[CAP],
|
interceptors=flights[CAP],
|
||||||
armor_attackers=db.unitdict_restrict_count(dict_from_flight(flights[PinpointStrike]), sum(defenders.values())),
|
armor_attackers=db.unitdict_restrict_count(dict_from_flight(flights[PinpointStrike]), sum(defenders.values())),
|
||||||
armor_defenders=defenders)
|
armor_defenders=defenders)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class InfantryTransportEvent(Event):
|
|||||||
else:
|
else:
|
||||||
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
|
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"
|
assert Embarking in flights and len(flights) == 1, "Invalid flights"
|
||||||
|
|
||||||
op = InfantryTransportOperation(
|
op = InfantryTransportOperation(
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class InsurgentAttackEvent(Event):
|
|||||||
else:
|
else:
|
||||||
return not attackers_success
|
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"
|
assert CAS in flights and len(flights) == 1, "Invalid flights"
|
||||||
|
|
||||||
suitable_unittypes = db.find_unittype(Reconnaissance, self.attacker_name)
|
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 game.operation.intercept import InterceptOperation
|
||||||
from theater.conflicttheater import *
|
|
||||||
from userdata.debriefing import Debriefing
|
|
||||||
|
|
||||||
from .event import *
|
from .event import *
|
||||||
|
|
||||||
@@ -68,7 +59,7 @@ class InterceptEvent(Event):
|
|||||||
if self.to_cp.captured:
|
if self.to_cp.captured:
|
||||||
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
|
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"
|
assert CAP in flights and len(flights) == 1, "Invalid flights"
|
||||||
|
|
||||||
escort = self.to_cp.base.scramble_sweep(self._enemy_scramble_multiplier())
|
escort = self.to_cp.base.scramble_sweep(self._enemy_scramble_multiplier())
|
||||||
@@ -83,14 +74,14 @@ class InterceptEvent(Event):
|
|||||||
from_cp=self.from_cp,
|
from_cp=self.from_cp,
|
||||||
to_cp=self.to_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},
|
transport={self.transport_unit: 1},
|
||||||
airdefense={airdefense_unit: self.AIRDEFENSE_COUNT},
|
airdefense={airdefense_unit: self.AIRDEFENSE_COUNT},
|
||||||
interceptors=flights[CAP])
|
interceptors=flights[CAP])
|
||||||
|
|
||||||
self.operation = op
|
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"
|
assert CAP in flights and len(flights) == 1, "Invalid flights"
|
||||||
|
|
||||||
interceptors = self.from_cp.base.scramble_interceptors(self.game.settings.multiplier)
|
interceptors = self.from_cp.base.scramble_interceptors(self.game.settings.multiplier)
|
||||||
@@ -106,7 +97,7 @@ class InterceptEvent(Event):
|
|||||||
|
|
||||||
op.setup(escort=flights[CAP],
|
op.setup(escort=flights[CAP],
|
||||||
transport={self.transport_unit: 1},
|
transport={self.transport_unit: 1},
|
||||||
interceptors=flight_dict_from(interceptors),
|
interceptors=assigned_units_from(interceptors),
|
||||||
airdefense={})
|
airdefense={})
|
||||||
|
|
||||||
self.operation = op
|
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 game.operation.navalintercept import NavalInterceptionOperation
|
||||||
from userdata.debriefing import Debriefing
|
|
||||||
|
|
||||||
from .event import *
|
from .event import *
|
||||||
|
|
||||||
@@ -19,7 +10,7 @@ class NavalInterceptEvent(Event):
|
|||||||
targets = None # type: db.ShipDict
|
targets = None # type: db.ShipDict
|
||||||
|
|
||||||
def _targets_count(self) -> int:
|
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
|
factor = (self.to_cp.importance - IMPORTANCE_LOW) * 10
|
||||||
return max(int(factor), 1)
|
return max(int(factor), 1)
|
||||||
|
|
||||||
@@ -77,7 +68,7 @@ class NavalInterceptEvent(Event):
|
|||||||
if self.to_cp.captured:
|
if self.to_cp.captured:
|
||||||
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
|
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"
|
assert CAS in flights and len(flights) == 1, "Invalid flights"
|
||||||
|
|
||||||
self.targets = {
|
self.targets = {
|
||||||
@@ -98,7 +89,7 @@ class NavalInterceptEvent(Event):
|
|||||||
|
|
||||||
self.operation = op
|
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"
|
assert CAP in flights and len(flights) == 1, "Invalid flights"
|
||||||
|
|
||||||
self.targets = {
|
self.targets = {
|
||||||
@@ -114,7 +105,7 @@ class NavalInterceptEvent(Event):
|
|||||||
)
|
)
|
||||||
|
|
||||||
strikegroup = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
|
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],
|
interceptors=flights[CAP],
|
||||||
targets=self.targets)
|
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 game.operation.strike import StrikeOperation
|
||||||
from theater.conflicttheater import *
|
|
||||||
from userdata.debriefing import Debriefing
|
|
||||||
|
|
||||||
from .event import *
|
from .event import *
|
||||||
|
|
||||||
@@ -50,7 +41,7 @@ class StrikeEvent(Event):
|
|||||||
super(StrikeEvent, self).commit(debriefing)
|
super(StrikeEvent, self).commit(debriefing)
|
||||||
self.to_cp.base.affect_strength(-self.SINGLE_OBJECT_STRENGTH_INFLUENCE * len(debriefing.destroyed_objects))
|
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"
|
assert CAP in flights and CAS in flights and len(flights) == 2, "Invalid flights"
|
||||||
|
|
||||||
op = StrikeOperation(
|
op = StrikeOperation(
|
||||||
@@ -64,6 +55,6 @@ class StrikeEvent(Event):
|
|||||||
interceptors = self.to_cp.base.scramble_interceptors(self.game.settings.multiplier)
|
interceptors = self.to_cp.base.scramble_interceptors(self.game.settings.multiplier)
|
||||||
op.setup(strikegroup=flights[CAS],
|
op.setup(strikegroup=flights[CAS],
|
||||||
escort=flights[CAP],
|
escort=flights[CAP],
|
||||||
interceptors=flight_dict_from(interceptors))
|
interceptors=assigned_units_from(interceptors))
|
||||||
|
|
||||||
self.operation = op
|
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.triggergen import *
|
||||||
from gen.airsupportgen import *
|
|
||||||
from gen.visualgen import *
|
|
||||||
|
|
||||||
from .operation import *
|
from .operation import *
|
||||||
|
|
||||||
|
|
||||||
class BaseAttackOperation(Operation):
|
class BaseAttackOperation(Operation):
|
||||||
cas = None # type: FlightDict
|
cas = None # type: db.AssignedUnitsDict
|
||||||
escort = None # type: FlightDict
|
escort = None # type: db.AssignedUnitsDict
|
||||||
intercept = None # type: FlightDict
|
intercept = None # type: db.AssignedUnitsDict
|
||||||
attack = None # type: db.ArmorDict
|
attack = None # type: db.ArmorDict
|
||||||
defense = None # type: db.ArmorDict
|
defense = None # type: db.ArmorDict
|
||||||
aa = None # type: db.AirDefenseDict
|
aa = None # type: db.AirDefenseDict
|
||||||
@@ -23,10 +16,10 @@ class BaseAttackOperation(Operation):
|
|||||||
trigger_radius = TRIGGER_RADIUS_SMALL
|
trigger_radius = TRIGGER_RADIUS_SMALL
|
||||||
|
|
||||||
def setup(self,
|
def setup(self,
|
||||||
cas: FlightDict,
|
cas: db.AssignedUnitsDict,
|
||||||
escort: FlightDict,
|
escort: db.AssignedUnitsDict,
|
||||||
attack: FlightDict,
|
attack: db.AssignedUnitsDict,
|
||||||
intercept: FlightDict,
|
intercept: db.AssignedUnitsDict,
|
||||||
defense: db.ArmorDict,
|
defense: db.ArmorDict,
|
||||||
aa: db.AirDefenseDict):
|
aa: db.AirDefenseDict):
|
||||||
self.cas = cas
|
self.cas = cas
|
||||||
@@ -57,10 +50,10 @@ class BaseAttackOperation(Operation):
|
|||||||
self.armorgen.generate(self.attack, self.defense)
|
self.armorgen.generate(self.attack, self.defense)
|
||||||
self.aagen.generate(self.aa)
|
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_cas_strikegroup(*assigned_units_split(self.cas), 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.visualgen.generate_target_smokes(self.to_cp)
|
self.visualgen.generate_target_smokes(self.to_cp)
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
from itertools import zip_longest
|
from game.db import assigned_units_split
|
||||||
|
|
||||||
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 .operation import *
|
from .operation import *
|
||||||
|
|
||||||
@@ -19,14 +7,14 @@ MAX_DISTANCE_BETWEEN_GROUPS = 12000
|
|||||||
|
|
||||||
|
|
||||||
class FrontlineAttackOperation(Operation):
|
class FrontlineAttackOperation(Operation):
|
||||||
strikegroup = None # type: FlightDict
|
strikegroup = None # type: db.AssignedUnitsDict
|
||||||
attackers = None # type: db.ArmorDict
|
attackers = None # type: db.ArmorDict
|
||||||
target = None # type: db.ArmorDict
|
target = None # type: db.ArmorDict
|
||||||
|
|
||||||
def setup(self,
|
def setup(self,
|
||||||
target: db.ArmorDict,
|
target: db.ArmorDict,
|
||||||
attackers: db.ArmorDict,
|
attackers: db.ArmorDict,
|
||||||
strikegroup: FlightDict):
|
strikegroup: db.AssignedUnitsDict):
|
||||||
self.strikegroup = strikegroup
|
self.strikegroup = strikegroup
|
||||||
self.target = target
|
self.target = target
|
||||||
self.attackers = attackers
|
self.attackers = attackers
|
||||||
@@ -50,7 +38,16 @@ class FrontlineAttackOperation(Operation):
|
|||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
self.armorgen.generate_vec(self.attackers, self.target)
|
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.values()}
|
||||||
|
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.values()}
|
||||||
|
if heli_flights:
|
||||||
|
self.briefinggen.append_frequency("FARP", "127.5 MHz AM")
|
||||||
|
for farp, dict in zip(self.groundobjectgen.generate_farps(sum([x[0] for x in heli_flights.values()])),
|
||||||
|
db.assignedunits_split_to_count(heli_flights, self.groundobjectgen.FARP_CAPACITY)):
|
||||||
|
self.airgen.generate_cas_strikegroup(*assigned_units_split(dict), at=farp, escort=False)
|
||||||
|
|
||||||
self.briefinggen.title = "Frontline CAS"
|
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."
|
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 game.db import assigned_units_split
|
||||||
|
|
||||||
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 .operation import *
|
from .operation import *
|
||||||
|
|
||||||
@@ -19,17 +7,17 @@ MAX_DISTANCE_BETWEEN_GROUPS = 12000
|
|||||||
|
|
||||||
|
|
||||||
class FrontlinePatrolOperation(Operation):
|
class FrontlinePatrolOperation(Operation):
|
||||||
cas = None # type: FlightDict
|
cas = None # type: db.AssignedUnitsDict
|
||||||
escort = None # type: FlightDict
|
escort = None # type: db.AssignedUnitsDict
|
||||||
interceptors = None # type: FlightDict
|
interceptors = None # type: db.AssignedUnitsDict
|
||||||
|
|
||||||
armor_attackers = None # type: db.ArmorDict
|
armor_attackers = None # type: db.ArmorDict
|
||||||
armor_defenders = None # type: db.ArmorDict
|
armor_defenders = None # type: db.ArmorDict
|
||||||
|
|
||||||
def setup(self,
|
def setup(self,
|
||||||
cas: FlightDict,
|
cas: db.AssignedUnitsDict,
|
||||||
escort: FlightDict,
|
escort: db.AssignedUnitsDict,
|
||||||
interceptors: FlightDict,
|
interceptors: db.AssignedUnitsDict,
|
||||||
armor_attackers: db.ArmorDict,
|
armor_attackers: db.ArmorDict,
|
||||||
armor_defenders: db.ArmorDict):
|
armor_defenders: db.ArmorDict):
|
||||||
self.cas = cas
|
self.cas = cas
|
||||||
@@ -55,9 +43,9 @@ class FrontlinePatrolOperation(Operation):
|
|||||||
conflict=conflict)
|
conflict=conflict)
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
self.airgen.generate_defenders_cas(*flight_arguments(self.cas), at=self.defenders_starting_position)
|
self.airgen.generate_defenders_cas(*assigned_units_split(self.cas), at=self.defenders_starting_position)
|
||||||
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_migcap(*flight_arguments(self.interceptors), at=self.attackers_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)
|
self.armorgen.generate_vec(self.armor_attackers, self.armor_defenders)
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,13 @@
|
|||||||
from dcs.terrain import Terrain
|
from game.db import assigned_units_split
|
||||||
|
|
||||||
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 .operation import *
|
from .operation import *
|
||||||
|
|
||||||
|
|
||||||
class InfantryTransportOperation(Operation):
|
class InfantryTransportOperation(Operation):
|
||||||
transport = None # type: FlightDict
|
transport = None # type: db.AssignedUnitsDict
|
||||||
aa = None # type: db.AirDefenseDict
|
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.transport = transport
|
||||||
self.aa = aa
|
self.aa = aa
|
||||||
|
|
||||||
@@ -36,7 +26,7 @@ class InfantryTransportOperation(Operation):
|
|||||||
conflict=conflict)
|
conflict=conflict)
|
||||||
|
|
||||||
def generate(self):
|
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.armorgen.generate_passengers(count=6)
|
||||||
self.aagen.generate_at_defenders_location(self.aa)
|
self.aagen.generate_at_defenders_location(self.aa)
|
||||||
|
|||||||
@@ -1,25 +1,15 @@
|
|||||||
from dcs.terrain import Terrain
|
from game.db import assigned_units_split
|
||||||
|
|
||||||
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 .operation import *
|
from .operation import *
|
||||||
|
|
||||||
|
|
||||||
class InsurgentAttackOperation(Operation):
|
class InsurgentAttackOperation(Operation):
|
||||||
strikegroup = None # type: FlightDict
|
strikegroup = None # type: db.AssignedUnitsDict
|
||||||
target = None # type: db.ArmorDict
|
target = None # type: db.ArmorDict
|
||||||
|
|
||||||
def setup(self,
|
def setup(self,
|
||||||
target: db.ArmorDict,
|
target: db.ArmorDict,
|
||||||
strikegroup: FlightDict):
|
strikegroup: db.AssignedUnitsDict):
|
||||||
self.strikegroup = strikegroup
|
self.strikegroup = strikegroup
|
||||||
self.target = target
|
self.target = target
|
||||||
|
|
||||||
@@ -38,7 +28,7 @@ class InsurgentAttackOperation(Operation):
|
|||||||
conflict=conflict)
|
conflict=conflict)
|
||||||
|
|
||||||
def generate(self):
|
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.armorgen.generate(self.target, {})
|
||||||
|
|
||||||
self.briefinggen.title = "Destroy insurgents"
|
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 *
|
from .operation import *
|
||||||
|
|
||||||
|
|
||||||
class InterceptOperation(Operation):
|
class InterceptOperation(Operation):
|
||||||
escort = None # type: FlightDict
|
escort = None # type: db.AssignedUnitsDict
|
||||||
transport = None # type: db.PlaneDict
|
transport = None # type: db.PlaneDict
|
||||||
interceptors = None # type: FlightDict
|
interceptors = None # type: db.AssignedUnitsDict
|
||||||
airdefense = None # type: db.AirDefenseDict
|
airdefense = None # type: db.AirDefenseDict
|
||||||
|
|
||||||
trigger_radius = TRIGGER_RADIUS_LARGE
|
trigger_radius = TRIGGER_RADIUS_LARGE
|
||||||
|
|
||||||
def setup(self,
|
def setup(self,
|
||||||
escort: FlightDict,
|
escort: db.AssignedUnitsDict,
|
||||||
transport: db.PlaneDict,
|
transport: db.PlaneDict,
|
||||||
airdefense: db.AirDefenseDict,
|
airdefense: db.AirDefenseDict,
|
||||||
interceptors: FlightDict):
|
interceptors: db.AssignedUnitsDict):
|
||||||
self.escort = escort
|
self.escort = escort
|
||||||
self.transport = transport
|
self.transport = transport
|
||||||
self.airdefense = airdefense
|
self.airdefense = airdefense
|
||||||
@@ -52,9 +51,9 @@ class InterceptOperation(Operation):
|
|||||||
self.attackers_starting_position = ship
|
self.attackers_starting_position = ship
|
||||||
|
|
||||||
self.airgen.generate_transport(self.transport, self.to_cp.at)
|
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.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"
|
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 *
|
from .operation import *
|
||||||
|
|
||||||
|
|
||||||
class NavalInterceptionOperation(Operation):
|
class NavalInterceptionOperation(Operation):
|
||||||
strikegroup = None # type: FlightDict
|
strikegroup = None # type: db.AssignedUnitsDict
|
||||||
interceptors = None # type: FlightDict
|
interceptors = None # type: db.AssignedUnitsDict
|
||||||
targets = None # type: db.ShipDict
|
targets = None # type: db.ShipDict
|
||||||
trigger_radius = TRIGGER_RADIUS_LARGE
|
trigger_radius = TRIGGER_RADIUS_LARGE
|
||||||
|
|
||||||
def setup(self,
|
def setup(self,
|
||||||
strikegroup: FlightDict,
|
strikegroup: db.AssignedUnitsDict,
|
||||||
interceptors: FlightDict,
|
interceptors: db.AssignedUnitsDict,
|
||||||
targets: db.ShipDict):
|
targets: db.ShipDict):
|
||||||
self.strikegroup = strikegroup
|
self.strikegroup = strikegroup
|
||||||
self.interceptors = interceptors
|
self.interceptors = interceptors
|
||||||
@@ -37,14 +36,14 @@ class NavalInterceptionOperation(Operation):
|
|||||||
target_groups = self.shipgen.generate_cargo(units=self.targets)
|
target_groups = self.shipgen.generate_cargo(units=self.targets)
|
||||||
|
|
||||||
self.airgen.generate_ship_strikegroup(
|
self.airgen.generate_ship_strikegroup(
|
||||||
*flight_arguments(self.strikegroup),
|
*assigned_units_split(self.strikegroup),
|
||||||
target_groups=target_groups,
|
target_groups=target_groups,
|
||||||
at=self.attackers_starting_position
|
at=self.attackers_starting_position
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.interceptors:
|
if self.interceptors:
|
||||||
self.airgen.generate_defense(
|
self.airgen.generate_defense(
|
||||||
*flight_arguments(self.interceptors),
|
*assigned_units_split(self.interceptors),
|
||||||
at=self.defenders_starting_position
|
at=self.defenders_starting_position
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,14 @@
|
|||||||
import typing
|
|
||||||
|
|
||||||
from dcs.lua.parse import loads
|
from dcs.lua.parse import loads
|
||||||
from dcs.unittype import UnitType
|
|
||||||
|
|
||||||
from userdata.debriefing import *
|
from userdata.debriefing import *
|
||||||
|
|
||||||
from theater import *
|
|
||||||
from gen 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:
|
class Operation:
|
||||||
attackers_starting_position = None # type: db.StartingPosition
|
attackers_starting_position = None # type: db.StartingPosition
|
||||||
defenders_starting_position = None # type: db.StartingPosition
|
defenders_starting_position = None # type: db.StartingPosition
|
||||||
|
|
||||||
mission = None # type: dcs.Mission
|
mission = None # type: dcs.Mission
|
||||||
conflict = None # type: Conflict
|
conflict = None # type: Conflict
|
||||||
armorgen = None # type: ArmorConflictGenerator
|
armorgen = None # type: ArmorConflictGenerator
|
||||||
|
|||||||
@@ -1,27 +1,17 @@
|
|||||||
from dcs.terrain import Terrain
|
from game.db import assigned_units_split
|
||||||
|
|
||||||
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 .operation import *
|
from .operation import *
|
||||||
|
|
||||||
|
|
||||||
class StrikeOperation(Operation):
|
class StrikeOperation(Operation):
|
||||||
strikegroup = None # type: FlightDict
|
strikegroup = None # type: db.AssignedUnitsDict
|
||||||
escort = None # type: FlightDict
|
escort = None # type: db.AssignedUnitsDict
|
||||||
interceptors = None # type: FlightDict
|
interceptors = None # type: db.AssignedUnitsDict
|
||||||
|
|
||||||
def setup(self,
|
def setup(self,
|
||||||
strikegroup: FlightDict,
|
strikegroup: db.AssignedUnitsDict,
|
||||||
escort: FlightDict,
|
escort: db.AssignedUnitsDict,
|
||||||
interceptors: FlightDict):
|
interceptors: db.AssignedUnitsDict):
|
||||||
self.strikegroup = strikegroup
|
self.strikegroup = strikegroup
|
||||||
self.escort = escort
|
self.escort = escort
|
||||||
self.interceptors = interceptors
|
self.interceptors = interceptors
|
||||||
@@ -61,13 +51,13 @@ class StrikeOperation(Operation):
|
|||||||
|
|
||||||
targets.sort(key=lambda x: self.from_cp.position.distance_to_point(x[1]))
|
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,
|
targets=targets,
|
||||||
at=self.attackers_starting_position)
|
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.title = "Strike"
|
||||||
self.briefinggen.description = "Destroy infrastructure assets and military supplies in the region. Each building destroyed will lower targets strength."
|
self.briefinggen.description = "Destroy infrastructure assets and military supplies in the region. Each building destroyed will lower targets strength."
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from dcs.mission import *
|
|||||||
|
|
||||||
DISTANCE_FACTOR = 0.5, 1
|
DISTANCE_FACTOR = 0.5, 1
|
||||||
EXTRA_AA_MIN_DISTANCE = 35000
|
EXTRA_AA_MIN_DISTANCE = 35000
|
||||||
|
EXTRA_AA_MAX_DISTANCE = 150000
|
||||||
EXTRA_AA_POSITION_FROM_CP = 550
|
EXTRA_AA_POSITION_FROM_CP = 550
|
||||||
|
|
||||||
|
|
||||||
@@ -58,7 +59,9 @@ class ExtraAAConflictGenerator:
|
|||||||
if cp.position.distance_to_point(self.conflict.from_cp.position) < EXTRA_AA_MIN_DISTANCE:
|
if cp.position.distance_to_point(self.conflict.from_cp.position) < EXTRA_AA_MIN_DISTANCE:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
print("generated extra aa for {}".format(cp))
|
if cp.position.distance_to_point(self.conflict.position) > EXTRA_AA_MAX_DISTANCE:
|
||||||
|
continue
|
||||||
|
|
||||||
country_name = cp.captured and self.player_name or self.enemy_name
|
country_name = cp.captured and self.player_name or self.enemy_name
|
||||||
position = cp.position.point_from_heading(0, EXTRA_AA_POSITION_FROM_CP)
|
position = cp.position.point_from_heading(0, EXTRA_AA_POSITION_FROM_CP)
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ GROUP_VERTICAL_OFFSET = 300
|
|||||||
|
|
||||||
|
|
||||||
class AircraftConflictGenerator:
|
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
|
vertical_offset = None # type: int
|
||||||
|
|
||||||
def __init__(self, mission: Mission, conflict: Conflict, settings: Settings):
|
def __init__(self, mission: Mission, conflict: Conflict, settings: Settings):
|
||||||
@@ -77,7 +77,7 @@ class AircraftConflictGenerator:
|
|||||||
count -= group_size
|
count -= group_size
|
||||||
client_count -= client_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
|
did_load_loadout = False
|
||||||
unit_type = group.units[0].unit_type
|
unit_type = group.units[0].unit_type
|
||||||
if unit_type in db.PLANE_PAYLOAD_OVERRIDES:
|
if unit_type in db.PLANE_PAYLOAD_OVERRIDES:
|
||||||
@@ -112,6 +112,7 @@ class AircraftConflictGenerator:
|
|||||||
group.units[idx].set_client()
|
group.units[idx].set_client()
|
||||||
|
|
||||||
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
|
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
|
||||||
|
group.set_frequency(251.0)
|
||||||
|
|
||||||
def _generate_at_airport(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, airport: Airport = None) -> FlyingGroup:
|
def _generate_at_airport(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, airport: Airport = None) -> FlyingGroup:
|
||||||
assert count > 0
|
assert count > 0
|
||||||
@@ -155,11 +156,11 @@ class AircraftConflictGenerator:
|
|||||||
start_type=self._start_type(),
|
start_type=self._start_type(),
|
||||||
group_size=count)
|
group_size=count)
|
||||||
|
|
||||||
def _generate_at_carrier(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: ShipGroup) -> FlyingGroup:
|
def _generate_at_group(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: typing.Union[ShipGroup, StaticGroup]) -> FlyingGroup:
|
||||||
assert count > 0
|
assert count > 0
|
||||||
assert unit is not None
|
assert unit is not None
|
||||||
|
|
||||||
logging.info("airgen: {} for {} at carrier {}".format(unit_type, side.id, at))
|
logging.info("airgen: {} for {} at unit {}".format(unit_type, side.id, at))
|
||||||
return self.m.flight_group_from_unit(
|
return self.m.flight_group_from_unit(
|
||||||
country=side,
|
country=side,
|
||||||
name=name,
|
name=name,
|
||||||
@@ -172,10 +173,10 @@ class AircraftConflictGenerator:
|
|||||||
def _generate_group(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: db.StartingPosition):
|
def _generate_group(self, name: str, side: Country, unit_type: FlyingType, count: int, client_count: int, at: db.StartingPosition):
|
||||||
if isinstance(at, Point):
|
if isinstance(at, Point):
|
||||||
return self._generate_inflight(name, side, unit_type, count, client_count, at)
|
return self._generate_inflight(name, side, unit_type, count, client_count, at)
|
||||||
elif isinstance(at, ShipGroup):
|
elif isinstance(at, Group):
|
||||||
takeoff_ban = unit_type in db.CARRIER_TAKEOFF_BAN
|
takeoff_ban = unit_type in db.CARRIER_TAKEOFF_BAN
|
||||||
if not takeoff_ban:
|
if not takeoff_ban:
|
||||||
return self._generate_at_carrier(name, side, unit_type, count, client_count, at)
|
return self._generate_at_group(name, side, unit_type, count, client_count, at)
|
||||||
else:
|
else:
|
||||||
return self._generate_inflight(name, side, unit_type, count, client_count, at.position)
|
return self._generate_inflight(name, side, unit_type, count, client_count, at.position)
|
||||||
elif issubclass(at, Airport):
|
elif issubclass(at, Airport):
|
||||||
@@ -192,14 +193,16 @@ class AircraftConflictGenerator:
|
|||||||
assert False
|
assert False
|
||||||
|
|
||||||
def _rtb_for(self, group: FlyingGroup, cp: ControlPoint, at: db.StartingPosition = None):
|
def _rtb_for(self, group: FlyingGroup, cp: ControlPoint, at: db.StartingPosition = None):
|
||||||
group.add_waypoint(cp.position, RTB_ALTITUDE)
|
if not at:
|
||||||
|
at = cp.at
|
||||||
|
|
||||||
if isinstance(cp.at, Point):
|
if isinstance(at, Point):
|
||||||
pass
|
group.add_waypoint(at, RTB_ALTITUDE)
|
||||||
elif isinstance(cp.at, ShipGroup):
|
elif isinstance(at, Group):
|
||||||
pass
|
group.add_waypoint(at.position, RTB_ALTITUDE)
|
||||||
elif issubclass(cp.at, Airport):
|
elif issubclass(at, Airport):
|
||||||
group.land_at(cp.at)
|
group.add_waypoint(at.position, RTB_ALTITUDE)
|
||||||
|
group.land_at(at)
|
||||||
|
|
||||||
def _at_position(self, at) -> Point:
|
def _at_position(self, at) -> Point:
|
||||||
if isinstance(at, Point):
|
if isinstance(at, Point):
|
||||||
@@ -243,8 +246,8 @@ class AircraftConflictGenerator:
|
|||||||
groups.append(group)
|
groups.append(group)
|
||||||
return groups
|
return groups
|
||||||
|
|
||||||
def generate_cas_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
|
def generate_cas_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None, escort=True):
|
||||||
assert len(self.escort_targets) == 0
|
assert not escort or len(self.escort_targets) == 0
|
||||||
|
|
||||||
for flying_type, count, client_count in self._split_to_groups(attackers, clients):
|
for flying_type, count, client_count in self._split_to_groups(attackers, clients):
|
||||||
group = self._generate_group(
|
group = self._generate_group(
|
||||||
@@ -261,11 +264,12 @@ class AircraftConflictGenerator:
|
|||||||
|
|
||||||
group.task = CAS.name
|
group.task = CAS.name
|
||||||
self._setup_group(group, CAS, client_count)
|
self._setup_group(group, CAS, client_count)
|
||||||
self.escort_targets.append((group, group.points.index(waypoint)))
|
if escort:
|
||||||
|
self.escort_targets.append((group, group.points.index(waypoint)))
|
||||||
self._rtb_for(group, self.conflict.from_cp, at)
|
self._rtb_for(group, self.conflict.from_cp, at)
|
||||||
|
|
||||||
def generate_ground_attack_strikegroup(self, strikegroup: db.PlaneDict, clients: db.PlaneDict, targets: typing.List[typing.Tuple[str, Point]], at: db.StartingPosition = None):
|
def generate_ground_attack_strikegroup(self, strikegroup: db.PlaneDict, clients: db.PlaneDict, targets: typing.List[typing.Tuple[str, Point]], at: db.StartingPosition = None, escort=True):
|
||||||
assert len(self.escort_targets) == 0
|
assert not escort or len(self.escort_targets) == 0
|
||||||
|
|
||||||
for flying_type, count, client_count in self._split_to_groups(strikegroup, clients):
|
for flying_type, count, client_count in self._split_to_groups(strikegroup, clients):
|
||||||
group = self._generate_group(
|
group = self._generate_group(
|
||||||
@@ -285,11 +289,12 @@ class AircraftConflictGenerator:
|
|||||||
|
|
||||||
group.task = GroundAttack.name
|
group.task = GroundAttack.name
|
||||||
self._setup_group(group, GroundAttack, client_count)
|
self._setup_group(group, GroundAttack, client_count)
|
||||||
self.escort_targets.append((group, group.points.index(escort_until_waypoint)))
|
if escort:
|
||||||
|
self.escort_targets.append((group, group.points.index(escort_until_waypoint)))
|
||||||
self._rtb_for(group, self.conflict.from_cp, at)
|
self._rtb_for(group, self.conflict.from_cp, at)
|
||||||
|
|
||||||
def generate_defenders_cas(self, defenders: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
|
def generate_defenders_cas(self, defenders: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None, escort=True):
|
||||||
assert len(self.escort_targets) == 0
|
assert not escort or len(self.escort_targets) == 0
|
||||||
|
|
||||||
for flying_type, count, client_count in self._split_to_groups(defenders, clients):
|
for flying_type, count, client_count in self._split_to_groups(defenders, clients):
|
||||||
group = self._generate_group(
|
group = self._generate_group(
|
||||||
@@ -310,11 +315,12 @@ class AircraftConflictGenerator:
|
|||||||
|
|
||||||
group.task = CAS.name
|
group.task = CAS.name
|
||||||
self._setup_group(group, CAS, client_count)
|
self._setup_group(group, CAS, client_count)
|
||||||
self.escort_targets.append((group, group.points.index(waypoint)))
|
if escort:
|
||||||
|
self.escort_targets.append((group, group.points.index(waypoint)))
|
||||||
self._rtb_for(group, self.conflict.to_cp, at)
|
self._rtb_for(group, self.conflict.to_cp, at)
|
||||||
|
|
||||||
def generate_ship_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, target_groups: typing.Collection[ShipGroup], at: db.StartingPosition = None):
|
def generate_ship_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, target_groups: typing.Collection[ShipGroup], at: db.StartingPosition = None, escort=True):
|
||||||
assert len(self.escort_targets) == 0
|
assert not escort or len(self.escort_targets) == 0
|
||||||
|
|
||||||
for flying_type, count, client_count in self._split_to_groups(attackers, clients):
|
for flying_type, count, client_count in self._split_to_groups(attackers, clients):
|
||||||
group = self._generate_group(
|
group = self._generate_group(
|
||||||
@@ -331,7 +337,8 @@ class AircraftConflictGenerator:
|
|||||||
|
|
||||||
group.task = AntishipStrike.name
|
group.task = AntishipStrike.name
|
||||||
self._setup_group(group, AntishipStrike, client_count)
|
self._setup_group(group, AntishipStrike, client_count)
|
||||||
self.escort_targets.append((group, group.points.index(wayp)))
|
if escort:
|
||||||
|
self.escort_targets.append((group, group.points.index(wayp)))
|
||||||
self._rtb_for(group, self.conflict.from_cp, at)
|
self._rtb_for(group, self.conflict.from_cp, at)
|
||||||
|
|
||||||
def generate_attackers_escort(self, attackers: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
|
def generate_attackers_escort(self, attackers: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
|
||||||
@@ -413,8 +420,8 @@ class AircraftConflictGenerator:
|
|||||||
self._setup_group(group, CAP, client_count)
|
self._setup_group(group, CAP, client_count)
|
||||||
self._rtb_for(group, self.conflict.to_cp, at)
|
self._rtb_for(group, self.conflict.to_cp, at)
|
||||||
|
|
||||||
def generate_transport(self, transport: db.PlaneDict, destination: Airport):
|
def generate_transport(self, transport: db.PlaneDict, destination: Airport, escort=True):
|
||||||
assert len(self.escort_targets) == 0
|
assert not escort or len(self.escort_targets) == 0
|
||||||
|
|
||||||
for flying_type, count, client_count in self._split_to_groups(transport):
|
for flying_type, count, client_count in self._split_to_groups(transport):
|
||||||
group = self._generate_group(
|
group = self._generate_group(
|
||||||
@@ -426,8 +433,8 @@ class AircraftConflictGenerator:
|
|||||||
at=self._group_point(self.conflict.air_defenders_location))
|
at=self._group_point(self.conflict.air_defenders_location))
|
||||||
|
|
||||||
waypoint = group.add_waypoint(destination.position.random_point_within(0, 0), TRANSPORT_LANDING_ALT)
|
waypoint = group.add_waypoint(destination.position.random_point_within(0, 0), TRANSPORT_LANDING_ALT)
|
||||||
self.escort_targets.append((group, group.points.index(waypoint)))
|
if escort:
|
||||||
|
self.escort_targets.append((group, group.points.index(waypoint)))
|
||||||
group.task = Transport.name
|
group.task = Transport.name
|
||||||
group.land_at(destination)
|
group.land_at(destination)
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,9 @@ class Conflict:
|
|||||||
y = lerp * dy + self.tail.y
|
y = lerp * dy + self.tail.y
|
||||||
return Point(x, 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
|
@classmethod
|
||||||
def has_frontline_between(cls, from_cp: ControlPoint, to_cp: ControlPoint) -> bool:
|
def has_frontline_between(cls, from_cp: ControlPoint, to_cp: ControlPoint) -> bool:
|
||||||
return from_cp.has_frontline and to_cp.has_frontline
|
return from_cp.has_frontline and to_cp.has_frontline
|
||||||
@@ -190,7 +193,7 @@ class Conflict:
|
|||||||
return pos
|
return pos
|
||||||
|
|
||||||
@classmethod
|
@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
|
pos = initial
|
||||||
for _ in range(0, int(max_distance), 500):
|
for _ in range(0, int(max_distance), 500):
|
||||||
if theater.is_on_land(pos):
|
if theater.is_on_land(pos):
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ from .naming import *
|
|||||||
from dcs.mission import *
|
from dcs.mission import *
|
||||||
from dcs.statics import *
|
from dcs.statics import *
|
||||||
|
|
||||||
|
FARP_FRONTLINE_DISTANCE = 10000
|
||||||
|
|
||||||
|
|
||||||
CATEGORY_MAPPING = {
|
CATEGORY_MAPPING = {
|
||||||
"power": [Fortification.Workshop_A],
|
"power": [Fortification.Workshop_A],
|
||||||
@@ -20,11 +22,27 @@ CATEGORY_MAPPING = {
|
|||||||
|
|
||||||
|
|
||||||
class GroundObjectsGenerator:
|
class GroundObjectsGenerator:
|
||||||
|
FARP_CAPACITY = 4
|
||||||
|
|
||||||
def __init__(self, mission: Mission, conflict: Conflict, game):
|
def __init__(self, mission: Mission, conflict: Conflict, game):
|
||||||
self.m = mission
|
self.m = mission
|
||||||
self.conflict = conflict
|
self.conflict = conflict
|
||||||
self.game = game
|
self.game = game
|
||||||
|
|
||||||
|
def generate_farps(self, number_of_units=1) -> typing.Collection[StaticGroup]:
|
||||||
|
assert self.conflict.is_vector, "FARP could be generated only on frontline conflicts!"
|
||||||
|
|
||||||
|
for i, _ in enumerate(range(0, number_of_units, self.FARP_CAPACITY)):
|
||||||
|
heading = self.conflict.heading - 90
|
||||||
|
position = self.conflict.find_ground_position(self.conflict.center.point_from_heading(heading, FARP_FRONTLINE_DISTANCE), heading)
|
||||||
|
position = position.point_from_heading(0, i * 275)
|
||||||
|
|
||||||
|
yield self.m.farp(
|
||||||
|
country=self.m.country(self.game.player),
|
||||||
|
name="FARP",
|
||||||
|
position=position,
|
||||||
|
)
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
side = self.m.country(self.game.enemy)
|
side = self.m.country(self.game.enemy)
|
||||||
|
|
||||||
|
|||||||
@@ -72,32 +72,35 @@ class TriggersGenerator:
|
|||||||
for coalition_name, coalition in self.mission.coalition.items():
|
for coalition_name, coalition in self.mission.coalition.items():
|
||||||
for country in coalition.countries.values():
|
for country in coalition.countries.values():
|
||||||
if coalition_name == player_coalition:
|
if coalition_name == player_coalition:
|
||||||
for plane_group in country.plane_group + country.helicopter_group:
|
for group in country.plane_group + country.helicopter_group:
|
||||||
if plane_group.task == AWACS.name or plane_group.task == Refueling.name:
|
if group.task == AWACS.name or group.task == Refueling.name:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if player_cp.position.distance_to_point(group.position) > PUSH_TRIGGER_SIZE * 3:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
regroup_heading = self.conflict.to_cp.position.heading_between_point(player_cp.position)
|
regroup_heading = self.conflict.to_cp.position.heading_between_point(player_cp.position)
|
||||||
|
|
||||||
pos1 = plane_group.position.point_from_heading(regroup_heading, REGROUP_ZONE_DISTANCE)
|
pos1 = group.position.point_from_heading(regroup_heading, REGROUP_ZONE_DISTANCE)
|
||||||
pos2 = plane_group.position.point_from_heading(regroup_heading, REGROUP_ZONE_DISTANCE+5000)
|
pos2 = group.position.point_from_heading(regroup_heading, REGROUP_ZONE_DISTANCE+5000)
|
||||||
w1 = plane_group.add_waypoint(pos1, REGROUP_ALT)
|
w1 = group.add_waypoint(pos1, REGROUP_ALT)
|
||||||
w2 = plane_group.add_waypoint(pos2, REGROUP_ALT)
|
w2 = group.add_waypoint(pos2, REGROUP_ALT)
|
||||||
|
|
||||||
plane_group.points.remove(w1)
|
group.points.remove(w1)
|
||||||
plane_group.points.remove(w2)
|
group.points.remove(w2)
|
||||||
|
|
||||||
plane_group.points.insert(1, w2)
|
group.points.insert(1, w2)
|
||||||
plane_group.points.insert(1, w1)
|
group.points.insert(1, w1)
|
||||||
|
|
||||||
w1.tasks.append(Silence(True))
|
w1.tasks.append(Silence(True))
|
||||||
|
|
||||||
switch_waypoint_task = ControlledTask(SwitchWaypoint(from_waypoint=3, to_waypoint=2))
|
switch_waypoint_task = ControlledTask(SwitchWaypoint(from_waypoint=3, to_waypoint=2))
|
||||||
switch_waypoint_task.start_if_user_flag(1, False)
|
switch_waypoint_task.start_if_user_flag(1, False)
|
||||||
w2.tasks.append(switch_waypoint_task)
|
w2.tasks.append(switch_waypoint_task)
|
||||||
plane_group.points[3].tasks.append(Silence(False))
|
group.points[3].tasks.append(Silence(False))
|
||||||
|
|
||||||
plane_group.add_trigger_action(SwitchWaypoint(to_waypoint=4))
|
group.add_trigger_action(SwitchWaypoint(to_waypoint=4))
|
||||||
push_by_trigger.append(plane_group)
|
push_by_trigger.append(group)
|
||||||
|
|
||||||
push_trigger_zone = self.mission.triggers.add_triggerzone(player_cp.position, PUSH_TRIGGER_SIZE, name="Push zone")
|
push_trigger_zone = self.mission.triggers.add_triggerzone(player_cp.position, PUSH_TRIGGER_SIZE, name="Push zone")
|
||||||
push_trigger = TriggerOnce(Event.NoEvent, "Push trigger")
|
push_trigger = TriggerOnce(Event.NoEvent, "Push trigger")
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
BIN
resources/ui/terrain_caucasus.gif
Normal file
BIN
resources/ui/terrain_caucasus.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 852 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB |
BIN
resources/ui/terrain_nevada.gif
Normal file
BIN
resources/ui/terrain_nevada.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
BIN
resources/ui/terrain_pg.gif
Normal file
BIN
resources/ui/terrain_pg.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB |
Submodule submodules/dcs updated: fce769c41d...e2f8478c4e
@@ -140,7 +140,7 @@ class EventMenu(Menu):
|
|||||||
else:
|
else:
|
||||||
self.event.is_awacs_enabled = False
|
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]
|
units_scramble_counts = {} # type: typing.Dict[typing.Type[UnitType], int]
|
||||||
tasks_scramble_counts = {} # type: typing.Dict[typing.Type[Task], int]
|
tasks_scramble_counts = {} # type: typing.Dict[typing.Type[Task], int]
|
||||||
tasks_clients_counts = {} # type: typing.Dict[typing.Type[Task], int]
|
tasks_clients_counts = {} # type: typing.Dict[typing.Type[Task], int]
|
||||||
|
|||||||
@@ -86,17 +86,17 @@ class NewGameMenu(Menu):
|
|||||||
Radiobutton(terrain, variable=self.selected_terrain, value=0, **STYLES["radiobutton"]) \
|
Radiobutton(terrain, variable=self.selected_terrain, value=0, **STYLES["radiobutton"]) \
|
||||||
.grid(row=0, column=0, sticky=W)
|
.grid(row=0, column=0, sticky=W)
|
||||||
Label(terrain, text="Caucasus", **STYLES["widget"]).grid(row=0, column=1, sticky=W)
|
Label(terrain, text="Caucasus", **STYLES["widget"]).grid(row=0, column=1, sticky=W)
|
||||||
self.create_label_image(terrain, "terrain_caucasus.png").grid(row=0, column=2, padx=5)
|
self.create_label_image(terrain, "terrain_caucasus.gif").grid(row=0, column=2, padx=5)
|
||||||
|
|
||||||
Radiobutton(terrain, variable=self.selected_terrain, value=1, **STYLES["radiobutton"]) \
|
Radiobutton(terrain, variable=self.selected_terrain, value=1, **STYLES["radiobutton"]) \
|
||||||
.grid(row=1, column=0, sticky=W)
|
.grid(row=1, column=0, sticky=W)
|
||||||
Label(terrain, text="Nevada", **STYLES["widget"]).grid(row=1, column=1, sticky=W)
|
Label(terrain, text="Nevada", **STYLES["widget"]).grid(row=1, column=1, sticky=W)
|
||||||
self.create_label_image(terrain, "terrain_nevada.png").grid(row=1, column=2, padx=5)
|
self.create_label_image(terrain, "terrain_nevada.gif").grid(row=1, column=2, padx=5)
|
||||||
|
|
||||||
Radiobutton(terrain, variable=self.selected_terrain, value=2, **STYLES["radiobutton"]) \
|
Radiobutton(terrain, variable=self.selected_terrain, value=2, **STYLES["radiobutton"]) \
|
||||||
.grid(row=2, column=0, sticky=W)
|
.grid(row=2, column=0, sticky=W)
|
||||||
Label(terrain, text="Persian Gulf", **STYLES["widget"]).grid(row=2, column=1, sticky=W)
|
Label(terrain, text="Persian Gulf", **STYLES["widget"]).grid(row=2, column=1, sticky=W)
|
||||||
self.create_label_image(terrain, "terrain_pg.png").grid(row=2, column=2, padx=5)
|
self.create_label_image(terrain, "terrain_pg.gif").grid(row=2, column=2, padx=5)
|
||||||
|
|
||||||
Label(terrain, text="Currently strike missions are only\navailable for a number of airports only in Caucasus", **STYLES["widget"]) \
|
Label(terrain, text="Currently strike missions are only\navailable for a number of airports only in Caucasus", **STYLES["widget"]) \
|
||||||
.grid(row=3, column=0, columnspan=3, sticky=W)
|
.grid(row=3, column=0, columnspan=3, sticky=W)
|
||||||
|
|||||||
@@ -44,11 +44,8 @@ def restore_game():
|
|||||||
if not _save_file_exists():
|
if not _save_file_exists():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
with open(_save_file(), "rb") as f:
|
||||||
with open(_save_file(), "rb") as f:
|
return pickle.load(f)
|
||||||
return pickle.load(f)
|
|
||||||
except Exception as e:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
|
|
||||||
def save_game(game) -> bool:
|
def save_game(game) -> bool:
|
||||||
|
|||||||
Reference in New Issue
Block a user