mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
intercept mission
This commit is contained in:
parent
a61f487196
commit
781ddce09d
6
.idea/dcs_pmcliberation.iml
generated
6
.idea/dcs_pmcliberation.iml
generated
@ -1,8 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module type="PYTHON_MODULE" version="4">
|
<module type="PYTHON_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$">
|
||||||
<orderEntry type="jdk" jdkName="Python 3.6" jdkType="Python SDK" />
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.6 (venv)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="TestRunnerService">
|
<component name="TestRunnerService">
|
||||||
|
|||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (venv)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
||||||
17
__init__.py
17
__init__.py
@ -35,7 +35,22 @@ theater.senaki.base.aa = {
|
|||||||
AirDefence.AAA_ZU_23_on_Ural_375: 2,
|
AirDefence.AAA_ZU_23_on_Ural_375: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
op = game.mission.CaptureOperation.playerless(m, theater.kutaisi, theater.senaki)
|
"""
|
||||||
|
op = game.mission.CaptureOperation(m, m.country("USA"), m.country("Russia"), theater.senaki, theater.batumi, {A_10C: 2}, {F_15C: 2}, {Armor.MBT_M1A2_Abrams: 4}, {Su_27: 4}, {Armor.MBT_T_55: 4}, {})
|
||||||
|
op.generate()
|
||||||
|
"""
|
||||||
|
|
||||||
|
op = game.mission.InterceptOperation(m,
|
||||||
|
m.country("USA"),
|
||||||
|
m.country("Russia"),
|
||||||
|
theater.batumi,
|
||||||
|
m.terrain.batumi(),
|
||||||
|
escort={Su_27: 2},
|
||||||
|
transport={An_26B: 2},
|
||||||
|
interceptors={M_2000C: 2})
|
||||||
op.generate()
|
op.generate()
|
||||||
|
|
||||||
|
if not os.path.exists("./build"):
|
||||||
|
os.mkdir("./build")
|
||||||
|
|
||||||
m.save("build/output.miz")
|
m.save("build/output.miz")
|
||||||
|
|||||||
55
game/event.py
Normal file
55
game/event.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import typing
|
||||||
|
|
||||||
|
import dcs
|
||||||
|
|
||||||
|
from theater.controlpoint import *
|
||||||
|
from .mission import *
|
||||||
|
|
||||||
|
class Event:
|
||||||
|
silent = False
|
||||||
|
operation = None # type: Operation
|
||||||
|
|
||||||
|
def failure(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def success(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class InterceptEvent(Event):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class CaptureEvent(Event):
|
||||||
|
silent = True
|
||||||
|
|
||||||
|
def __init__(self, from_cp: ControlPoint, to_cp: ControlPoint):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def player_defending(self, from_cp: ControlPoint, to_cp: ControlPoint, interceptors: typing.Dict[PlaneType, int]):
|
||||||
|
assert not self.operation
|
||||||
|
|
||||||
|
cas = from_cp.base.scramble_cas(to_cp)
|
||||||
|
escort = from_cp.base.scramble_sweep(to_cp)
|
||||||
|
attackers = from_cp.base.assemble_cap(to_cp)
|
||||||
|
|
||||||
|
self.operation = CaptureOperation(from_cp=from_cp,
|
||||||
|
to_cp=to_cp,
|
||||||
|
cas=cas,
|
||||||
|
escort=escort,
|
||||||
|
attack=attackers,
|
||||||
|
intercept=interceptors,
|
||||||
|
defense=to_cp.base.armor,
|
||||||
|
aa=to_cp.base.aa)
|
||||||
|
|
||||||
|
def player_attacking(self, from_cp: ControlPoint, to_cp: ControlPoint, cas: typing.Dict[PlaneType, int], escort: typing.Dict[PlaneType, int], armor: typing.Dict[Armor, int]):
|
||||||
|
assert not self.operation
|
||||||
|
|
||||||
|
interceptors = to_cp.base.scramble_sweep()
|
||||||
|
|
||||||
|
self.operation = CaptureOperation(from_cp=from_cp,
|
||||||
|
to_cp=to_cp,
|
||||||
|
cas=cas,
|
||||||
|
escort=escort,
|
||||||
|
attack=armor,
|
||||||
|
intercept=interceptors,
|
||||||
|
defense=to_cp.base.armor,
|
||||||
|
aa=to_cp.base.aa)
|
||||||
11
game/game.py
11
game/game.py
@ -2,9 +2,20 @@ import typing
|
|||||||
|
|
||||||
from theater.conflicttheater import *
|
from theater.conflicttheater import *
|
||||||
from theater.controlpoint import *
|
from theater.controlpoint import *
|
||||||
|
from .event import *
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
|
events = [] # type: typing.List[Event]
|
||||||
|
|
||||||
def __init__(self, theater: ConflictTheater):
|
def __init__(self, theater: ConflictTheater):
|
||||||
self.theater = theater
|
self.theater = theater
|
||||||
|
|
||||||
|
def _fill_cap_events(self):
|
||||||
|
for cp in [x for x in self.theater.controlpoints if x.captured]:
|
||||||
|
for connected_cp in [x for x in cp.connected_points if not x.captured]:
|
||||||
|
self.events.append(CaptureEvent(cp, connected_cp))
|
||||||
|
|
||||||
|
def pass_turn(self):
|
||||||
|
self.events = [] # type: typing.List[Event]
|
||||||
|
self._fill_cap_events()
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,8 @@ class Operation:
|
|||||||
class CaptureOperation(Operation):
|
class CaptureOperation(Operation):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
mission: Mission,
|
mission: Mission,
|
||||||
|
attacker: Country,
|
||||||
|
defender: Country,
|
||||||
from_cp: ControlPoint,
|
from_cp: ControlPoint,
|
||||||
to_cp: ControlPoint,
|
to_cp: ControlPoint,
|
||||||
cas: typing.Dict[PlaneType, int],
|
cas: typing.Dict[PlaneType, int],
|
||||||
@ -31,13 +33,7 @@ class CaptureOperation(Operation):
|
|||||||
intercept: typing.Dict[PlaneType, int],
|
intercept: typing.Dict[PlaneType, int],
|
||||||
defense: typing.Dict[Armor, int],
|
defense: typing.Dict[Armor, int],
|
||||||
aa: typing.Dict[AirDefence, int]):
|
aa: typing.Dict[AirDefence, int]):
|
||||||
conflict = None
|
conflict = to_cp.conflict_attack(from_cp, attacker, defender)
|
||||||
if from_cp.captured:
|
|
||||||
assert not to_cp.captured
|
|
||||||
conflict = to_cp.conflict_attack(from_cp, US, THEM)
|
|
||||||
else:
|
|
||||||
assert not from_cp.captured
|
|
||||||
conflict = to_cp.conflict_attack(from_cp, THEM, US)
|
|
||||||
|
|
||||||
super(CaptureOperation, self).__init__(mission, conflict)
|
super(CaptureOperation, self).__init__(mission, conflict)
|
||||||
self.from_cp = from_cp
|
self.from_cp = from_cp
|
||||||
@ -51,49 +47,37 @@ class CaptureOperation(Operation):
|
|||||||
|
|
||||||
self.aa = aa
|
self.aa = aa
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def player_defending(self, from_cp: ControlPoint, to_cp: ControlPoint, interceptors: typing.Dict[PlaneType, int]):
|
|
||||||
cas = from_cp.base.scramble_cas(to_cp)
|
|
||||||
escort = from_cp.base.scramble_sweep(to_cp)
|
|
||||||
attackers = from_cp.base.assemble_cap(to_cp)
|
|
||||||
|
|
||||||
return CaptureOperation(from_cp=from_cp,
|
|
||||||
to_cp=to_cp,
|
|
||||||
cas=cas,
|
|
||||||
escort=escort,
|
|
||||||
attack=attackers,
|
|
||||||
intercept=interceptors,
|
|
||||||
defense=to_cp.base.armor,
|
|
||||||
aa=to_cp.base.aa)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def player_attacking(self, from_cp: ControlPoint, to_cp: ControlPoint, cas: typing.Dict[PlaneType, int], escort: typing.Dict[PlaneType, int], armor: typing.Dict[Armor, int]):
|
|
||||||
interceptors = to_cp.base.scramble_sweep()
|
|
||||||
|
|
||||||
return CaptureOperation(from_cp=from_cp,
|
|
||||||
to_cp=to_cp,
|
|
||||||
cas=cas,
|
|
||||||
escort=escort,
|
|
||||||
attack=armor,
|
|
||||||
intercept=interceptors,
|
|
||||||
defense=to_cp.base.armor,
|
|
||||||
aa=to_cp.base.aa)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def playerless(self, mission: Mission, from_cp: ControlPoint, to_cp: ControlPoint):
|
|
||||||
return CaptureOperation(mission=mission,
|
|
||||||
from_cp=from_cp,
|
|
||||||
to_cp=to_cp,
|
|
||||||
cas=from_cp.base.scramble_cas(to_cp),
|
|
||||||
escort=from_cp.base.scramble_sweep(to_cp),
|
|
||||||
attack=from_cp.base.assemble_cap(to_cp),
|
|
||||||
intercept=to_cp.base.scramble_interceptors(0.5),
|
|
||||||
defense=to_cp.base.assemble_defense(0.5),
|
|
||||||
aa=to_cp.base.aa)
|
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
self.armorgen.generate(self.attack, self.defense)
|
self.armorgen.generate(self.attack, self.defense)
|
||||||
self.airgen.generate_cas(self.cas)
|
self.airgen.generate_cas(self.cas)
|
||||||
self.airgen.generate_escort(self.escort)
|
self.airgen.generate_cas_escort(self.escort)
|
||||||
self.airgen.generate_interceptors(self.intercept)
|
self.airgen.generate_defense(self.intercept)
|
||||||
self.aagen.generate(self.aa)
|
self.aagen.generate(self.aa)
|
||||||
|
|
||||||
|
class InterceptOperation(Operation):
|
||||||
|
def __init__(self,
|
||||||
|
mission: Mission,
|
||||||
|
attacker: Country,
|
||||||
|
defender: Country,
|
||||||
|
destination: ControlPoint,
|
||||||
|
destination_port: Airport,
|
||||||
|
escort: typing.Dict[PlaneType, int],
|
||||||
|
transport: typing.Dict[PlaneType, int],
|
||||||
|
interceptors: typing.Dict[PlaneType, int]):
|
||||||
|
conflict = Conflict.intercept_conflict(
|
||||||
|
attacker=attacker,
|
||||||
|
defender=defender,
|
||||||
|
position=destination.position,
|
||||||
|
heading=0
|
||||||
|
)
|
||||||
|
|
||||||
|
super(InterceptOperation, self).__init__(mission, conflict)
|
||||||
|
self.destination_port = destination_port
|
||||||
|
self.escort = escort
|
||||||
|
self.transport = transport
|
||||||
|
self.interceptors = interceptors
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
self.airgen.generate_transport(self.transport, self.destination_port)
|
||||||
|
self.airgen.generate_transport_escort(self.escort)
|
||||||
|
self.airgen.generate_interception(self.interceptors)
|
||||||
|
|||||||
108
gen/aircraft.py
108
gen/aircraft.py
@ -19,9 +19,12 @@ from dcs.task import *
|
|||||||
|
|
||||||
SPREAD_DISTANCE_FACTOR = 1, 2
|
SPREAD_DISTANCE_FACTOR = 1, 2
|
||||||
ESCORT_MAX_DIST = 30000
|
ESCORT_MAX_DIST = 30000
|
||||||
|
WORKAROUND_WAYP_DIST = 1000
|
||||||
|
|
||||||
WARM_START_ALTITUDE = 6000
|
WARM_START_ALTITUDE = 6000
|
||||||
WARM_START_AIRSPEED = 300
|
WARM_START_AIRSPEED = 300
|
||||||
|
|
||||||
|
INTERCEPT_ALT = 15000
|
||||||
CAS_ALTITUDE = 3000
|
CAS_ALTITUDE = 3000
|
||||||
|
|
||||||
INTERCEPT_MAX_DISTANCE_FACTOR = 15
|
INTERCEPT_MAX_DISTANCE_FACTOR = 15
|
||||||
@ -49,6 +52,7 @@ class AircraftConflictGenerator:
|
|||||||
at: Point = None,
|
at: Point = None,
|
||||||
airport: Airport = None) -> PlaneGroup:
|
airport: Airport = None) -> PlaneGroup:
|
||||||
starttype = airport == None and StartType.Warm or StartType.Cold
|
starttype = airport == None and StartType.Warm or StartType.Cold
|
||||||
|
print("generating {} ({}) at {} {}".format(unit, count, at, airport, side))
|
||||||
return self.m.flight_group(
|
return self.m.flight_group(
|
||||||
country=side,
|
country=side,
|
||||||
name=name,
|
name=name,
|
||||||
@ -61,52 +65,112 @@ class AircraftConflictGenerator:
|
|||||||
start_type=starttype,
|
start_type=starttype,
|
||||||
group_size=count)
|
group_size=count)
|
||||||
|
|
||||||
|
def _generate_escort(self, units: typing.Dict[PlaneType, int], airport: Airport, side: Country, location: Point):
|
||||||
|
assert len(self.escort_targets) > 0
|
||||||
|
|
||||||
|
for type, count in units.items():
|
||||||
|
group = self._generate_group(
|
||||||
|
name=namegen.next_escort_group_name(),
|
||||||
|
side=side,
|
||||||
|
unit=type,
|
||||||
|
count=count,
|
||||||
|
at=location,
|
||||||
|
airport=airport)
|
||||||
|
|
||||||
|
group.task = Escort.name
|
||||||
|
group.load_task_default_loadout(dcs.task.Escort)
|
||||||
|
|
||||||
|
heading = group.position.heading_between_point(self.conflict.position)
|
||||||
|
position = group.position # type: Point
|
||||||
|
wayp = group.add_waypoint(position.point_from_heading(heading, WORKAROUND_WAYP_DIST), CAS_ALTITUDE)
|
||||||
|
|
||||||
|
for group in self.escort_targets:
|
||||||
|
wayp.tasks.append(EscortTaskAction(group.id, engagement_max_dist=ESCORT_MAX_DIST))
|
||||||
|
|
||||||
def generate_cas(self, attackers: typing.Dict[PlaneType, int], airport: Airport = None):
|
def generate_cas(self, attackers: typing.Dict[PlaneType, int], airport: Airport = None):
|
||||||
|
assert len(self.escort_targets) == 0
|
||||||
|
|
||||||
for type, count in attackers.items():
|
for type, count in attackers.items():
|
||||||
group = self._generate_group(
|
group = self._generate_group(
|
||||||
name=namegen.next_cas_group_name(),
|
name=namegen.next_cas_group_name(),
|
||||||
side=self.conflict.attackers_side,
|
side=self.conflict.attackers_side,
|
||||||
unit=type,
|
unit=type,
|
||||||
count=count,
|
count=count,
|
||||||
at=airport == None and self._group_point(self.conflict.air_attackers_location) or None,
|
at=airport is None and self._group_point(self.conflict.air_attackers_location) or None,
|
||||||
airport=airport)
|
airport=airport)
|
||||||
self.escort_targets.append(group)
|
self.escort_targets.append(group)
|
||||||
|
|
||||||
group.add_waypoint(self.conflict.position, CAS_ALTITUDE)
|
group.add_waypoint(self.conflict.position, CAS_ALTITUDE)
|
||||||
group.task = CAS.name
|
group.task = CAS.name
|
||||||
|
group.load_task_default_loadout(CAS)
|
||||||
|
|
||||||
def generate_escort(self, attackers: typing.Dict[PlaneType, int], airport: Airport = None):
|
def generate_cas_escort(self, attackers: typing.Dict[PlaneType, int], airport: Airport = None):
|
||||||
for type, count in attackers.items():
|
self._generate_escort(
|
||||||
group = self._generate_group(
|
units=attackers,
|
||||||
name=namegen.next_escort_group_name(),
|
airport=airport,
|
||||||
side=self.conflict.attackers_side,
|
side=self.conflict.attackers_side,
|
||||||
unit=type,
|
location=airport is None and self._group_point(self.conflict.air_attackers_location) or None
|
||||||
count=count,
|
)
|
||||||
at=airport == None and self._group_point(self.conflict.air_attackers_location) or None,
|
|
||||||
airport=airport)
|
|
||||||
|
|
||||||
group.task = Escort.name
|
def generate_transport_escort(self, escort: typing.Dict[PlaneType, int], airport: Airport = None):
|
||||||
group.load_task_default_loadout(dcs.task.Escort.name)
|
self._generate_escort(
|
||||||
|
units=escort,
|
||||||
|
airport=airport,
|
||||||
|
side=self.conflict.defenders_side,
|
||||||
|
location=airport is None and self._group_point(self.conflict.air_defenders_location) or None
|
||||||
|
)
|
||||||
|
|
||||||
heading = group.position.heading_between_point(self.conflict.position)
|
def generate_defense(self, defenders: typing.Dict[PlaneType, int], airport: Airport = None):
|
||||||
position = group.position # type: Point
|
|
||||||
wayp = group.add_waypoint(position.point_from_heading(heading, 3000), CAS_ALTITUDE)
|
|
||||||
|
|
||||||
for group in self.escort_targets:
|
|
||||||
wayp.tasks.append(EscortTaskAction(group.id, engagement_max_dist=ESCORT_MAX_DIST))
|
|
||||||
|
|
||||||
def generate_interceptors(self, defenders: typing.Dict[PlaneType, int], airport: Airport = None):
|
|
||||||
for type, count in defenders.items():
|
for type, count in defenders.items():
|
||||||
group = self._generate_group(
|
group = self._generate_group(
|
||||||
name=namegen.next_intercept_group_name(),
|
name=namegen.next_intercept_group_name(),
|
||||||
side=self.conflict.defenders_side,
|
side=self.conflict.defenders_side,
|
||||||
unit=type,
|
unit=type,
|
||||||
count=count,
|
count=count,
|
||||||
at=airport == None and self._group_point(self.conflict.air_defenders_location) or None,
|
at=airport is None and self._group_point(self.conflict.air_defenders_location) or None,
|
||||||
airport=airport)
|
airport=airport)
|
||||||
|
|
||||||
group.task = FighterSweep.name
|
group.task = FighterSweep.name
|
||||||
group.load_task_default_loadout(dcs.task.FighterSweep())
|
group.load_task_default_loadout(FighterSweep)
|
||||||
wayp = group.add_waypoint(self.conflict.position, CAS_ALTITUDE)
|
wayp = group.add_waypoint(self.conflict.position, CAS_ALTITUDE)
|
||||||
wayp.tasks.append(dcs.task.EngageTargets(max_distance=self.conflict.size * INTERCEPT_MAX_DISTANCE_FACTOR))
|
wayp.tasks.append(dcs.task.EngageTargets(max_distance=self.conflict.size * INTERCEPT_MAX_DISTANCE_FACTOR))
|
||||||
wayp.tasks.append(dcs.task.OrbitAction())
|
wayp.tasks.append(dcs.task.OrbitAction())
|
||||||
|
|
||||||
|
def generate_transport(self, transport: typing.Dict[PlaneType, int], destination: Airport):
|
||||||
|
assert len(self.escort_targets) == 0
|
||||||
|
|
||||||
|
for type, count in transport.items():
|
||||||
|
group = self._generate_group(
|
||||||
|
name=namegen.next_transport_group_name(),
|
||||||
|
side=self.conflict.defenders_side,
|
||||||
|
unit=type,
|
||||||
|
count=count,
|
||||||
|
at=self._group_point(self.conflict.air_defenders_location),
|
||||||
|
airport=None
|
||||||
|
)
|
||||||
|
|
||||||
|
group.task = Transport.name
|
||||||
|
|
||||||
|
self.escort_targets.append(group)
|
||||||
|
group.land_at(destination)
|
||||||
|
|
||||||
|
def generate_interception(self, interceptors: typing.Dict[PlaneType, int], airport: Airport = None):
|
||||||
|
for type, count in interceptors.items():
|
||||||
|
group = self._generate_group(
|
||||||
|
name=namegen.next_intercept_group_name(),
|
||||||
|
side=self.conflict.attackers_side,
|
||||||
|
unit=type,
|
||||||
|
count=count,
|
||||||
|
at=airport is None and self._group_point(self.conflict.air_attackers_location) or None,
|
||||||
|
airport=airport
|
||||||
|
)
|
||||||
|
|
||||||
|
group.task = FighterSweep.name
|
||||||
|
group.load_task_default_loadout(FighterSweep)
|
||||||
|
|
||||||
|
heading = group.position.heading_between_point(self.conflict.position)
|
||||||
|
initial_wayp = group.add_waypoint(group.position.point_from_heading(heading, WORKAROUND_WAYP_DIST), INTERCEPT_ALT)
|
||||||
|
initial_wayp.tasks.append(EngageTargets())
|
||||||
|
|
||||||
|
wayp = group.add_waypoint(self.conflict.position, 0)
|
||||||
|
wayp.tasks.append(EngageTargets())
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import typing
|
|||||||
import pdb
|
import pdb
|
||||||
import dcs
|
import dcs
|
||||||
|
|
||||||
|
from random import randint
|
||||||
from dcs import Mission
|
from dcs import Mission
|
||||||
|
|
||||||
from dcs.mission import *
|
from dcs.mission import *
|
||||||
@ -17,18 +18,42 @@ def _opposite_heading(h):
|
|||||||
return h+180
|
return h+180
|
||||||
|
|
||||||
GROUND_DISTANCE_FACTOR = 2
|
GROUND_DISTANCE_FACTOR = 2
|
||||||
AIR_DISTANCE_FACTOR = 5
|
AIR_DISTANCE = 8000
|
||||||
|
|
||||||
|
INTERCEPT_ATTACKERS_HEADING = -45, 45
|
||||||
|
INTERCEPT_DEFENDERS_HEADING = -10, 10
|
||||||
|
INTERCEPT_ATTACKERS_DISTANCE = 60000
|
||||||
|
INTERCEPT_DEFENDERS_DISTANCE = 30000
|
||||||
|
|
||||||
class Conflict:
|
class Conflict:
|
||||||
def __init__(self, attacker: Country, attack_heading: int, defender: Country, defense_heading: int, position: Point, size: int):
|
@classmethod
|
||||||
self.attackers_side = attacker
|
def capture_conflict(self, attacker: Country, attack_heading: int, defender: Country, defense_heading: int, position: Point, size: int):
|
||||||
self.defenders_side = defender
|
instance = self()
|
||||||
self.position = position
|
instance.attackers_side = attacker
|
||||||
self.size = size
|
instance.defenders_side = defender
|
||||||
|
instance.position = position
|
||||||
|
instance.size = size
|
||||||
|
|
||||||
self.ground_attackers_location = self.position.point_from_heading(attack_heading, self.size * GROUND_DISTANCE_FACTOR)
|
instance.ground_attackers_location = instance.position.point_from_heading(attack_heading, instance.size * GROUND_DISTANCE_FACTOR)
|
||||||
self.ground_defenders_location = self.position.point_from_heading(defense_heading, self.size * GROUND_DISTANCE_FACTOR)
|
instance.ground_defenders_location = instance.position.point_from_heading(defense_heading, instance.size * GROUND_DISTANCE_FACTOR)
|
||||||
|
|
||||||
self.air_attackers_location = self.position.point_from_heading(attack_heading, self.size * AIR_DISTANCE_FACTOR)
|
instance.air_attackers_location = instance.position.point_from_heading(attack_heading, AIR_DISTANCE)
|
||||||
self.air_defenders_location = self.position.point_from_heading(defense_heading, self.size * AIR_DISTANCE_FACTOR)
|
instance.air_defenders_location = instance.position.point_from_heading(defense_heading, AIR_DISTANCE)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def intercept_conflict(self, attacker: Country, defender: Country, position: Point, heading: int):
|
||||||
|
from theater.conflicttheater import SIZE_REGULAR
|
||||||
|
|
||||||
|
instance = self()
|
||||||
|
instance.attackers_side = attacker
|
||||||
|
instance.defenders_side = defender
|
||||||
|
|
||||||
|
instance.position = position
|
||||||
|
instance.size = SIZE_REGULAR
|
||||||
|
|
||||||
|
instance.air_attackers_location = instance.position.point_from_heading(random.randint(*INTERCEPT_ATTACKERS_HEADING) + heading, INTERCEPT_ATTACKERS_DISTANCE)
|
||||||
|
instance.air_defenders_location = instance.position.point_from_heading(random.randint(*INTERCEPT_DEFENDERS_HEADING) + heading, INTERCEPT_DEFENDERS_DISTANCE)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
|||||||
@ -21,6 +21,10 @@ class NameGenerator:
|
|||||||
self.number += 1
|
self.number += 1
|
||||||
return "AA Unit {}".format(self.number)
|
return "AA Unit {}".format(self.number)
|
||||||
|
|
||||||
|
def next_transport_group_name(self):
|
||||||
|
self.number += 1
|
||||||
|
return "Transport Unit {}".format(self.number)
|
||||||
|
|
||||||
|
|
||||||
namegen = NameGenerator()
|
namegen = NameGenerator()
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import math
|
|||||||
from dcs.mapping import *
|
from dcs.mapping import *
|
||||||
from dcs.country import *
|
from dcs.country import *
|
||||||
|
|
||||||
from gen.conflictgen import Conflict
|
from gen.conflictgen import *
|
||||||
|
|
||||||
class ControlPoint:
|
class ControlPoint:
|
||||||
connected_points = [] # type: typing.List[ControlPoint]
|
connected_points = [] # type: typing.List[ControlPoint]
|
||||||
@ -27,12 +27,12 @@ class ControlPoint:
|
|||||||
def connect(self, to):
|
def connect(self, to):
|
||||||
self.connected_points.append(to)
|
self.connected_points.append(to)
|
||||||
|
|
||||||
def find_radial(self, heading: int):
|
def find_radial(self, heading: int, ignored_radial: int = None):
|
||||||
closest_radial = 0
|
closest_radial = 0
|
||||||
closest_radial_delta = 360
|
closest_radial_delta = 360
|
||||||
for radial in self.radials:
|
for radial in [x for x in self.radials if x != ignored_radial]:
|
||||||
delta = math.fabs(radial - heading)
|
delta = math.fabs(radial - heading)
|
||||||
if closest_radial_delta < delta:
|
if delta < closest_radial_delta:
|
||||||
closest_radial = radial
|
closest_radial = radial
|
||||||
closest_radial_delta = delta
|
closest_radial_delta = delta
|
||||||
|
|
||||||
@ -42,13 +42,13 @@ class ControlPoint:
|
|||||||
cp = from_cp # type: ControlPoint
|
cp = from_cp # type: ControlPoint
|
||||||
|
|
||||||
attack_radial = self.find_radial(cp.position.heading_between_point(self.position))
|
attack_radial = self.find_radial(cp.position.heading_between_point(self.position))
|
||||||
defense_radial = self.find_radial(self.position.heading_between_point(cp.position))
|
defense_radial = self.find_radial(self.position.heading_between_point(cp.position), ignored_radial=attack_radial)
|
||||||
|
|
||||||
return Conflict(attacker=attacker,
|
return Conflict.capture_conflict(attacker=attacker,
|
||||||
attack_heading=attack_radial,
|
attack_heading=attack_radial,
|
||||||
defender=defender,
|
defender=defender,
|
||||||
defense_heading=defense_radial,
|
defense_heading=defense_radial,
|
||||||
position=self.position,
|
position=self.position,
|
||||||
size=self.size)
|
size=self.size)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user