update to ground objects parser; waypoints in briefings & general briefings update; minor fixes

This commit is contained in:
Vasyl Horbachenko 2018-09-13 05:09:57 +03:00
parent 03fc17fae6
commit edf9efddf9
18 changed files with 96 additions and 40 deletions

View File

@ -49,13 +49,13 @@ Events:
* InfantryTransportEvent - helicopter infantry transport * InfantryTransportEvent - helicopter infantry transport
""" """
EVENT_PROBABILITIES = { EVENT_PROBABILITIES = {
BaseAttackEvent: [100, 10], BaseAttackEvent: [100, 15],
FrontlineAttackEvent: [100, 0], FrontlineAttackEvent: [100, 0],
FrontlinePatrolEvent: [100, 0], FrontlinePatrolEvent: [100, 0],
StrikeEvent: [100, 0], StrikeEvent: [100, 0],
InterceptEvent: [25, 10], InterceptEvent: [25, 15],
InsurgentAttackEvent: [0, 10], InsurgentAttackEvent: [0, 10],
NavalInterceptEvent: [25, 10], NavalInterceptEvent: [25, 15],
InfantryTransportEvent: [25, 0], InfantryTransportEvent: [25, 0],
} }

View File

@ -59,5 +59,11 @@ class BaseAttackOperation(Operation):
self.briefinggen.title = "Base attack" self.briefinggen.title = "Base attack"
self.briefinggen.description = "The goal of an attacker is to lower defender presence by destroying their armor and aircraft. Base will be considered captured if attackers on the ground overrun the defenders. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu." self.briefinggen.description = "The goal of an attacker is to lower defender presence by destroying their armor and aircraft. Base will be considered captured if attackers on the ground overrun the defenders. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu."
if self.game.player == self.attacker_name:
self.briefinggen.append_waypoint("TARGET")
else:
pass
super(BaseAttackOperation, self).generate() super(BaseAttackOperation, self).generate()

View File

@ -51,4 +51,6 @@ class FrontlineAttackOperation(Operation):
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."
self.briefinggen.append_waypoint("CAS AREA IP")
self.briefinggen.append_waypoint("CAS AREA EGRESS")
super(FrontlineAttackOperation, self).generate() super(FrontlineAttackOperation, self).generate()

View File

@ -51,4 +51,6 @@ class FrontlinePatrolOperation(Operation):
self.briefinggen.title = "Frontline CAP" self.briefinggen.title = "Frontline CAP"
self.briefinggen.description = "Providing CAP support for ground units attacking enemy lines. Enemy will scramble its CAS and your task is to intercept it. Operation will be considered successful if total number of friendly units will be lower than enemy by at least a factor of 0.8 (i.e. with 12 units from both sides, there should be at least 8 friendly units alive), lowering targets strength as a result." self.briefinggen.description = "Providing CAP support for ground units attacking enemy lines. Enemy will scramble its CAS and your task is to intercept it. Operation will be considered successful if total number of friendly units will be lower than enemy by at least a factor of 0.8 (i.e. with 12 units from both sides, there should be at least 8 friendly units alive), lowering targets strength as a result."
self.briefinggen.append_waypoint("CAP AREA IP")
self.briefinggen.append_waypoint("CAP AREA EGRESS")
super(FrontlinePatrolOperation, self).generate() super(FrontlinePatrolOperation, self).generate()

View File

@ -36,6 +36,7 @@ class InfantryTransportOperation(Operation):
self.briefinggen.title = "Infantry transport" self.briefinggen.title = "Infantry transport"
self.briefinggen.description = "Helicopter operation to transport infantry troops from the base to the front line. Lowers target strength" self.briefinggen.description = "Helicopter operation to transport infantry troops from the base to the front line. Lowers target strength"
self.briefinggen.append_waypoint("DROP POINT")
# TODO: horrible, horrible hack # TODO: horrible, horrible hack
# this will disable vehicle activation triggers, # this will disable vehicle activation triggers,

View File

