base mission generation framework

This commit is contained in:
Vasiliy Horbachenko 2018-05-24 11:53:40 +03:00
parent 6152570fd8
commit f4a3aef2d5
15 changed files with 180 additions and 28 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
*.pyc *.pyc
__pycache__ __pycache__
output.miz
.DS_Store

View File

@ -4,22 +4,34 @@ import dcs
import os import os
import gen import gen
import theater.caucasus
m = dcs.Mission() m = dcs.Mission()
theater = theater.caucasus.CaucasusTheater()
conflict = theater.controlpoints[0].conflict_attack(theater.controlpoints[1], m.country("USA"), m.country("Russia"))
"""
conflict = gen.Conflict( conflict = gen.Conflict(
heading=100, heading=100,
attacker=m.country("USA"), attacker=m.country("USA"),
defender=m.country("Russia"), defender=m.country("Russia"),
point=m.terrain.krymsk().position, point=m.terrain.krymsk().position,
size=10000) size=10000)
"""
armor_conflict = gen.ArmorConflictGenerator(m, conflict) armor_conflict = gen.ArmorConflictGenerator(m, conflict)
armor_conflict.generate( armor_conflict.generate(
attackers={dcs.vehicles.Armor.MBT_M1A2_Abrams: 8}, attackers={dcs.vehicles.Armor.MBT_M1A2_Abrams: 8},
defenders={dcs.vehicles.Armor.MBT_T_80U: 6}) defenders={dcs.vehicles.Armor.MBT_T_80U: 10})
aircraft_conflict = gen.AircraftConflictGenerator(m, conflict) aircraft_conflict = gen.AircraftConflictGenerator(m, conflict)
aircraft_conflict.generate_cas({dcs.planes.A_10C: 2}) aircraft_conflict.generate_cas({dcs.planes.A_10C: 4})
aircraft_conflict.generate_escort({dcs.planes.F_15C: 2}) aircraft_conflict.generate_escort({dcs.planes.F_15C: 4})
aircraft_conflict.generate_interceptors({dcs.planes.Su_27: 2}) aircraft_conflict.generate_interceptors({dcs.planes.Su_27: 6})
aa_conflict = gen.AAConflictGenerator(m, conflict)
aa_conflict.generate({dcs.vehicles.AirDefence.AAA_ZU_23_on_Ural_375: 3})
m.save("output.miz")

11
game/game.py Normal file
View File

@ -0,0 +1,11 @@
import typing
from theater.conflicttheater import *
class Game:
def __init__(self, theater: ConflictTheater):
self.theater = theater
def pass_time(self, time: int):
pass

3
game/side.py Normal file
View File

@ -0,0 +1,3 @@
import typing
import dcs

View File

@ -0,0 +1,40 @@
import typing
import pdb
import dcs
from random import randint
import globals
from .conflictgen import *
from .naming import *
from dcs.mission import *
from dcs.vehicles import *
from dcs.unitgroup import *
from dcs.unittype import *
from dcs.mapping import *
from dcs.point import *
from dcs.task import *
DISTANCE_FACTOR = 4, 5
class AAConflictGenerator:
def __init__(self, mission: Mission, conflict: Conflict):
self.m = mission
self.conflict = conflict
def generate(self, units: typing.Dict[UnitType, int]):
for type, count in units.items():
for _ in range(count):
p = self.conflict.ground_defenders_location.random_point_within(
self.conflict.size * DISTANCE_FACTOR[1],
self.conflict.size * DISTANCE_FACTOR[0])
self.m.vehicle_group(
country=self.conflict.defenders_side,
name=namegen.next_ground_group_name(),
_type=type,
position=p,
group_size=1)

View File

