mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
naval interceptions fixed; unit placement fixes
This commit is contained in:
parent
e2dbaa100f
commit
78ab7cadd4
16
game/db.py
16
game/db.py
@ -72,8 +72,10 @@ PRICES = {
|
|||||||
CV_1143_5_Admiral_Kuznetsov: 100,
|
CV_1143_5_Admiral_Kuznetsov: 100,
|
||||||
CVN_74_John_C__Stennis: 100,
|
CVN_74_John_C__Stennis: 100,
|
||||||
|
|
||||||
Bulk_cargo_ship_Yakushev: 100,
|
LHA_1_Tarawa: 30,
|
||||||
Dry_cargo_ship_Ivanov: 100,
|
Bulk_cargo_ship_Yakushev: 10,
|
||||||
|
Dry_cargo_ship_Ivanov: 10,
|
||||||
|
Tanker_Elnya_160: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
UNIT_BY_TASK = {
|
UNIT_BY_TASK = {
|
||||||
@ -135,7 +137,7 @@ UNIT_BY_TASK = {
|
|||||||
],
|
],
|
||||||
|
|
||||||
Carriage: [CVN_74_John_C__Stennis, CV_1143_5_Admiral_Kuznetsov, ],
|
Carriage: [CVN_74_John_C__Stennis, CV_1143_5_Admiral_Kuznetsov, ],
|
||||||
CargoTransportation: [Dry_cargo_ship_Ivanov, Bulk_cargo_ship_Yakushev],
|
CargoTransportation: [Dry_cargo_ship_Ivanov, Bulk_cargo_ship_Yakushev, Tanker_Elnya_160, LHA_1_Tarawa],
|
||||||
}
|
}
|
||||||
|
|
||||||
SAM_BAN = [
|
SAM_BAN = [
|
||||||
@ -193,6 +195,7 @@ UNIT_BY_COUNTRY = {
|
|||||||
CV_1143_5_Admiral_Kuznetsov,
|
CV_1143_5_Admiral_Kuznetsov,
|
||||||
Bulk_cargo_ship_Yakushev,
|
Bulk_cargo_ship_Yakushev,
|
||||||
Dry_cargo_ship_Ivanov,
|
Dry_cargo_ship_Ivanov,
|
||||||
|
Tanker_Elnya_160,
|
||||||
],
|
],
|
||||||
|
|
||||||
"USA": [
|
"USA": [
|
||||||
@ -220,15 +223,14 @@ UNIT_BY_COUNTRY = {
|
|||||||
AirDefence.SAM_Patriot_ICC,
|
AirDefence.SAM_Patriot_ICC,
|
||||||
|
|
||||||
CVN_74_John_C__Stennis,
|
CVN_74_John_C__Stennis,
|
||||||
# TODO: verify or find out proper USA cargo ship
|
LHA_1_Tarawa,
|
||||||
Bulk_cargo_ship_Yakushev,
|
|
||||||
Dry_cargo_ship_Ivanov,
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
PLANE_PAYLOAD_OVERRIDES = {
|
PLANE_PAYLOAD_OVERRIDES = {
|
||||||
FA_18C_hornet: {
|
FA_18C_hornet: {
|
||||||
"*": "AIM-9M*6, AIM-7M*2, FUEL*3",
|
Escort: "AIM-9M*6, AIM-7M*2, FUEL*3",
|
||||||
|
CAP: "AIM-9M*6, AIM-7M*2, FUEL*3",
|
||||||
},
|
},
|
||||||
|
|
||||||
# TODO: figure out a way to setup su33 loadout
|
# TODO: figure out a way to setup su33 loadout
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
from dcs.task import *
|
||||||
|
|
||||||
from game import db
|
from game import db
|
||||||
from game.operation.capture import CaptureOperation
|
from game.operation.capture import CaptureOperation
|
||||||
from userdata.debriefing import Debriefing
|
from userdata.debriefing import Debriefing
|
||||||
@ -29,8 +31,8 @@ class CaptureEvent(Event):
|
|||||||
return descr
|
return descr
|
||||||
|
|
||||||
def is_successfull(self, debriefing: Debriefing):
|
def is_successfull(self, debriefing: Debriefing):
|
||||||
alive_attackers = sum(debriefing.alive_units[self.attacker_name].values())
|
alive_attackers = sum([v for k, v in debriefing.alive_units[self.attacker_name].items() if db.unit_task(k) == PinpointStrike])
|
||||||
alive_defenders = sum(debriefing.alive_units[self.defender_name].values())
|
alive_defenders = sum([v for k, v in debriefing.alive_units[self.defender_name].items() if db.unit_task(k) == PinpointStrike])
|
||||||
attackers_success = alive_attackers > alive_defenders
|
attackers_success = alive_attackers > alive_defenders
|
||||||
if self.from_cp.captured:
|
if self.from_cp.captured:
|
||||||
return attackers_success
|
return attackers_success
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from dcs.task import *
|
|||||||
|
|
||||||
from game import *
|
from game import *
|
||||||
from game.event import *
|
from game.event import *
|
||||||
|
from game.operation.groundintercept import GroundInterceptOperation
|
||||||
from userdata.debriefing import Debriefing
|
from userdata.debriefing import Debriefing
|
||||||
|
|
||||||
|
|
||||||
@ -27,7 +28,10 @@ class GroundInterceptEvent(Event):
|
|||||||
if unit in self.targets:
|
if unit in self.targets:
|
||||||
destroyed_targets += count
|
destroyed_targets += count
|
||||||
|
|
||||||
return (float(destroyed_targets) / float(total_targets)) >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
if self.from_cp.captured:
|
||||||
|
return math.ceil(float(destroyed_targets) / total_targets) >= self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
||||||
|
else:
|
||||||
|
return math.ceil(float(destroyed_targets) / total_targets) < self.SUCCESS_TARGETS_HIT_PERCENTAGE
|
||||||
|
|
||||||
def commit(self, debriefing: Debriefing):
|
def commit(self, debriefing: Debriefing):
|
||||||
super(GroundInterceptEvent, self).commit(debriefing)
|
super(GroundInterceptEvent, self).commit(debriefing)
|
||||||
@ -38,13 +42,14 @@ class GroundInterceptEvent(Event):
|
|||||||
else:
|
else:
|
||||||
self.to_cp.base.affect_strength(+self.STRENGTH_INFLUENCE)
|
self.to_cp.base.affect_strength(+self.STRENGTH_INFLUENCE)
|
||||||
else:
|
else:
|
||||||
assert False
|
if self.is_successfull(debriefing):
|
||||||
|
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
|
||||||
|
else:
|
||||||
|
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
|
||||||
|
|
||||||
def skip(self):
|
def skip(self):
|
||||||
if not 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)
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def player_attacking(self, strikegroup: db.PlaneDict, clients: db.PlaneDict):
|
def player_attacking(self, strikegroup: db.PlaneDict, clients: db.PlaneDict):
|
||||||
suitable_unittypes = db.find_unittype(PinpointStrike, self.defender_name)
|
suitable_unittypes = db.find_unittype(PinpointStrike, self.defender_name)
|
||||||
@ -61,8 +66,31 @@ class GroundInterceptEvent(Event):
|
|||||||
from_cp=self.from_cp,
|
from_cp=self.from_cp,
|
||||||
to_cp=self.to_cp)
|
to_cp=self.to_cp)
|
||||||
op.setup(target=self.targets,
|
op.setup(target=self.targets,
|
||||||
strikegroup=strikegroup)
|
strikegroup=strikegroup,
|
||||||
|
interceptors={})
|
||||||
|
|
||||||
self.operation = op
|
self.operation = op
|
||||||
|
|
||||||
|
def player_defending(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
|
||||||
|
suitable_unittypes = db.find_unittype(PinpointStrike, 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}
|
||||||
|
|
||||||
|
op = GroundInterceptOperation(
|
||||||
|
self.game,
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
|
strikegroup = self.from_cp.base.scramble_cas()
|
||||||
|
op.setup(target=self.targets,
|
||||||
|
strikegroup=strikegroup,
|
||||||
|
interceptors=interceptors)
|
||||||
|
|
||||||
|
self.operation = op
|
||||||
|
|||||||
@ -14,13 +14,14 @@ from .event import Event
|
|||||||
|
|
||||||
class NavalInterceptEvent(Event):
|
class NavalInterceptEvent(Event):
|
||||||
STRENGTH_INFLUENCE = 0.3
|
STRENGTH_INFLUENCE = 0.3
|
||||||
|
SUCCESS_RATE = 0.5
|
||||||
|
|
||||||
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, IMPORTANCE_HIGH
|
||||||
factor = (self.to_cp.importance - IMPORTANCE_LOW) * 10
|
factor = (self.to_cp.importance - IMPORTANCE_LOW) * 10
|
||||||
return min(int(factor), 1)
|
return max(int(factor), 1)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return "Naval intercept at {}".format(self.to_cp)
|
return "Naval intercept at {}".format(self.to_cp)
|
||||||
@ -33,11 +34,16 @@ class NavalInterceptEvent(Event):
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
def is_successfull(self, debriefing: Debriefing):
|
def is_successfull(self, debriefing: Debriefing):
|
||||||
targets_destroyed = [c for t, c in debriefing.destroyed_units.items() if t in self.targets.values()]
|
total_targets = sum(self.targets.values())
|
||||||
|
destroyed_targets = 0
|
||||||
|
for unit, count in debriefing.destroyed_units[self.defender_name].items():
|
||||||
|
if unit in self.targets:
|
||||||
|
destroyed_targets += count
|
||||||
|
|
||||||
if self.from_cp.captured:
|
if self.from_cp.captured:
|
||||||
return targets_destroyed > 0
|
return math.ceil(float(destroyed_targets) / total_targets) > self.SUCCESS_RATE
|
||||||
else:
|
else:
|
||||||
return targets_destroyed == 0
|
return math.ceil(float(destroyed_targets) / total_targets) < self.SUCCESS_RATE
|
||||||
|
|
||||||
def commit(self, debriefing: Debriefing):
|
def commit(self, debriefing: Debriefing):
|
||||||
super(NavalInterceptEvent, self).commit(debriefing)
|
super(NavalInterceptEvent, self).commit(debriefing)
|
||||||
@ -88,8 +94,8 @@ class NavalInterceptEvent(Event):
|
|||||||
self.game,
|
self.game,
|
||||||
attacker_name=self.attacker_name,
|
attacker_name=self.attacker_name,
|
||||||
defender_name=self.defender_name,
|
defender_name=self.defender_name,
|
||||||
attacker_clients=clients,
|
attacker_clients={},
|
||||||
defender_clients={},
|
defender_clients=clients,
|
||||||
from_cp=self.from_cp,
|
from_cp=self.from_cp,
|
||||||
to_cp=self.to_cp
|
to_cp=self.to_cp
|
||||||
)
|
)
|
||||||
|
|||||||
29
game/game.py
29
game/game.py
@ -32,10 +32,12 @@ COMMISION_AMOUNTS_FACTORS = {
|
|||||||
ENEMY_INTERCEPT_PROBABILITY_BASE = 8
|
ENEMY_INTERCEPT_PROBABILITY_BASE = 8
|
||||||
ENEMY_INTERCEPT_GLOBAL_PROBABILITY_BASE = 5
|
ENEMY_INTERCEPT_GLOBAL_PROBABILITY_BASE = 5
|
||||||
ENEMY_CAPTURE_PROBABILITY_BASE = 4
|
ENEMY_CAPTURE_PROBABILITY_BASE = 4
|
||||||
|
ENEMY_GROUNDINTERCEPT_PROBABILITY_BASE = 8
|
||||||
|
ENEMY_NAVALINTERCEPT_PROBABILITY_BASE = 8
|
||||||
|
|
||||||
PLAYER_INTERCEPT_PROBABILITY_BASE = 35
|
PLAYER_INTERCEPT_PROBABILITY_BASE = 35
|
||||||
PLAYER_GROUNDINTERCEPT_PROBABILITY_BASE = 35
|
PLAYER_GROUNDINTERCEPT_PROBABILITY_BASE = 35
|
||||||
|
PLAYER_NAVALINTERCEPT_PROBABILITY_BASE = 35
|
||||||
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 25
|
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 25
|
||||||
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG = 2
|
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG = 2
|
||||||
|
|
||||||
@ -135,12 +137,21 @@ class Game:
|
|||||||
game=self))
|
game=self))
|
||||||
break
|
break
|
||||||
|
|
||||||
|
for from_cp, to_cp in self.theater.conflicts(False):
|
||||||
|
if self._roll(ENEMY_GROUNDINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||||
|
self.events.append(GroundInterceptEvent(attacker_name=self.enemy,
|
||||||
|
defender_name=self.player,
|
||||||
|
from_cp=from_cp,
|
||||||
|
to_cp=to_cp,
|
||||||
|
game=self))
|
||||||
|
break
|
||||||
|
|
||||||
def _generate_navalinterceptions(self):
|
def _generate_navalinterceptions(self):
|
||||||
for from_cp, to_cp in self.theater.conflicts(True):
|
for from_cp, to_cp in self.theater.conflicts(True):
|
||||||
if to_cp.radials == ALL_RADIALS:
|
if to_cp.radials == LAND:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self._roll(100, from_cp.base.strength):
|
if self._roll(PLAYER_NAVALINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||||
self.events.append(NavalInterceptEvent(attacker_name=self.player,
|
self.events.append(NavalInterceptEvent(attacker_name=self.player,
|
||||||
defender_name=self.enemy,
|
defender_name=self.enemy,
|
||||||
from_cp=from_cp,
|
from_cp=from_cp,
|
||||||
@ -148,6 +159,18 @@ class Game:
|
|||||||
game=self))
|
game=self))
|
||||||
break
|
break
|
||||||
|
|
||||||
|
for from_cp, to_cp in self.theater.conflicts(False):
|
||||||
|
if to_cp.radials == LAND:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if self._roll(ENEMY_NAVALINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||||
|
self.events.append(NavalInterceptEvent(attacker_name=self.enemy,
|
||||||
|
defender_name=self.player,
|
||||||
|
from_cp=from_cp,
|
||||||
|
to_cp=to_cp,
|
||||||
|
game=self))
|
||||||
|
break
|
||||||
|
|
||||||
def _generate_globalinterceptions(self):
|
def _generate_globalinterceptions(self):
|
||||||
global_count = len([x for x in self.theater.player_points() if x.is_global])
|
global_count = len([x for x in self.theater.player_points() if x.is_global])
|
||||||
for from_cp in [x for x in self.theater.player_points() if x.is_global]:
|
for from_cp in [x for x in self.theater.player_points() if x.is_global]:
|
||||||
|
|||||||
@ -44,7 +44,8 @@ class CaptureOperation(Operation):
|
|||||||
attacker=self.mission.country(self.attacker_name),
|
attacker=self.mission.country(self.attacker_name),
|
||||||
defender=self.mission.country(self.defender_name),
|
defender=self.mission.country(self.defender_name),
|
||||||
from_cp=self.from_cp,
|
from_cp=self.from_cp,
|
||||||
to_cp=self.to_cp
|
to_cp=self.to_cp,
|
||||||
|
theater=self.game.theater
|
||||||
)
|
)
|
||||||
self.initialize(mission=self.mission,
|
self.initialize(mission=self.mission,
|
||||||
conflict=conflict)
|
conflict=conflict)
|
||||||
|
|||||||
@ -13,20 +13,31 @@ from gen.conflictgen import Conflict
|
|||||||
from .operation import Operation
|
from .operation import Operation
|
||||||
|
|
||||||
class GroundInterceptOperation(Operation):
|
class GroundInterceptOperation(Operation):
|
||||||
|
strikegroup = None # type: db.PlaneDict
|
||||||
|
interceptors = None # type: db.PlaneDict
|
||||||
|
target = None # type: db.ArmorDict
|
||||||
|
|
||||||
def setup(self,
|
def setup(self,
|
||||||
target: db.ArmorDict,
|
target: db.ArmorDict,
|
||||||
strikegroup: db.PlaneDict):
|
strikegroup: db.PlaneDict,
|
||||||
|
interceptors: db.PlaneDict):
|
||||||
self.strikegroup = strikegroup
|
self.strikegroup = strikegroup
|
||||||
|
self.interceptors = interceptors
|
||||||
self.target = target
|
self.target = target
|
||||||
|
|
||||||
def prepare(self, terrain: Terrain, is_quick: bool):
|
def prepare(self, terrain: Terrain, is_quick: bool):
|
||||||
super(GroundInterceptOperation, self).prepare(terrain, is_quick)
|
super(GroundInterceptOperation, self).prepare(terrain, is_quick)
|
||||||
|
if self.defender_name == self.game.player:
|
||||||
|
self.attackers_starting_position = None
|
||||||
|
self.defenders_starting_position = None
|
||||||
|
|
||||||
conflict = Conflict.ground_intercept_conflict(
|
conflict = Conflict.ground_intercept_conflict(
|
||||||
attacker=self.mission.country(self.attacker_name),
|
attacker=self.mission.country(self.attacker_name),
|
||||||
defender=self.mission.country(self.defender_name),
|
defender=self.mission.country(self.defender_name),
|
||||||
heading=self.to_cp.position.heading_between_point(self.from_cp.position),
|
heading=self.to_cp.position.heading_between_point(self.from_cp.position),
|
||||||
from_cp=self.from_cp,
|
from_cp=self.from_cp,
|
||||||
to_cp=self.to_cp
|
to_cp=self.to_cp,
|
||||||
|
theater=self.game.theater
|
||||||
)
|
)
|
||||||
|
|
||||||
self.initialize(mission=self.mission,
|
self.initialize(mission=self.mission,
|
||||||
@ -34,6 +45,9 @@ class GroundInterceptOperation(Operation):
|
|||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
self.airgen.generate_cas_strikegroup(self.strikegroup, clients=self.attacker_clients, at=self.attackers_starting_position)
|
self.airgen.generate_cas_strikegroup(self.strikegroup, clients=self.attacker_clients, at=self.attackers_starting_position)
|
||||||
self.armorgen.generate({}, self.target)
|
|
||||||
|
|
||||||
|
if self.interceptors:
|
||||||
|
self.airgen.generate_defense(self.interceptors, clients=self.defender_clients, at=self.defenders_starting_position)
|
||||||
|
|
||||||
|
self.armorgen.generate({}, self.target)
|
||||||
super(GroundInterceptOperation, self).generate()
|
super(GroundInterceptOperation, self).generate()
|
||||||
|
|||||||
@ -30,7 +30,8 @@ class InterceptOperation(Operation):
|
|||||||
attacker=self.mission.country(self.attacker_name),
|
attacker=self.mission.country(self.attacker_name),
|
||||||
defender=self.mission.country(self.defender_name),
|
defender=self.mission.country(self.defender_name),
|
||||||
from_cp=self.from_cp,
|
from_cp=self.from_cp,
|
||||||
to_cp=self.to_cp
|
to_cp=self.to_cp,
|
||||||
|
theater=self.game.theater
|
||||||
)
|
)
|
||||||
|
|
||||||
self.initialize(mission=self.mission,
|
self.initialize(mission=self.mission,
|
||||||
|
|||||||
@ -19,13 +19,15 @@ class NavalInterceptionOperation(Operation):
|
|||||||
|
|
||||||
def prepare(self, terrain: Terrain, is_quick: bool):
|
def prepare(self, terrain: Terrain, is_quick: bool):
|
||||||
super(NavalInterceptionOperation, self).prepare(terrain, is_quick)
|
super(NavalInterceptionOperation, self).prepare(terrain, is_quick)
|
||||||
|
if self.defender_name == self.game.player:
|
||||||
|
self.attackers_starting_position = None
|
||||||
|
|
||||||
conflict = Conflict.naval_intercept_conflict(
|
conflict = Conflict.naval_intercept_conflict(
|
||||||
attacker=self.mission.country(self.attacker_name),
|
attacker=self.mission.country(self.attacker_name),
|
||||||
defender=self.mission.country(self.defender_name),
|
defender=self.mission.country(self.defender_name),
|
||||||
theater=self.game.theater,
|
|
||||||
from_cp=self.from_cp,
|
from_cp=self.from_cp,
|
||||||
to_cp=self.to_cp
|
to_cp=self.to_cp,
|
||||||
|
theater=self.game.theater
|
||||||
)
|
)
|
||||||
|
|
||||||
self.initialize(self.mission, conflict)
|
self.initialize(self.mission, conflict)
|
||||||
@ -33,17 +35,18 @@ class NavalInterceptionOperation(Operation):
|
|||||||
def generate(self):
|
def generate(self):
|
||||||
super(NavalInterceptionOperation, self).generate()
|
super(NavalInterceptionOperation, self).generate()
|
||||||
|
|
||||||
|
target_groups = self.shipgen.generate_cargo(units=self.targets)
|
||||||
|
|
||||||
self.airgen.generate_ship_strikegroup(
|
self.airgen.generate_ship_strikegroup(
|
||||||
attackers= self.strikegroup,
|
attackers=self.strikegroup,
|
||||||
clients=self.attacker_clients,
|
clients=self.attacker_clients,
|
||||||
|
target_groups=target_groups,
|
||||||
at=self.attackers_starting_position
|
at=self.attackers_starting_position
|
||||||
)
|
)
|
||||||
|
|
||||||
self.airgen.generate_interception(
|
if self.interceptors:
|
||||||
interceptors=self.interceptors,
|
self.airgen.generate_defense(
|
||||||
clients=self.defender_clients,
|
defenders=self.interceptors,
|
||||||
at=self.defenders_starting_position
|
clients=self.defender_clients,
|
||||||
)
|
at=self.defenders_starting_position
|
||||||
|
)
|
||||||
self.shipgen.generate_cargo(units=self.targets)
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ from .naming import *
|
|||||||
|
|
||||||
from dcs.mission import *
|
from dcs.mission import *
|
||||||
|
|
||||||
DISTANCE_FACTOR = 2, 4
|
DISTANCE_FACTOR = 0.5, 1
|
||||||
EXTRA_AA_MIN_DISTANCE = 35000
|
EXTRA_AA_MIN_DISTANCE = 35000
|
||||||
EXTRA_AA_POSITION_FROM_CP = 550
|
EXTRA_AA_POSITION_FROM_CP = 550
|
||||||
|
|
||||||
|
|||||||
@ -195,7 +195,7 @@ class AircraftConflictGenerator:
|
|||||||
|
|
||||||
group.add_waypoint(self.conflict.from_cp.position, RTB_ALTITUDE)
|
group.add_waypoint(self.conflict.from_cp.position, RTB_ALTITUDE)
|
||||||
|
|
||||||
def generate_ship_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
|
def generate_ship_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, target_groups: typing.Collection[ShipGroup], at: db.StartingPosition = None):
|
||||||
assert len(self.escort_targets) == 0
|
assert 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):
|
||||||
@ -208,7 +208,10 @@ class AircraftConflictGenerator:
|
|||||||
at=at and at or self._group_point(self.conflict.air_attackers_location))
|
at=at and at or self._group_point(self.conflict.air_attackers_location))
|
||||||
self.escort_targets.append(group)
|
self.escort_targets.append(group)
|
||||||
|
|
||||||
group.add_waypoint(self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
|
wayp = group.add_waypoint(self.conflict.position, CAS_ALTITUDE, WARM_START_AIRSPEED)
|
||||||
|
for target_group in target_groups:
|
||||||
|
wayp.tasks.append(AttackGroup(target_group.id))
|
||||||
|
|
||||||
group.task = AntishipStrike.name
|
group.task = AntishipStrike.name
|
||||||
self._setup_group(group, AntishipStrike, clients)
|
self._setup_group(group, AntishipStrike, clients)
|
||||||
|
|
||||||
|
|||||||
@ -17,8 +17,8 @@ from dcs.country import *
|
|||||||
from theater import *
|
from theater import *
|
||||||
|
|
||||||
|
|
||||||
GROUND_DISTANCE_FACTOR = 0.8
|
GROUND_DISTANCE_FACTOR = 1
|
||||||
GROUNDINTERCEPT_DISTANCE_FACTOR = 3
|
GROUNDINTERCEPT_DISTANCE_FACTOR = 6
|
||||||
AIR_DISTANCE = 32000
|
AIR_DISTANCE = 32000
|
||||||
|
|
||||||
INTERCEPT_ATTACKERS_HEADING = -45, 45
|
INTERCEPT_ATTACKERS_HEADING = -45, 45
|
||||||
@ -29,6 +29,7 @@ INTERCEPT_MAX_DISTANCE = 80000
|
|||||||
INTERCEPT_MIN_DISTANCE = 45000
|
INTERCEPT_MIN_DISTANCE = 45000
|
||||||
|
|
||||||
NAVAL_INTERCEPT_DISTANCE_FACTOR = 1.3
|
NAVAL_INTERCEPT_DISTANCE_FACTOR = 1.3
|
||||||
|
NAVAL_INTERCEPT_DISTANCE_MAX = 90000
|
||||||
NAVAL_INTERCEPT_STEP = 3000
|
NAVAL_INTERCEPT_STEP = 3000
|
||||||
|
|
||||||
|
|
||||||
@ -60,96 +61,148 @@ class Conflict:
|
|||||||
air_attackers_location = None # type: Point
|
air_attackers_location = None # type: Point
|
||||||
air_defenders_location = None # type: Point
|
air_defenders_location = None # type: Point
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
position: Point,
|
||||||
|
theater: ConflictTheater,
|
||||||
|
from_cp: ControlPoint,
|
||||||
|
to_cp: ControlPoint,
|
||||||
|
attackers_side: Country,
|
||||||
|
defenders_side: Country,
|
||||||
|
ground_attackers_location: Point,
|
||||||
|
ground_defenders_location: Point,
|
||||||
|
air_attackers_location: Point,
|
||||||
|
air_defenders_location: Point):
|
||||||
|
self.attackers_side = attackers_side
|
||||||
|
self.defenders_side = defenders_side
|
||||||
|
self.from_cp = from_cp
|
||||||
|
self.to_cp = to_cp
|
||||||
|
self.theater = theater
|
||||||
|
self.position = position
|
||||||
|
self.size = to_cp.size
|
||||||
|
self.radials = to_cp.radials
|
||||||
|
self.ground_attackers_location = ground_attackers_location
|
||||||
|
self.ground_defenders_location = ground_defenders_location
|
||||||
|
self.air_attackers_location = air_attackers_location
|
||||||
|
self.air_defenders_location = air_defenders_location
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def capture_conflict(self, attacker: Country, defender: Country, from_cp, to_cp):
|
def _find_ground_location(cls, initial: Point, max_distance: int, heading: int, theater: ConflictTheater) -> Point:
|
||||||
|
for _ in range(0, int(max_distance), 100):
|
||||||
|
if theater.is_on_land(initial):
|
||||||
|
return initial
|
||||||
|
|
||||||
|
initial = initial.point_from_heading(heading, 100)
|
||||||
|
return initial
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def capture_conflict(cls, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||||
|
position = to_cp.position
|
||||||
attack_heading = to_cp.find_radial(to_cp.position.heading_between_point(from_cp.position))
|
attack_heading = to_cp.find_radial(to_cp.position.heading_between_point(from_cp.position))
|
||||||
defense_heading = to_cp.find_radial(from_cp.position.heading_between_point(to_cp.position), ignored_radial=attack_heading)
|
defense_heading = to_cp.find_radial(from_cp.position.heading_between_point(to_cp.position), ignored_radial=attack_heading)
|
||||||
position = to_cp.position
|
|
||||||
|
|
||||||
instance = self()
|
distance = to_cp.size * GROUND_DISTANCE_FACTOR
|
||||||
instance.attackers_side = attacker
|
attackers_location = position.point_from_heading(attack_heading, distance)
|
||||||
instance.defenders_side = defender
|
attackers_location = Conflict._find_ground_location(attackers_location, distance * 2, _heading_sum(attack_heading, 180), theater)
|
||||||
instance.from_cp = from_cp
|
|
||||||
instance.to_cp = to_cp
|
|
||||||
instance.position = position
|
|
||||||
instance.size = to_cp.size
|
|
||||||
instance.radials = to_cp.radials
|
|
||||||
|
|
||||||
instance.ground_attackers_location = instance.position.point_from_heading(attack_heading, instance.size * GROUND_DISTANCE_FACTOR)
|
defenders_location = position.point_from_heading(defense_heading, distance)
|
||||||
instance.ground_defenders_location = instance.position.point_from_heading(defense_heading, instance.size * GROUND_DISTANCE_FACTOR)
|
defenders_location = Conflict._find_ground_location(defenders_location, distance * 2, _heading_sum(defense_heading, 180), theater)
|
||||||
|
|
||||||
instance.air_attackers_location = instance.position.point_from_heading(attack_heading, AIR_DISTANCE)
|
return cls(
|
||||||
instance.air_defenders_location = instance.position.point_from_heading(defense_heading, AIR_DISTANCE)
|
position=position,
|
||||||
|
theater=theater,
|
||||||
return instance
|
from_cp=from_cp,
|
||||||
|
to_cp=to_cp,
|
||||||
|
attackers_side=attacker,
|
||||||
|
defenders_side=defender,
|
||||||
|
ground_attackers_location=attackers_location,
|
||||||
|
ground_defenders_location=defenders_location,
|
||||||
|
air_attackers_location=position.point_from_heading(attack_heading, AIR_DISTANCE),
|
||||||
|
air_defenders_location=position.point_from_heading(defense_heading, AIR_DISTANCE)
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def intercept_conflict(self, attacker: Country, defender: Country, from_cp, to_cp):
|
def intercept_conflict(cls, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||||
from theater.conflicttheater import SIZE_REGULAR
|
|
||||||
from theater.conflicttheater import ALL_RADIALS
|
|
||||||
|
|
||||||
heading = _heading_sum(from_cp.position.heading_between_point(to_cp.position), random.choice([-1, 1]) * random.randint(60, 100))
|
|
||||||
|
|
||||||
raw_distance = from_cp.position.distance_to_point(to_cp.position) * 0.4
|
raw_distance = from_cp.position.distance_to_point(to_cp.position) * 0.4
|
||||||
distance = max(min(raw_distance, INTERCEPT_MAX_DISTANCE), INTERCEPT_MIN_DISTANCE)
|
distance = max(min(raw_distance, INTERCEPT_MAX_DISTANCE), INTERCEPT_MIN_DISTANCE)
|
||||||
|
|
||||||
|
heading = _heading_sum(from_cp.position.heading_between_point(to_cp.position), random.choice([-1, 1]) * random.randint(60, 100))
|
||||||
position = from_cp.position.point_from_heading(heading, distance)
|
position = from_cp.position.point_from_heading(heading, distance)
|
||||||
|
|
||||||
instance = self()
|
return cls(
|
||||||
instance.from_cp = from_cp
|
position=position,
|
||||||
instance.to_cp = to_cp
|
theater=theater,
|
||||||
instance.attackers_side = attacker
|
from_cp=from_cp,
|
||||||
instance.defenders_side = defender
|
to_cp=to_cp,
|
||||||
|
attackers_side=attacker,
|
||||||
instance.position = position
|
defenders_side=defender,
|
||||||
instance.size = SIZE_REGULAR
|
ground_attackers_location=None,
|
||||||
instance.radials = ALL_RADIALS
|
ground_defenders_location=None,
|
||||||
|
air_attackers_location=position.point_from_heading(random.randint(*INTERCEPT_ATTACKERS_HEADING) + heading, INTERCEPT_ATTACKERS_DISTANCE),
|
||||||
instance.air_attackers_location = instance.position.point_from_heading(random.randint(*INTERCEPT_ATTACKERS_HEADING) + heading, INTERCEPT_ATTACKERS_DISTANCE)
|
air_defenders_location=position
|
||||||
instance.air_defenders_location = instance.position
|
)
|
||||||
|
|
||||||
return instance
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def ground_intercept_conflict(self, attacker: Country, defender: Country, heading: int, from_cp, to_cp):
|
def ground_intercept_conflict(cls, attacker: Country, defender: Country, heading: int, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||||
instance = self()
|
heading = random.choice(to_cp.radials)
|
||||||
instance.from_cp = from_cp
|
initial_location = to_cp.position.point_from_heading(heading, to_cp.size * GROUNDINTERCEPT_DISTANCE_FACTOR),
|
||||||
instance.to_cp = to_cp
|
max_distance = to_cp.size * GROUNDINTERCEPT_DISTANCE_FACTOR
|
||||||
instance.attackers_side = attacker
|
ground_location = Conflict._find_ground_location(initial_location, max_distance, _heading_sum(heading, 180), theater)
|
||||||
instance.defenders_side = defender
|
|
||||||
|
|
||||||
instance.position = to_cp.position
|
return cls(
|
||||||
instance.size = to_cp.size
|
position=to_cp.position,
|
||||||
instance.radials = to_cp.radials
|
theater=theater,
|
||||||
|
from_cp=from_cp,
|
||||||
instance.air_attackers_location = instance.position.point_from_heading(random.randint(*INTERCEPT_ATTACKERS_HEADING) + heading, AIR_DISTANCE)
|
to_cp=to_cp,
|
||||||
instance.ground_defenders_location = instance.position.point_from_heading(random.choice(to_cp.radials), instance.size * GROUNDINTERCEPT_DISTANCE_FACTOR)
|
attackers_side=attacker,
|
||||||
|
defenders_side=defender,
|
||||||
return instance
|
ground_attackers_location=None,
|
||||||
|
ground_defenders_location=ground_location,
|
||||||
|
air_attackers_location=to_cp.position.point_from_heading(random.randint(*INTERCEPT_ATTACKERS_HEADING) + heading, AIR_DISTANCE),
|
||||||
|
air_defenders_location=to_cp.position.point_from_heading(random.randint(*INTERCEPT_ATTACKERS_HEADING) + _opposite_heading(heading), AIR_DISTANCE)
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def naval_intercept_conflict(cls, attacker: Country, defender: Country, theater: ConflictTheater, from_cp: ControlPoint, to_cp: ControlPoint):
|
def intercept_conflict(cls, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||||
|
raw_distance = from_cp.position.distance_to_point(to_cp.position) * 0.4
|
||||||
|
distance = max(min(raw_distance, INTERCEPT_MAX_DISTANCE), INTERCEPT_MIN_DISTANCE)
|
||||||
|
|
||||||
|
heading = _heading_sum(from_cp.position.heading_between_point(to_cp.position), random.choice([-1, 1]) * random.randint(60, 100))
|
||||||
|
position = from_cp.position.point_from_heading(heading, distance)
|
||||||
|
|
||||||
|
return cls(
|
||||||
|
position=position,
|
||||||
|
theater=theater,
|
||||||
|
from_cp=from_cp,
|
||||||
|
to_cp=to_cp,
|
||||||
|
attackers_side=attacker,
|
||||||
|
defenders_side=defender,
|
||||||
|
ground_attackers_location=None,
|
||||||
|
ground_defenders_location=None,
|
||||||
|
air_attackers_location=position.point_from_heading(random.randint(*INTERCEPT_ATTACKERS_HEADING) + heading, INTERCEPT_ATTACKERS_DISTANCE),
|
||||||
|
air_defenders_location=position
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def naval_intercept_conflict(cls, attacker: Country, defender: Country, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater):
|
||||||
radial = random.choice(to_cp.sea_radials)
|
radial = random.choice(to_cp.sea_radials)
|
||||||
|
|
||||||
initial_distance = int(from_cp.position.distance_to_point(to_cp.position) * NAVAL_INTERCEPT_DISTANCE_FACTOR)
|
initial_distance = min(int(from_cp.position.distance_to_point(to_cp.position) * NAVAL_INTERCEPT_DISTANCE_FACTOR), NAVAL_INTERCEPT_DISTANCE_MAX)
|
||||||
position = to_cp.position.point_from_heading(radial, initial_distance)
|
position = to_cp.position.point_from_heading(radial, initial_distance)
|
||||||
for offset in range(0, initial_distance, NAVAL_INTERCEPT_STEP):
|
for offset in range(0, initial_distance, NAVAL_INTERCEPT_STEP):
|
||||||
if theater.is_on_land(position):
|
if not theater.is_on_land(position):
|
||||||
|
position = to_cp.position.point_from_heading(radial, initial_distance - offset)
|
||||||
break
|
break
|
||||||
else:
|
|
||||||
position = to_cp.position.point_from_heading(radial, offset)
|
|
||||||
|
|
||||||
instance = cls()
|
|
||||||
instance.from_cp = from_cp
|
|
||||||
instance.to_cp = to_cp
|
|
||||||
instance.attackers_side = attacker
|
|
||||||
instance.defenders_side = defender
|
|
||||||
|
|
||||||
instance.position = position
|
|
||||||
instance.size = SIZE_REGULAR
|
|
||||||
instance.radials = to_cp.radials
|
|
||||||
|
|
||||||
attacker_heading = from_cp.position.heading_between_point(to_cp.position)
|
attacker_heading = from_cp.position.heading_between_point(to_cp.position)
|
||||||
instance.air_attackers_location = instance.position.point_from_heading(attacker_heading, AIR_DISTANCE)
|
return cls(
|
||||||
instance.air_defenders_location = instance.position.point_from_heading(_opposite_heading(attacker_heading), AIR_DISTANCE)
|
position=position,
|
||||||
|
theater=theater,
|
||||||
return instance
|
from_cp=from_cp,
|
||||||
|
to_cp=to_cp,
|
||||||
|
attackers_side=attacker,
|
||||||
|
defenders_side=defender,
|
||||||
|
ground_attackers_location=None,
|
||||||
|
ground_defenders_location=position,
|
||||||
|
air_attackers_location=position.point_from_heading(attacker_heading, AIR_DISTANCE),
|
||||||
|
air_defenders_location=position.point_from_heading(_opposite_heading(attacker_heading), AIR_DISTANCE)
|
||||||
|
)
|
||||||
|
|||||||
@ -28,7 +28,7 @@ class ShipGenerator:
|
|||||||
country=self.conflict.defenders_side,
|
country=self.conflict.defenders_side,
|
||||||
name=namegen.next_transport_group_name(),
|
name=namegen.next_transport_group_name(),
|
||||||
_type=unit_type,
|
_type=unit_type,
|
||||||
position=self.conflict.position.random_point_within(SHIP_RANDOM_SPREAD, SHIP_RANDOM_SPREAD),
|
position=self.conflict.ground_defenders_location.random_point_within(SHIP_RANDOM_SPREAD, SHIP_RANDOM_SPREAD),
|
||||||
group_size=unit_count,
|
group_size=unit_count,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@ -4,11 +4,11 @@ from dcs.mission import Mission
|
|||||||
from dcs.terrain import PersianGulf
|
from dcs.terrain import PersianGulf
|
||||||
|
|
||||||
m = Mission()
|
m = Mission()
|
||||||
m.load_file("./gulf_terrain.miz")
|
m.load_file("tools/cau_terrain.miz")
|
||||||
|
|
||||||
landmap = []
|
landmap = []
|
||||||
for plane_group in m.country("USA").plane_group:
|
for plane_group in m.country("USA").plane_group:
|
||||||
landmap.append([(x.position.x, x.position.y) for x in plane_group.points])
|
landmap.append([(x.position.x, x.position.y) for x in plane_group.points])
|
||||||
|
|
||||||
with open("gulflandmap.p", "wb") as f:
|
with open("./caulandmap.p", "wb") as f:
|
||||||
pickle.dump(landmap, f)
|
pickle.dump(landmap, f)
|
||||||
|
|||||||
@ -99,7 +99,7 @@ class Base:
|
|||||||
|
|
||||||
def filter_units(self, applicable_units: typing.Collection):
|
def filter_units(self, applicable_units: typing.Collection):
|
||||||
self.aircraft = {k: v for k, v in self.aircraft.items() if k in applicable_units}
|
self.aircraft = {k: v for k, v in self.aircraft.items() if k in applicable_units}
|
||||||
self.armor = {k: v for k, v in self.aircraft.items() if k in applicable_units}
|
self.armor = {k: v for k, v in self.armor.items() if k in applicable_units}
|
||||||
|
|
||||||
def commision_units(self, units: typing.Dict[typing.Any, int]):
|
def commision_units(self, units: typing.Dict[typing.Any, int]):
|
||||||
for value in units.values():
|
for value in units.values():
|
||||||
|
|||||||
@ -19,26 +19,26 @@ class CaucasusTheater(ConflictTheater):
|
|||||||
"night": (0, 5),
|
"night": (0, 5),
|
||||||
}
|
}
|
||||||
|
|
||||||
soganlug = ControlPoint.from_airport(caucasus.Soganlug, ALL_RADIALS, SIZE_SMALL, IMPORTANCE_LOW)
|
soganlug = ControlPoint.from_airport(caucasus.Soganlug, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
kutaisi = ControlPoint.from_airport(caucasus.Kutaisi, ALL_RADIALS, SIZE_SMALL, IMPORTANCE_LOW)
|
kutaisi = ControlPoint.from_airport(caucasus.Kutaisi, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
senaki = ControlPoint.from_airport(caucasus.Senaki_Kolkhi, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_LOW)
|
senaki = ControlPoint.from_airport(caucasus.Senaki_Kolkhi, LAND, SIZE_REGULAR, IMPORTANCE_LOW)
|
||||||
kobuleti = ControlPoint.from_airport(caucasus.Kobuleti, COAST_NS_E, SIZE_SMALL, IMPORTANCE_LOW)
|
kobuleti = ControlPoint.from_airport(caucasus.Kobuleti, COAST_A_E, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
batumi = ControlPoint.from_airport(caucasus.Batumi, COAST_NS_E, SIZE_SMALL, IMPORTANCE_MEDIUM)
|
batumi = ControlPoint.from_airport(caucasus.Batumi, COAST_DL_E, SIZE_SMALL, IMPORTANCE_MEDIUM)
|
||||||
sukhumi = ControlPoint.from_airport(caucasus.Sukhumi_Babushara, COAST_NS_E, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
sukhumi = ControlPoint.from_airport(caucasus.Sukhumi_Babushara, COAST_DR_E, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
||||||
gudauta = ControlPoint.from_airport(caucasus.Gudauta, COAST_NS_E, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
gudauta = ControlPoint.from_airport(caucasus.Gudauta, COAST_DR_E, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
||||||
sochi = ControlPoint.from_airport(caucasus.Sochi_Adler, COAST_NS_E, SIZE_BIG, IMPORTANCE_HIGH)
|
sochi = ControlPoint.from_airport(caucasus.Sochi_Adler, COAST_DR_E, SIZE_BIG, IMPORTANCE_HIGH)
|
||||||
|
|
||||||
gelendzhik = ControlPoint.from_airport(caucasus.Gelendzhik, COAST_NS_E, SIZE_BIG, IMPORTANCE_MEDIUM)
|
gelendzhik = ControlPoint.from_airport(caucasus.Gelendzhik, COAST_DR_E, SIZE_BIG, IMPORTANCE_MEDIUM)
|
||||||
maykop = ControlPoint.from_airport(caucasus.Maykop_Khanskaya, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH)
|
maykop = ControlPoint.from_airport(caucasus.Maykop_Khanskaya, LAND, SIZE_LARGE, IMPORTANCE_HIGH)
|
||||||
krasnodar = ControlPoint.from_airport(caucasus.Krasnodar_Center, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH)
|
krasnodar = ControlPoint.from_airport(caucasus.Krasnodar_Center, LAND, SIZE_LARGE, IMPORTANCE_HIGH)
|
||||||
novorossiysk = ControlPoint.from_airport(caucasus.Novorossiysk, COAST_NS_E, SIZE_BIG, IMPORTANCE_MEDIUM)
|
novorossiysk = ControlPoint.from_airport(caucasus.Novorossiysk, COAST_DR_E, SIZE_BIG, IMPORTANCE_MEDIUM)
|
||||||
krymsk = ControlPoint.from_airport(caucasus.Krymsk, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH)
|
krymsk = ControlPoint.from_airport(caucasus.Krymsk, LAND, SIZE_LARGE, IMPORTANCE_HIGH)
|
||||||
anapa = ControlPoint.from_airport(caucasus.Anapa_Vityazevo, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH)
|
anapa = ControlPoint.from_airport(caucasus.Anapa_Vityazevo, LAND, SIZE_LARGE, IMPORTANCE_HIGH)
|
||||||
|
|
||||||
beslan = ControlPoint.from_airport(caucasus.Beslan, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_LOW)
|
beslan = ControlPoint.from_airport(caucasus.Beslan, LAND, SIZE_REGULAR, IMPORTANCE_LOW)
|
||||||
nalchik = ControlPoint.from_airport(caucasus.Nalchik, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_LOW)
|
nalchik = ControlPoint.from_airport(caucasus.Nalchik, LAND, SIZE_REGULAR, IMPORTANCE_LOW)
|
||||||
mineralnye = ControlPoint.from_airport(caucasus.Mineralnye_Vody, ALL_RADIALS, SIZE_BIG, IMPORTANCE_MEDIUM)
|
mineralnye = ControlPoint.from_airport(caucasus.Mineralnye_Vody, LAND, SIZE_BIG, IMPORTANCE_MEDIUM)
|
||||||
mozdok = ControlPoint.from_airport(caucasus.Mozdok, ALL_RADIALS, SIZE_BIG, IMPORTANCE_MEDIUM)
|
mozdok = ControlPoint.from_airport(caucasus.Mozdok, LAND, SIZE_BIG, IMPORTANCE_MEDIUM)
|
||||||
|
|
||||||
carrier_1 = ControlPoint.carrier("Carrier", mapping.Point(-305810.6875, 406399.1875))
|
carrier_1 = ControlPoint.carrier("Carrier", mapping.Point(-305810.6875, 406399.1875))
|
||||||
|
|
||||||
|
|||||||
@ -17,15 +17,32 @@ IMPORTANCE_LOW = 1
|
|||||||
IMPORTANCE_MEDIUM = 1.2
|
IMPORTANCE_MEDIUM = 1.2
|
||||||
IMPORTANCE_HIGH = 1.4
|
IMPORTANCE_HIGH = 1.4
|
||||||
|
|
||||||
|
"""
|
||||||
ALL_RADIALS = [0, 45, 90, 135, 180, 225, 270, 315, ]
|
ALL_RADIALS = [0, 45, 90, 135, 180, 225, 270, 315, ]
|
||||||
COAST_NS_E = [45, 90, 135, ]
|
COAST_NS_E = [45, 90, 135, ]
|
||||||
COAST_EW_N = [315, 0, 45, ]
|
COAST_EW_N = [315, 0, 45, ]
|
||||||
|
COAST_NSEW_E = [225, 270, 315, ]
|
||||||
|
COAST_NSEW_W = [45, 90, 135, ]
|
||||||
|
|
||||||
COAST_NS_W = [225, 270, 315, ]
|
COAST_NS_W = [225, 270, 315, ]
|
||||||
COAST_EW_S = [135, 180, 225, ]
|
COAST_EW_S = [135, 180, 225, ]
|
||||||
|
"""
|
||||||
|
|
||||||
COAST_SWNE = [45, 90, 135, 180, 225, ]
|
LAND = [0, 45, 90, 135, 180, 225, 270, 315, ]
|
||||||
COAST_SENW = [135, 180, 225, 270, 315, ]
|
|
||||||
|
COAST_V_E = [0, 45, 90, 135, 180]
|
||||||
|
COAST_V_W = [180, 225, 270, 315, 0]
|
||||||
|
|
||||||
|
COAST_A_W = [315, 0, 45, 135, 180, 225, 270]
|
||||||
|
COAST_A_E = [0, 45, 90, 135, 180, 225, 315]
|
||||||
|
|
||||||
|
COAST_H_N = [270, 315, 0, 45, 90]
|
||||||
|
COAST_H_S = [90, 135, 180, 225, 270]
|
||||||
|
|
||||||
|
COAST_DL_E = [45, 90, 135, 180, 225]
|
||||||
|
COAST_DL_W = [225, 270, 315, 0, 45]
|
||||||
|
COAST_DR_E = [315, 0, 45, 90, 135]
|
||||||
|
COAST_DR_W = [135, 180, 225, 315]
|
||||||
|
|
||||||
|
|
||||||
class ConflictTheater:
|
class ConflictTheater:
|
||||||
@ -50,7 +67,8 @@ class ConflictTheater:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
for poly in self.landmap_poly:
|
for poly in self.landmap_poly:
|
||||||
return ray_tracing(point.x, point.y, poly)
|
if ray_tracing(point.x, point.y, poly):
|
||||||
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ class ControlPoint:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def carrier(cls, name: str, at: Point):
|
def carrier(cls, name: str, at: Point):
|
||||||
import theater.conflicttheater
|
import theater.conflicttheater
|
||||||
return cls(name, at, at, theater.conflicttheater.ALL_RADIALS, theater.conflicttheater.SIZE_SMALL, 1)
|
return cls(name, at, at, theater.conflicttheater.LAND, theater.conflicttheater.SIZE_SMALL, 1)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|||||||
@ -17,20 +17,20 @@ class NevadaTheater(ConflictTheater):
|
|||||||
"night": (0, 5),
|
"night": (0, 5),
|
||||||
}
|
}
|
||||||
|
|
||||||
mina = ControlPoint.from_airport(nevada.Mina_Airport_3Q0, ALL_RADIALS, SIZE_SMALL, IMPORTANCE_LOW)
|
mina = ControlPoint.from_airport(nevada.Mina_Airport_3Q0, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
tonopah = ControlPoint.from_airport(nevada.Tonopah_Airport, ALL_RADIALS, SIZE_SMALL, IMPORTANCE_LOW)
|
tonopah = ControlPoint.from_airport(nevada.Tonopah_Airport, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
tonopah_test_range = ControlPoint.from_airport(nevada.Tonopah_Test_Range_Airfield, ALL_RADIALS, SIZE_SMALL, IMPORTANCE_LOW)
|
tonopah_test_range = ControlPoint.from_airport(nevada.Tonopah_Test_Range_Airfield, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
lincoln_conty = ControlPoint.from_airport(nevada.Lincoln_County, ALL_RADIALS, SIZE_SMALL, IMPORTANCE_LOW)
|
lincoln_conty = ControlPoint.from_airport(nevada.Lincoln_County, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
|
||||||
pahute_mesa = ControlPoint.from_airport(nevada.Pahute_Mesa_Airstrip, ALL_RADIALS, SIZE_SMALL, IMPORTANCE_MEDIUM)
|
pahute_mesa = ControlPoint.from_airport(nevada.Pahute_Mesa_Airstrip, LAND, SIZE_SMALL, IMPORTANCE_MEDIUM)
|
||||||
groom_lake = ControlPoint.from_airport(nevada.Groom_Lake_AFB, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
groom_lake = ControlPoint.from_airport(nevada.Groom_Lake_AFB, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
||||||
mesquite = ControlPoint.from_airport(nevada.Mesquite, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
mesquite = ControlPoint.from_airport(nevada.Mesquite, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
||||||
beatty = ControlPoint.from_airport(nevada.Beatty_Airport, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
beatty = ControlPoint.from_airport(nevada.Beatty_Airport, LAND, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
||||||
|
|
||||||
creech = ControlPoint.from_airport(nevada.Creech_AFB, ALL_RADIALS, SIZE_BIG, IMPORTANCE_HIGH)
|
creech = ControlPoint.from_airport(nevada.Creech_AFB, LAND, SIZE_BIG, IMPORTANCE_HIGH)
|
||||||
las_vegas = ControlPoint.from_airport(nevada.North_Las_Vegas, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH)
|
las_vegas = ControlPoint.from_airport(nevada.North_Las_Vegas, LAND, SIZE_LARGE, IMPORTANCE_HIGH)
|
||||||
jean = ControlPoint.from_airport(nevada.Jean_Airport, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_HIGH)
|
jean = ControlPoint.from_airport(nevada.Jean_Airport, LAND, SIZE_REGULAR, IMPORTANCE_HIGH)
|
||||||
laughlin = ControlPoint.from_airport(nevada.Laughlin_Airport, ALL_RADIALS, SIZE_LARGE, IMPORTANCE_HIGH)
|
laughlin = ControlPoint.from_airport(nevada.Laughlin_Airport, LAND, SIZE_LARGE, IMPORTANCE_HIGH)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(NevadaTheater, self).__init__()
|
super(NevadaTheater, self).__init__()
|
||||||
|
|||||||
@ -19,27 +19,27 @@ class PersianGulfTheater(ConflictTheater):
|
|||||||
"night": (0, 5),
|
"night": (0, 5),
|
||||||
}
|
}
|
||||||
|
|
||||||
al_dhafra = ControlPoint.from_airport(persiangulf.Al_Dhafra_AB, ALL_RADIALS, SIZE_BIG, IMPORTANCE_LOW)
|
al_dhafra = ControlPoint.from_airport(persiangulf.Al_Dhafra_AB, LAND, SIZE_BIG, IMPORTANCE_LOW)
|
||||||
al_maktoum = ControlPoint.from_airport(persiangulf.Al_Maktoum_Intl, ALL_RADIALS, SIZE_BIG, IMPORTANCE_LOW)
|
al_maktoum = ControlPoint.from_airport(persiangulf.Al_Maktoum_Intl, LAND, SIZE_BIG, IMPORTANCE_LOW)
|
||||||
al_minhad = ControlPoint.from_airport(persiangulf.Al_Minhad_AB, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_LOW)
|
al_minhad = ControlPoint.from_airport(persiangulf.Al_Minhad_AB, LAND, SIZE_REGULAR, IMPORTANCE_LOW)
|
||||||
sir_abu_nuayr = ControlPoint.from_airport(persiangulf.Sir_Abu_Nuayr, [330], SIZE_SMALL, IMPORTANCE_LOW)
|
sir_abu_nuayr = ControlPoint.from_airport(persiangulf.Sir_Abu_Nuayr, [0, 330], SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
|
||||||
dubai = ControlPoint.from_airport(persiangulf.Dubai_Intl, COAST_SWNE, SIZE_LARGE, IMPORTANCE_MEDIUM)
|
dubai = ControlPoint.from_airport(persiangulf.Dubai_Intl, COAST_DL_E, SIZE_LARGE, IMPORTANCE_MEDIUM)
|
||||||
sharjah = ControlPoint.from_airport(persiangulf.Sharjah_Intl, ALL_RADIALS, SIZE_BIG, IMPORTANCE_MEDIUM)
|
sharjah = ControlPoint.from_airport(persiangulf.Sharjah_Intl, LAND, SIZE_BIG, IMPORTANCE_MEDIUM)
|
||||||
fujairah = ControlPoint.from_airport(persiangulf.Fujairah_Intl, COAST_NS_W, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
fujairah = ControlPoint.from_airport(persiangulf.Fujairah_Intl, COAST_V_W, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
||||||
khasab = ControlPoint.from_airport(persiangulf.Khasab, COAST_EW_S, SIZE_SMALL, IMPORTANCE_MEDIUM)
|
khasab = ControlPoint.from_airport(persiangulf.Khasab, LAND, SIZE_SMALL, IMPORTANCE_MEDIUM)
|
||||||
|
|
||||||
sirri = ControlPoint.from_airport(persiangulf.Sirri_Island, ALL_RADIALS, SIZE_TINY, IMPORTANCE_MEDIUM)
|
sirri = ControlPoint.from_airport(persiangulf.Sirri_Island, COAST_DL_W, SIZE_REGULAR, IMPORTANCE_MEDIUM)
|
||||||
abu_musa = ControlPoint.from_airport(persiangulf.Abu_Musa_Island_Airport, ALL_RADIALS, SIZE_TINY, IMPORTANCE_MEDIUM)
|
abu_musa = ControlPoint.from_airport(persiangulf.Abu_Musa_Island_Airport, LAND, SIZE_SMALL, IMPORTANCE_MEDIUM)
|
||||||
tunb_island = ControlPoint.from_airport(persiangulf.Tunb_Island_AFB, [0, 270, 330], SIZE_SMALL, IMPORTANCE_HIGH)
|
tunb_island = ControlPoint.from_airport(persiangulf.Tunb_Island_AFB, [0, 270, 330], SIZE_REGULAR, IMPORTANCE_HIGH)
|
||||||
tunb_kochak = ControlPoint.from_airport(persiangulf.Tunb_Kochak, COAST_EW_S, SIZE_TINY, IMPORTANCE_HIGH)
|
tunb_kochak = ControlPoint.from_airport(persiangulf.Tunb_Kochak, [135, 180], SIZE_SMALL, IMPORTANCE_HIGH)
|
||||||
|
|
||||||
bandar_lengeh = ControlPoint.from_airport(persiangulf.Bandar_Lengeh, COAST_EW_N, SIZE_SMALL, IMPORTANCE_HIGH)
|
bandar_lengeh = ControlPoint.from_airport(persiangulf.Bandar_Lengeh, [270, 315, 0, 45], SIZE_SMALL, IMPORTANCE_HIGH)
|
||||||
qeshm = ControlPoint.from_airport(persiangulf.Qeshm_Island, COAST_EW_N, SIZE_SMALL, IMPORTANCE_HIGH)
|
qeshm = ControlPoint.from_airport(persiangulf.Qeshm_Island, [270, 315, 0, 45, 90, 135, 180], SIZE_SMALL, IMPORTANCE_HIGH)
|
||||||
|
|
||||||
havadarya = ControlPoint.from_airport(persiangulf.Havadarya, COAST_EW_N, SIZE_REGULAR, IMPORTANCE_HIGH)
|
havadarya = ControlPoint.from_airport(persiangulf.Havadarya, COAST_DL_W, SIZE_REGULAR, IMPORTANCE_HIGH)
|
||||||
bandar_abbas = ControlPoint.from_airport(persiangulf.Bandar_Abbas_Intl, COAST_EW_N, SIZE_BIG, IMPORTANCE_HIGH)
|
bandar_abbas = ControlPoint.from_airport(persiangulf.Bandar_Abbas_Intl, LAND, SIZE_BIG, IMPORTANCE_HIGH)
|
||||||
lar = ControlPoint.from_airport(persiangulf.Lar_Airbase, ALL_RADIALS, SIZE_REGULAR, IMPORTANCE_HIGH)
|
lar = ControlPoint.from_airport(persiangulf.Lar_Airbase, LAND, SIZE_REGULAR, IMPORTANCE_HIGH)
|
||||||
|
|
||||||
east_carrier = ControlPoint.carrier("West carrier", Point(-91023.430176, -159467.078125))
|
east_carrier = ControlPoint.carrier("West carrier", Point(-91023.430176, -159467.078125))
|
||||||
west_carrier = ControlPoint.carrier("East carrier", Point(-100531.972946, 60939.275818))
|
west_carrier = ControlPoint.carrier("East carrier", Point(-100531.972946, 60939.275818))
|
||||||
|
|||||||
@ -187,10 +187,17 @@ class EventMenu(Menu):
|
|||||||
clients=scrambled_clients)
|
clients=scrambled_clients)
|
||||||
elif type(self.event) is GroundInterceptEvent:
|
elif type(self.event) is GroundInterceptEvent:
|
||||||
e = self.event # type: GroundInterceptEvent
|
e = self.event # type: GroundInterceptEvent
|
||||||
e.player_attacking(strikegroup=scrambled_aircraft, clients=scrambled_clients)
|
if self.game.is_player_attack(self.event):
|
||||||
|
e.player_attacking(strikegroup=scrambled_aircraft, clients=scrambled_clients)
|
||||||
|
else:
|
||||||
|
e.player_defending(interceptors=scrambled_aircraft, clients=scrambled_clients)
|
||||||
elif type(self.event) is NavalInterceptEvent:
|
elif type(self.event) is NavalInterceptEvent:
|
||||||
e = self.event # type: NavalInterceptEvent
|
e = self.event # type: NavalInterceptEvent
|
||||||
e.player_attacking(strikegroup=scrambled_aircraft, clients=scrambled_clients)
|
|
||||||
|
if self.game.is_player_attack(self.event):
|
||||||
|
e.player_attacking(strikegroup=scrambled_aircraft, clients=scrambled_clients)
|
||||||
|
else:
|
||||||
|
e.player_defending(interceptors=scrambled_aircraft, clients=scrambled_clients)
|
||||||
|
|
||||||
self.game.initiate_event(self.event)
|
self.game.initiate_event(self.event)
|
||||||
EventResultsMenu(self.window, self.parent, self.game, self.event).display()
|
EventResultsMenu(self.window, self.parent, self.game, self.event).display()
|
||||||
|
|||||||
@ -83,11 +83,12 @@ class OverviewCanvas:
|
|||||||
extent=extent)
|
extent=extent)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
For debugging purposes
|
#For debugging purposes
|
||||||
|
|
||||||
for r in cp.radials:
|
for r in cp.radials:
|
||||||
p = self.transform_point(cp.position.point_from_heading(r, 20000))
|
p = self.transform_point(cp.position.point_from_heading(r, 20000))
|
||||||
self.canvas.create_text(p[0], p[1], text="{}".format(r))
|
self.canvas.create_text(p[0], p[1], text="{}".format(r))
|
||||||
|
continue
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.canvas.tag_bind(cp_id, "<Button-1>", self.display(cp))
|
self.canvas.tag_bind(cp_id, "<Button-1>", self.display(cp))
|
||||||
|
|||||||
@ -6,8 +6,9 @@ import os
|
|||||||
from dcs.lua import parse
|
from dcs.lua import parse
|
||||||
from dcs.mission import Mission
|
from dcs.mission import Mission
|
||||||
|
|
||||||
from dcs.unit import Vehicle
|
from dcs.unit import Vehicle, Ship
|
||||||
from dcs.vehicles import vehicle_map
|
from dcs.vehicles import vehicle_map
|
||||||
|
from dcs.ships import ship_map
|
||||||
from dcs.planes import plane_map
|
from dcs.planes import plane_map
|
||||||
from dcs.unit import UnitType
|
from dcs.unit import UnitType
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ class Debriefing:
|
|||||||
country_id = int(unit["country"])
|
country_id = int(unit["country"])
|
||||||
|
|
||||||
if type(unit_type_name) == str:
|
if type(unit_type_name) == str:
|
||||||
unit_type = vehicle_map.get(unit_type_name, plane_map.get(unit_type_name, None))
|
unit_type = vehicle_map.get(unit_type_name, plane_map.get(unit_type_name, ship_map.get(unit_type_name, None)))
|
||||||
if unit_type is None:
|
if unit_type is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -55,6 +56,8 @@ class Debriefing:
|
|||||||
unit_type = None
|
unit_type = None
|
||||||
if isinstance(unit, Vehicle):
|
if isinstance(unit, Vehicle):
|
||||||
unit_type = vehicle_map[unit.type]
|
unit_type = vehicle_map[unit.type]
|
||||||
|
elif isinstance(unit, Ship):
|
||||||
|
unit_type = ship_map[unit.type]
|
||||||
else:
|
else:
|
||||||
unit_type = unit.unit_type
|
unit_type = unit.unit_type
|
||||||
|
|
||||||
@ -74,8 +77,8 @@ class Debriefing:
|
|||||||
player = mission.country(player_name)
|
player = mission.country(player_name)
|
||||||
enemy = mission.country(enemy_name)
|
enemy = mission.country(enemy_name)
|
||||||
|
|
||||||
player_units = count_groups(player.plane_group + player.vehicle_group)
|
player_units = count_groups(player.plane_group + player.vehicle_group + player.ship_group)
|
||||||
enemy_units = count_groups(enemy.plane_group + enemy.vehicle_group)
|
enemy_units = count_groups(enemy.plane_group + enemy.vehicle_group + enemy.ship_group)
|
||||||
|
|
||||||
self.destroyed_units = {
|
self.destroyed_units = {
|
||||||
player.name: calculate_losses(player_units, self.alive_units.get(player.id, {})),
|
player.name: calculate_losses(player_units, self.alive_units.get(player.id, {})),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user