@ -28,10 +28,11 @@ class InsurgentAttackOperation(Operation):
conflict=conflict) conflict=conflict)
def generate(self): def generate(self):
self.airgen.generate_defense(*assigned_units_split(self.strikegroup), at=self.defenders_starting_position) self.airgen.generate_defenders_cas(*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"
self.briefinggen.description = "Destroy vehicles of insurgents in close proximity of the friendly base. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu." self.briefinggen.description = "Destroy vehicles of insurgents in close proximity of the friendly base. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu."
self.briefinggen.append_waypoint("TARGET")
super(InsurgentAttackOperation, self).generate() super(InsurgentAttackOperation, self).generate()

View File

@ -56,7 +56,14 @@ class InterceptOperation(Operation):
self.airgen.generate_interception(*assigned_units_split(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"
if self.game.player == self.attacker_name:
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.append_waypoint("TARGET")
for unit_type, count in self.transport.items():
self.briefinggen.append_target("{} ({})".format(db.unit_type_name(unit_type), count))
else:
self.briefinggen.description = "Escort friendly supply transport aircraft. Operation will be considered failed if most of the targets are destroyed, lowering CP strength as a result"
super(InterceptOperation, self).generate() super(InterceptOperation, self).generate()

View File

@ -48,7 +48,13 @@ class NavalInterceptionOperation(Operation):
) )
self.briefinggen.title = "Naval Intercept" self.briefinggen.title = "Naval Intercept"
self.briefinggen.description = "Destroy supply transport ships. Lowers target strength. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu." if self.game.player == self.attacker_name:
self.briefinggen.description = "Destroy supply transport ships. Lowers target strength. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu."
for unit_type, count in self.targets:
self.briefinggen.append_target("{} ({})".format(db.unit_type_name(unit_type), count))
else:
self.briefinggen.description = "Protect supply transport ships."
self.briefinggen.append_waypoint("TARGET")
super(NavalInterceptionOperation, self).generate() super(NavalInterceptionOperation, self).generate()

View File

@ -111,8 +111,6 @@ class Operation:
else: else:
self.envgen.load(self.environment_settings) self.envgen.load(self.environment_settings)
# @TODO: ADD WAYPOINT INFORMATION!
# main frequencies # main frequencies
self.briefinggen.append_frequency("Flight", "251 MHz AM") self.briefinggen.append_frequency("Flight", "251 MHz AM")
if self.conflict.from_cp.is_global or self.conflict.to_cp.is_global: if self.conflict.from_cp.is_global or self.conflict.to_cp.is_global:

View File

@ -47,7 +47,8 @@ class StrikeOperation(Operation):
category_counters[object.category] = category_counters.get(object.category, 0) + 1 category_counters[object.category] = category_counters.get(object.category, 0) + 1
markpoint_name = "{}{}".format(object.name_abbrev, category_counters[object.category]) markpoint_name = "{}{}".format(object.name_abbrev, category_counters[object.category])
targets.append((markpoint_name, object.position)) targets.append((markpoint_name, object.position))
self.briefinggen.append_target(str(object), markpoint_name) self.briefinggen.append_target(str(object))
self.briefinggen.append_waypoint("TARGET {} (TP {})".format(str(object), markpoint_name))
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]))

View File

@ -449,10 +449,7 @@ 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))
group.task = CAP.name group.task = CAP.name
group.points[0].tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
heading = group.position.heading_between_point(self.conflict.position)
initial_wayp = group.add_waypoint(group.position.point_from_heading(heading, WORKAROUND_WAYP_DIST), INTERCEPTION_ALT, INTERCEPTION_AIRSPEED)
initial_wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
wayp = group.add_waypoint(self.conflict.position, WARM_START_ALTITUDE, INTERCEPTION_AIRSPEED) wayp = group.add_waypoint(self.conflict.position, WARM_START_ALTITUDE, INTERCEPTION_AIRSPEED)
wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE)) wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))

View File

@ -12,6 +12,7 @@ class BriefingGenerator:
title = "" # type: str title = "" # type: str
description = "" # type: str description = "" # type: str
targets = None # type: typing.List[typing.Tuple[str, str]] targets = None # type: typing.List[typing.Tuple[str, str]]
waypoints = None # type: typing.List[str]
def __init__(self, mission: Mission, conflict: Conflict, game): def __init__(self, mission: Mission, conflict: Conflict, game):
self.m = mission self.m = mission
@ -20,6 +21,7 @@ class BriefingGenerator:
self.freqs = [] self.freqs = []
self.targets = [] self.targets = []
self.waypoints = []
def append_frequency(self, name: str, frequency: str): def append_frequency(self, name: str, frequency: str):
self.freqs.append((name, frequency)) self.freqs.append((name, frequency))
@ -27,7 +29,14 @@ class BriefingGenerator:
def append_target(self, description: str, markpoint: str = None): def append_target(self, description: str, markpoint: str = None):
self.targets.append((description, markpoint)) self.targets.append((description, markpoint))
def append_waypoint(self, description: str):
self.waypoints.append(description)
def generate(self): def generate(self):
self.waypoints.insert(0, "INITIAL")
self.waypoints.append("RTB")
self.waypoints.append("RTB Landing")
description = "" description = ""
if self.title: if self.title:
@ -43,7 +52,12 @@ class BriefingGenerator:
if self.targets: if self.targets:
description += "\n\nTARGETS:" description += "\n\nTARGETS:"
for name, tp in self.targets: for i, (name, tp) in enumerate(self.targets):
description += "\n{} {}".format(name, "(TP {})".format(tp) if tp else "") description += "\n#{} {} {}".format(i+1, name, "(TP {})".format(tp) if tp else "")
if self.waypoints:
description += "\n\nWAYPOINTS:"
for i, descr in enumerate(self.waypoints):
description += "\n#{}: {}".format(i+1, descr)
self.m.set_description_text(description) self.m.set_description_text(description)