@ -17,14 +17,15 @@ from dcs.mapping import *
from dcs.point import * from dcs.point import *
from dcs.task import * from dcs.task import *
SPREAD_DISTANCE_FACTOR = 0.1, 0.25 SPREAD_DISTANCE_FACTOR = 1, 2
SPREAD_DISTANCE_SIZE_FACTOR = 0.5
ESCORT_MAX_DIST = 30000 ESCORT_MAX_DIST = 30000
WARM_START_ALTITUDE = 6000 WARM_START_ALTITUDE = 6000
WARM_START_AIRSPEED = 300 WARM_START_AIRSPEED = 300
CAS_ALTITUDE = 3000 CAS_ALTITUDE = 3000
INTERCEPT_MAX_DISTANCE_FACTOR = 15
class AircraftConflictGenerator: class AircraftConflictGenerator:
escort_targets = [] # type: typing.List[PlaneGroup] escort_targets = [] # type: typing.List[PlaneGroup]
@ -37,8 +38,7 @@ class AircraftConflictGenerator:
int(self.conflict.size * SPREAD_DISTANCE_FACTOR[0]), int(self.conflict.size * SPREAD_DISTANCE_FACTOR[0]),
int(self.conflict.size * SPREAD_DISTANCE_FACTOR[1]), int(self.conflict.size * SPREAD_DISTANCE_FACTOR[1]),
) )
return point.random_point_within(distance, self.conflict.size * SPREAD_DISTANCE_FACTOR[0])
return point.random_point_within(distance, self.conflict.size * SPREAD_DISTANCE_SIZE_FACTOR)
def _generate_group( def _generate_group(
self, self,
@ -48,7 +48,7 @@ class AircraftConflictGenerator:
count: int, count: int,
at: Point = None, at: Point = None,
airport: Airport = None) -> PlaneGroup: airport: Airport = None) -> PlaneGroup:
starttype = airport == None and StartType.Warm or StartType.Runway starttype = airport == None and StartType.Warm or StartType.Cold
return self.m.flight_group( return self.m.flight_group(
country=side, country=side,
name=name, name=name,
@ -86,9 +86,14 @@ class AircraftConflictGenerator:
airport=airport) airport=airport)
group.task = Escort.name group.task = Escort.name
for group in self.escort_targets: group.load_task_default_loadout(dcs.task.Escort.name)
group.tasks.append(EscortTaskAction(group.id, engagement_max_dist=ESCORT_MAX_DIST))
heading = group.position.heading_between_point(self.conflict.point)
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): def generate_interceptors(self, defenders: typing.Dict[PlaneType, int], airport: Airport = None):
for type, count in defenders.items(): for type, count in defenders.items():
@ -100,5 +105,8 @@ class AircraftConflictGenerator:
at=airport == None and self._group_point(self.conflict.air_defenders_location) or None, at=airport == None and self._group_point(self.conflict.air_defenders_location) or None,
airport=airport) airport=airport)
group.add_waypoint(self.conflict.point, CAS_ALTITUDE) group.task = FighterSweep.name
group.task = FighterSweep() group.load_task_default_loadout(dcs.task.FighterSweep())
wayp = group.add_waypoint(self.conflict.point, CAS_ALTITUDE)
wayp.tasks.append(dcs.task.EngageTargets(max_distance=self.conflict.size * INTERCEPT_MAX_DISTANCE_FACTOR))
wayp.tasks.append(dcs.task.OrbitAction())

View File

@ -18,8 +18,8 @@ from dcs.point import *
from dcs.task import * from dcs.task import *
from dcs.country import * from dcs.country import *
SPREAD_DISTANCE_FACTOR = 0.01, 0.1 SPREAD_DISTANCE_FACTOR = 0.1, 0.3
SPREAD_DISTANCE_SIZE_FACTOR = 0.5 SPREAD_DISTANCE_SIZE_FACTOR = 0.1
class ArmorConflictGenerator: class ArmorConflictGenerator:
def __init__(self, mission: Mission, conflict: Conflict): def __init__(self, mission: Mission, conflict: Conflict):
@ -42,7 +42,7 @@ class ArmorConflictGenerator:
unit, unit,
position=self._group_point(at), position=self._group_point(at),
group_size=1, group_size=1,
move_formation=PointAction.OnRoad) move_formation=PointAction.OffRoad)
wayp = group.add_waypoint(self.conflict.point) wayp = group.add_waypoint(self.conflict.point)
wayp.tasks = [] wayp.tasks = []

View File