Binary file not shown.

View File

@ -3,20 +3,41 @@ import typing
from dcs.mission import Mission from dcs.mission import Mission
from dcs.mapping import Point from dcs.mapping import Point
from dcs.terrain import *
from dcs.unitgroup import VehicleGroup, StaticGroup from dcs.unitgroup import VehicleGroup, StaticGroup
from dcs.unit import * from dcs.unit import *
from dcs.statics import warehouse_map, fortification_map from dcs.statics import warehouse_map, fortification_map
from game import db from game import db
from gen.groundobjectsgen import TheaterGroundObject from gen.groundobjectsgen import TheaterGroundObject
from theater.caucasus import CaucasusTheater
from theater.persiangulf import PersianGulfTheater
from theater.nevada import NevadaTheater
m = Mission() m = Mission()
m.load_file("./cau_groundobjects.miz") m.load_file("resources/tools/cau_groundobjects.miz")
if isinstance(m.terrain, Caucasus):
theater = CaucasusTheater(load_ground_objects=False)
elif isinstance(m.terrain, PersianGulf):
theater = PersianGulfTheater(load_ground_objects=False)
elif isinstance(m.terrain, Nevada):
theater = NevadaTheater(load_ground_objects=False)
else:
assert False
def parse_name(name: str) -> int: def closest_cp(location: Point) -> (int, float):
first_part = name.split()[0].split("|") global theater
return int(first_part[0]) if len(first_part) == 1 else int(first_part[1]) min_distance, min_cp = None, None
for cp in theater.controlpoints:
if not min_distance or location.distance_to_point(cp.position) < min_distance:
min_distance = location.distance_to_point(cp.position)
min_cp = cp.id
assert min_cp is not None
return min_cp
if __name__ == "__main__": if __name__ == "__main__":
@ -27,11 +48,6 @@ if __name__ == "__main__":
theater_object = TheaterGroundObject() theater_object = TheaterGroundObject()
theater_object.object_id = len(theater_objects) + 1 theater_object.object_id = len(theater_objects) + 1
try:
theater_object.cp_id = parse_name(str(unit.name))
except Exception as e:
theater_object.cp_id = parse_name(str(group.name))
theater_object.position = unit.position theater_object.position = unit.position
theater_object.heading = unit.heading theater_object.heading = unit.heading
@ -40,15 +56,7 @@ if __name__ == "__main__":
else: else:
theater_object.dcs_identifier = unit.type theater_object.dcs_identifier = unit.type
airport_distance = m.terrain.airport_by_id(theater_object.cp_id).position.distance_to_point(theater_object.position)
if airport_distance > 150000:
print("Object {} {} is placed {}m from airport {}!".format(theater_object.dcs_identifier,
group.name,
airport_distance,
m.terrain.airport_by_id(theater_object.cp_id)))
assert theater_object.dcs_identifier assert theater_object.dcs_identifier
assert theater_object.cp_id
assert theater_object.object_id assert theater_object.object_id
theater_objects.append(theater_object) theater_objects.append(theater_object)
@ -61,11 +69,15 @@ if __name__ == "__main__":
continue continue
elif object_a.group_id: elif object_a.group_id:
object_b.group_id = object_a.group_id object_b.group_id = object_a.group_id
object_b.cp_id = object_a.cp_id
elif object_b.group_id: elif object_b.group_id:
object_a.group_id = object_b.group_id object_a.group_id = object_b.group_id
object_a.cp_id = object_b.cp_id
else: else:
object_a.group_id = group_ids object_a.group_id = group_ids
object_b.group_id = group_ids object_b.group_id = group_ids
object_a.cp_id = closest_cp(object_a.position)
object_b.cp_id = object_a.cp_id
group_ids += 1 group_ids += 1
assert object_a.cp_id == object_b.cp_id, "Object {} and {} are placed in group with different airports!".format(object_a.string_identifier, object_b.string_identifier) assert object_a.cp_id == object_b.cp_id, "Object {} and {} are placed in group with different airports!".format(object_a.string_identifier, object_b.string_identifier)
@ -73,15 +85,23 @@ if __name__ == "__main__":
for a in theater_objects: for a in theater_objects:
if not a.group_id: if not a.group_id:
a.group_id = group_ids a.group_id = group_ids
a.cp_id = closest_cp(a.position)
group_ids += 1 group_ids += 1
print("Total {} objects".format(len(theater_objects))) with open("resources/cau_groundobjects.p", "wb") as f:
with open("../cau_groundobjects.p", "wb") as f:
result = {} result = {}
for theater_object in theater_objects: for theater_object in theater_objects:
assert theater_object.cp_id
assert theater_object.group_id
assert theater_object.object_id
if theater_object.cp_id not in result: if theater_object.cp_id not in result:
result[theater_object.cp_id] = [] result[theater_object.cp_id] = []
result[theater_object.cp_id].append(theater_object) result[theater_object.cp_id].append(theater_object)
print("Total {} objects".format(len(theater_objects)))
for cp_id, objects in result.items():
print("{}: total {} objects".format(m.terrain.airport_by_id(cp_id), len(objects)))
pickle.dump(result, f) pickle.dump(result, f)

View File

@ -1,3 +1,3 @@
from .controlpoint import * from .controlpoint import *
from .conflicttheater import * from .conflicttheater import *
from .base import * from .base import *

View File

@ -44,7 +44,7 @@ class CaucasusTheater(ConflictTheater):
carrier_1 = ControlPoint.carrier("Carrier", mapping.Point(-305810.6875, 406399.1875)) carrier_1 = ControlPoint.carrier("Carrier", mapping.Point(-305810.6875, 406399.1875))
def __init__(self): def __init__(self, load_ground_objects=True):
super(CaucasusTheater, self).__init__() super(CaucasusTheater, self).__init__()
self.add_controlpoint(self.soganlug, connected_to=[self.kutaisi, self.beslan]) self.add_controlpoint(self.soganlug, connected_to=[self.kutaisi, self.beslan])
@ -73,8 +73,9 @@ class CaucasusTheater(ConflictTheater):
self.carrier_1.captured = True self.carrier_1.captured = True
self.soganlug.captured = True self.soganlug.captured = True
with open("resources/cau_groundobjects.p", "rb") as f: if load_ground_objects:
self.set_groundobject(pickle.load(f)) with open("resources/cau_groundobjects.p", "rb") as f:
self.set_groundobject(pickle.load(f))
def add_controlpoint(self, point: ControlPoint, connected_to: typing.Collection[ControlPoint] = []): def add_controlpoint(self, point: ControlPoint, connected_to: typing.Collection[ControlPoint] = []):
point.name = " ".join(re.split(r"[ -]", point.name)[:1]) point.name = " ".join(re.split(r"[ -]", point.name)[:1])

View File

@ -32,7 +32,7 @@ class NevadaTheater(ConflictTheater):
jean = ControlPoint.from_airport(nevada.Jean_Airport, LAND, SIZE_REGULAR, 1.2) jean = ControlPoint.from_airport(nevada.Jean_Airport, LAND, SIZE_REGULAR, 1.2)
laughlin = ControlPoint.from_airport(nevada.Laughlin_Airport, LAND, SIZE_LARGE, IMPORTANCE_HIGH) laughlin = ControlPoint.from_airport(nevada.Laughlin_Airport, LAND, SIZE_LARGE, IMPORTANCE_HIGH)
def __init__(self): def __init__(self, load_ground_objects=True):
super(NevadaTheater, self).__init__() super(NevadaTheater, self).__init__()
self.add_controlpoint(self.mina, connected_to=[self.tonopah]) self.add_controlpoint(self.mina, connected_to=[self.tonopah])

View File

@ -45,7 +45,7 @@ class PersianGulfTheater(ConflictTheater):
west_carrier = ControlPoint.carrier("East carrier", Point(-100531.972946, 60939.275818)) west_carrier = ControlPoint.carrier("East carrier", Point(-100531.972946, 60939.275818))
def __init__(self): def __init__(self, load_ground_objects=True):
super(PersianGulfTheater, self).__init__() super(PersianGulfTheater, self).__init__()
self.add_controlpoint(self.shiraz, connected_to=[self.lar, self.kerman]) self.add_controlpoint(self.shiraz, connected_to=[self.lar, self.kerman])