@ -2,6 +2,8 @@ import typing
import pdb import pdb
import dcs import dcs
from dcs import Mission
from dcs.mission import * from dcs.mission import *
from dcs.vehicles import * from dcs.vehicles import *
from dcs.unitgroup import * from dcs.unitgroup import *
@ -14,18 +16,22 @@ from dcs.country import *
def _opposite_heading(h): def _opposite_heading(h):
return h+180 return h+180
GROUND_DISTANCE_FACTOR = 1 GROUND_DISTANCE_FACTOR = 2
AIR_DISTANCE_FACTOR = 4 AIR_DISTANCE_FACTOR = 5
class Conflict: class Conflict:
def __init__(self, heading: int, attacker: Country, defender: Country, point: Point, size: int): trigger_zone = None # type: TriggerZone
activation_trigger = None # type: Trigger
def __init__(self, attacker: Country, attack_heading: int, defender: Country, defense_heading: int, point: Point, size: int):
self.attackers_side = attacker self.attackers_side = attacker
self.defenders_side = defender self.defenders_side = defender
self.point = point self.point = point
self.size = size self.size = size
self.ground_attackers_location = self.point.point_from_heading(heading, self.size * GROUND_DISTANCE_FACTOR) self.ground_attackers_location = self.point.point_from_heading(attack_heading, self.size * GROUND_DISTANCE_FACTOR)
self.ground_defenders_location = self.point.point_from_heading(_opposite_heading(heading), self.size * GROUND_DISTANCE_FACTOR) self.ground_defenders_location = self.point.point_from_heading(defense_heading, self.size * GROUND_DISTANCE_FACTOR)
self.air_attackers_location = self.point.point_from_heading(attack_heading, self.size * AIR_DISTANCE_FACTOR)
self.air_defenders_location = self.point.point_from_heading(defense_heading, self.size * AIR_DISTANCE_FACTOR)
self.air_attackers_location = self.point.point_from_heading(heading, self.size * AIR_DISTANCE_FACTOR)
self.air_defenders_location = self.point.point_from_heading(_opposite_heading(heading), self.size * AIR_DISTANCE_FACTOR)

View File

@ -16,6 +16,10 @@ class NameGenerator:
def next_intercept_group_name(self): def next_intercept_group_name(self):
self.number += 1 self.number += 1
return "Intercept Unit {}".format(self.number) return "Intercept Unit {}".format(self.number)
def next_ground_group_name(self):
self.number += 1
return "AA Unit {}".format(self.number)
namegen = NameGenerator() namegen = NameGenerator()

View File

@ -1,5 +0,0 @@
import dcs
class ControlPoint:
def __init__(self):
pass

11
theater/base.py Normal file
View File

@ -0,0 +1,11 @@
import typing
import dcs
from .controlpoint import *
from dcs.planes import *
from dcs.vehicles import *
class Base:
aircraft = [] # type: typing.Dict[PlaneType, int]
armor = [] # type: typing.Dict[Armor, int]

14
theater/caucasus.py Normal file
View File

@ -0,0 +1,14 @@
from dcs.terrain import caucasus
from .conflicttheater import *
from .base import *
class CaucasusTheater(ConflictTheater):
sukhumi = ControlPoint(caucasus.Sukhumi().position, 1000, 5, True, Base())
krymsk = ControlPoint(caucasus.Krymsk().position, 1500, 10, False, None)
kransnodar = ControlPoint(caucasus.KrasnodarCenter().position, 3000, 30, False, Base())
def __init__(self):
self.add_controlpoint(self.sukhumi, [self.krymsk])
self.add_controlpoint(self.krymsk, [self.sukhumi, self.kransnodar])
self.add_controlpoint(self.kransnodar, [self.krymsk])

View File

@ -0,0 +1,16 @@
import typing
import dcs
from .controlpoint import *
class ConflictTheater:
controlpoints = [] # type: typing.Collection[ControlPoint]
def add_controlpoint(self, point: ControlPoint, connected_to: typing.Collection[ControlPoint]):
for connected_point in connected_to:
point.connect(to=connected_point)
self.controlpoints.append(point)
def player_bases(self) -> typing.Collection[ControlPoint]:
return [point for point in self.controlpoints if point.captured and point.base]

30
theater/controlpoint.py Normal file
View File

@ -0,0 +1,30 @@
import typing
import dcs
from dcs.mapping import *
from dcs.country import *
from gen.conflictgen import Conflict
from .base import *
class ControlPoint:
connected_points = [] # type: typing.Collection[ControlPoint]
point = None # type: Point
captured = False
base = None # type: Base
def __init__(self, point: Point, size: int, importance: int, captured: bool, base: Base):
self.point = point
self.size = size
self.importance = importance
self.captured = captured
self.base = base
def connect(self, to):
self.connected_points.append(to)
def conflict_attack(self, x, attacker: Country, defender: Country) -> Conflict:
#heading = heading_between_points(self.point.x, self.point.y, x.point.x, x.point.y)
return Conflict(attacker, 0, defender, 90, self.point, self.size)