mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
WIP on CAP, and AI units can starts from ground uncontrolled instead of using late activation.
This commit is contained in:
parent
c73290eebb
commit
4373d89661
@ -1,12 +1,12 @@
|
|||||||
from dcs.action import ActivateGroup
|
from dcs.action import ActivateGroup, AITaskPush
|
||||||
from dcs.condition import TimeAfter, CoalitionHasAirdrome
|
from dcs.condition import TimeAfter, CoalitionHasAirdrome
|
||||||
from dcs.helicopters import UH_1H
|
from dcs.helicopters import UH_1H
|
||||||
from dcs.terrain.terrain import NoParkingSlotError
|
from dcs.terrain.terrain import NoParkingSlotError
|
||||||
from dcs.triggers import TriggerOnce, Event
|
from dcs.triggers import TriggerOnce, Event
|
||||||
|
|
||||||
from game.settings import Settings
|
from game.settings import Settings
|
||||||
from gen.flights.ai_flight_planner import FlightPlanner
|
from gen.flights.ai_flight_planner import FlightPlanner, CAP_DEFAULT_ENGAGE_DISTANCE, nm_to_meter
|
||||||
from gen.flights.flight import Flight, FlightType
|
from gen.flights.flight import Flight, FlightType, FlightWaypointType
|
||||||
from .conflictgen import *
|
from .conflictgen import *
|
||||||
from .naming import *
|
from .naming import *
|
||||||
from .triggergen import TRIGGER_WAYPOINT_OFFSET
|
from .triggergen import TRIGGER_WAYPOINT_OFFSET
|
||||||
@ -354,23 +354,48 @@ class AircraftConflictGenerator:
|
|||||||
|
|
||||||
def setup_group_activation_trigger(self, flight, group):
|
def setup_group_activation_trigger(self, flight, group):
|
||||||
if flight.scheduled_in > 0 and flight.client_count == 0:
|
if flight.scheduled_in > 0 and flight.client_count == 0:
|
||||||
group.late_activation = True
|
|
||||||
activation_trigger = TriggerOnce(Event.NoEvent, "LiberationActivationTriggerForGroup" + str(group.id))
|
|
||||||
activation_trigger.add_condition(TimeAfter(seconds=flight.scheduled_in*60))
|
|
||||||
|
|
||||||
if(flight.from_cp.cptype == ControlPointType.AIRBASE):
|
if flight.start_type != "In Flight":
|
||||||
if not flight.from_cp.captured:
|
group.late_activation = False
|
||||||
activation_trigger.add_condition(CoalitionHasAirdrome(self.game.get_player_coalition_id(), flight.from_cp.id))
|
group.uncontrolled = True
|
||||||
else:
|
|
||||||
activation_trigger.add_condition(CoalitionHasAirdrome(self.game.get_enemy_coalition_id(), flight.from_cp.id))
|
activation_trigger = TriggerOnce(Event.NoEvent, "LiberationControlTriggerForGroup" + str(group.id))
|
||||||
|
activation_trigger.add_condition(TimeAfter(seconds=flight.scheduled_in * 60))
|
||||||
|
if (flight.from_cp.cptype == ControlPointType.AIRBASE):
|
||||||
|
if flight.from_cp.captured:
|
||||||
|
activation_trigger.add_condition(
|
||||||
|
CoalitionHasAirdrome(self.game.get_player_coalition_id(), flight.from_cp.id))
|
||||||
|
else:
|
||||||
|
activation_trigger.add_condition(
|
||||||
|
CoalitionHasAirdrome(self.game.get_enemy_coalition_id(), flight.from_cp.id))
|
||||||
|
|
||||||
|
group.add_trigger_action(StartCommand())
|
||||||
|
activation_trigger.add_action(AITaskPush(group.id, len(group.tasks)))
|
||||||
|
self.m.triggerrules.triggers.append(activation_trigger)
|
||||||
|
print("ADD TRIG CTRL")
|
||||||
|
else:
|
||||||
|
group.late_activation = True
|
||||||
|
activation_trigger = TriggerOnce(Event.NoEvent, "LiberationActivationTriggerForGroup" + str(group.id))
|
||||||
|
activation_trigger.add_condition(TimeAfter(seconds=flight.scheduled_in*60))
|
||||||
|
|
||||||
|
if(flight.from_cp.cptype == ControlPointType.AIRBASE):
|
||||||
|
if flight.from_cp.captured:
|
||||||
|
activation_trigger.add_condition(CoalitionHasAirdrome(self.game.get_player_coalition_id(), flight.from_cp.id))
|
||||||
|
else:
|
||||||
|
activation_trigger.add_condition(CoalitionHasAirdrome(self.game.get_enemy_coalition_id(), flight.from_cp.id))
|
||||||
|
|
||||||
|
|
||||||
activation_trigger.add_action(ActivateGroup(group.id))
|
activation_trigger.add_action(ActivateGroup(group.id))
|
||||||
self.m.triggerrules.triggers.append(activation_trigger)
|
self.m.triggerrules.triggers.append(activation_trigger)
|
||||||
|
|
||||||
def generate_planned_flight(self, cp, country, flight:Flight):
|
def generate_planned_flight(self, cp, country, flight:Flight):
|
||||||
try:
|
try:
|
||||||
if flight.start_type == "In Flight" or flight.client_count == 0:
|
if flight.client_count == 0:
|
||||||
|
flight.start_type = "Warm"
|
||||||
|
|
||||||
|
print(flight.start_type)
|
||||||
|
|
||||||
|
if flight.start_type == "In Flight":
|
||||||
group = self._generate_group(
|
group = self._generate_group(
|
||||||
name=namegen.next_unit_name(country, cp.id, flight.unit_type),
|
name=namegen.next_unit_name(country, cp.id, flight.unit_type),
|
||||||
side=country,
|
side=country,
|
||||||
@ -406,6 +431,7 @@ class AircraftConflictGenerator:
|
|||||||
start_type=st)
|
start_type=st)
|
||||||
except Exception:
|
except Exception:
|
||||||
# Generated when there is no place on Runway or on Parking Slots
|
# Generated when there is no place on Runway or on Parking Slots
|
||||||
|
flight.start_type = "In Flight"
|
||||||
group = self._generate_group(
|
group = self._generate_group(
|
||||||
name=namegen.next_unit_name(country, cp.id, flight.unit_type),
|
name=namegen.next_unit_name(country, cp.id, flight.unit_type),
|
||||||
side=country,
|
side=country,
|
||||||
@ -427,8 +453,27 @@ class AircraftConflictGenerator:
|
|||||||
|
|
||||||
def setup_group_as_cap_flight(self, group, flight):
|
def setup_group_as_cap_flight(self, group, flight):
|
||||||
self._setup_group(group, CAP, flight.client_count)
|
self._setup_group(group, CAP, flight.client_count)
|
||||||
for point in flight.points:
|
|
||||||
group.add_waypoint(Point(point.x,point.y), point.alt)
|
#group.points[0].tasks.clear()
|
||||||
|
#group.tasks.clear()
|
||||||
|
#group.tasks.append(EngageTargets(max_distance=40, targets=[Targets.All.Air]))
|
||||||
|
#group.tasks.append(EngageTargets(max_distance=nm_to_meter(120), targets=[Targets.All.Air]))
|
||||||
|
|
||||||
|
for i, point in enumerate(flight.points):
|
||||||
|
|
||||||
|
if not point.only_for_player or (point.only_for_player and flight.client_count > 0):
|
||||||
|
pt = group.add_waypoint(Point(point.x, point.y), point.alt)
|
||||||
|
|
||||||
|
if point.waypoint_type == FlightWaypointType.PATROL_TRACK:
|
||||||
|
action = OrbitAction(altitude=pt.alt, pattern=OrbitAction.OrbitPattern.RaceTrack)
|
||||||
|
pt.tasks.append(action)
|
||||||
|
#for tgt in point.targets:
|
||||||
|
# if hasattr(tgt, "position"):
|
||||||
|
# engagetgt = EngageTargetsInZone(tgt.position, radius=CAP_DEFAULT_ENGAGE_DISTANCE, targets=[Targets.All.Air])
|
||||||
|
# pt.tasks.append(engagetgt)
|
||||||
|
elif point.waypoint_type == FlightWaypointType.LANDING_POINT:
|
||||||
|
pt.type = "Land"
|
||||||
|
|
||||||
|
|
||||||
def setup_group_as_cas_flight(self, group, flight):
|
def setup_group_as_cas_flight(self, group, flight):
|
||||||
group.task = CAS.name
|
group.task = CAS.name
|
||||||
|
|||||||
@ -6,7 +6,24 @@ import random
|
|||||||
from game import db
|
from game import db
|
||||||
from gen import Conflict
|
from gen import Conflict
|
||||||
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE
|
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE
|
||||||
from gen.flights.flight import Flight, FlightType, FlightWaypoint
|
from gen.flights.flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
|
||||||
|
|
||||||
|
|
||||||
|
def meter_to_feet(value_in_meter):
|
||||||
|
return int(3.28084 * value_in_meter)
|
||||||
|
|
||||||
|
|
||||||
|
def feet_to_meter(value_in_feet):
|
||||||
|
return int(float(value_in_feet)/3.048)
|
||||||
|
|
||||||
|
|
||||||
|
def meter_to_nm(value_in_meter):
|
||||||
|
return int(float(value_in_meter)*0.000539957)
|
||||||
|
|
||||||
|
|
||||||
|
def nm_to_meter(value_in_nm):
|
||||||
|
return int(float(value_in_nm)*1852)
|
||||||
|
|
||||||
|
|
||||||
# TODO : Ideally should be based on the aircraft type instead / Availability of fuel
|
# TODO : Ideally should be based on the aircraft type instead / Availability of fuel
|
||||||
STRIKE_MAX_RANGE = 1500000
|
STRIKE_MAX_RANGE = 1500000
|
||||||
@ -19,11 +36,15 @@ CAS_EVERY_X_MINUTES = 30
|
|||||||
SEAD_EVERY_X_MINUTES = 40
|
SEAD_EVERY_X_MINUTES = 40
|
||||||
STRIKE_EVERY_X_MINUTES = 40
|
STRIKE_EVERY_X_MINUTES = 40
|
||||||
|
|
||||||
INGRESS_EGRESS_DISTANCE = 45000
|
INGRESS_EGRESS_DISTANCE = nm_to_meter(45)
|
||||||
INGRESS_ALT = 6096 # 20k feet
|
INGRESS_ALT = feet_to_meter(20000)
|
||||||
EGRESS_ALT = 6096 # 20k feet
|
EGRESS_ALT = feet_to_meter(20000)
|
||||||
PATROL_ALT_RANGE = (3600, 9200)
|
PATROL_ALT_RANGE = (feet_to_meter(15000), feet_to_meter(33000))
|
||||||
NAV_ALT = 9144
|
NAV_ALT = 9144
|
||||||
|
PATTERN_ALTITUDE = feet_to_meter(5000)
|
||||||
|
|
||||||
|
CAP_DEFAULT_ENGAGE_DISTANCE = nm_to_meter(40)
|
||||||
|
|
||||||
|
|
||||||
class FlightPlanner:
|
class FlightPlanner:
|
||||||
|
|
||||||
@ -69,7 +90,7 @@ class FlightPlanner:
|
|||||||
|
|
||||||
self.commision_strike()
|
self.commision_strike()
|
||||||
|
|
||||||
# TODO : commision STRIKE / ANTISHIP
|
# TODO : commision ANTISHIP
|
||||||
|
|
||||||
def remove_flight(self, index):
|
def remove_flight(self, index):
|
||||||
try:
|
try:
|
||||||
@ -135,30 +156,81 @@ class FlightPlanner:
|
|||||||
ftype = FlightType.BARCAP if self.from_cp.is_carrier else FlightType.CAP
|
ftype = FlightType.BARCAP if self.from_cp.is_carrier else FlightType.CAP
|
||||||
flight = Flight(unit, 2, self.from_cp, ftype)
|
flight = Flight(unit, 2, self.from_cp, ftype)
|
||||||
|
|
||||||
# Flight path : fly over each ground object (TODO : improve)
|
|
||||||
flight.points = []
|
flight.points = []
|
||||||
flight.scheduled_in = offset + i*random.randint(CAP_EVERY_X_MINUTES-5, CAP_EVERY_X_MINUTES+5)
|
flight.scheduled_in = offset + i*random.randint(CAP_EVERY_X_MINUTES-5, CAP_EVERY_X_MINUTES+5)
|
||||||
|
|
||||||
patrol_alt = random.randint(PATROL_ALT_RANGE[0], PATROL_ALT_RANGE[1])
|
patrol_alt = random.randint(PATROL_ALT_RANGE[0], PATROL_ALT_RANGE[1])
|
||||||
|
|
||||||
patrolled = []
|
# Choose a location for CAP patrols (Either behind frontline, or to protect ground objects)
|
||||||
for ground_object in self.from_cp.ground_objects:
|
rng = random.randint(0,100)
|
||||||
if ground_object.group_id not in patrolled and not ground_object.airbase_group:
|
if rng < 80 and len(self._get_cas_locations()) > 0:
|
||||||
point = FlightWaypoint(ground_object.position.x, ground_object.position.y, patrol_alt)
|
loc = random.choice(self._get_cas_locations())
|
||||||
point.name = "Patrol point"
|
ingress, heading, distance = Conflict.frontline_vector(self.from_cp, loc, self.game.theater)
|
||||||
point.description = "Patrol #" + str(len(flight.points))
|
center = ingress.point_from_heading(heading, distance / 2)
|
||||||
point.pretty_name = "Patrol #" + str(len(flight.points))
|
orbit_center = center.point_from_heading(heading - 90, random.randint(nm_to_meter(6), nm_to_meter(15)))
|
||||||
flight.points.append(point)
|
radius = distance * 2
|
||||||
patrolled.append(ground_object.group_id)
|
orbit0p = orbit_center.point_from_heading(heading, radius)
|
||||||
|
orbit1p = orbit_center.point_from_heading(heading + 180, radius)
|
||||||
|
elif len(self.from_cp.ground_objects) > 0:
|
||||||
|
loc = random.choice(self.from_cp.ground_objects)
|
||||||
|
hdg = self.from_cp.position.heading_between_point(loc.position)
|
||||||
|
radius = random.randint(nm_to_meter(5), nm_to_meter(10))
|
||||||
|
orbit0p = loc.position.point_from_heading(hdg - 90, radius)
|
||||||
|
orbit1p = loc.position.point_from_heading(hdg + 90, radius)
|
||||||
|
else:
|
||||||
|
loc = self.from_cp.position.point_from_heading(random.randint(0, 360), random.randint(nm_to_meter(5), nm_to_meter(40)))
|
||||||
|
hdg = self.from_cp.position.heading_between_point(loc.position)
|
||||||
|
radius = random.randint(nm_to_meter(40), nm_to_meter(120))
|
||||||
|
orbit0p = loc.position.point_from_heading(hdg - 90, radius)
|
||||||
|
orbit1p = loc.position.point_from_heading(hdg + 90, radius)
|
||||||
|
|
||||||
if len(flight.points) == 0:
|
|
||||||
for i in range(3):
|
# Create points
|
||||||
pos = self.from_cp.position.point_from_heading(random.randint(0, 360), random.randint(30000, 80000))
|
ascend_heading = random.randint(0, 360)
|
||||||
point = FlightWaypoint(pos.x, pos.y, patrol_alt)
|
pos_ascend = self.from_cp.position.point_from_heading(ascend_heading, 30000)
|
||||||
point.name = "Patrol point"
|
ascend = FlightWaypoint(pos_ascend.x, pos_ascend.y, patrol_alt)
|
||||||
point.description = "Patrol #" + str(len(flight.points))
|
ascend.name = "ASCEND"
|
||||||
point.pretty_name = "Patrol #" + str(len(flight.points))
|
ascend.description = "Ascend to alt [" + str(meter_to_feet(patrol_alt)) + " ft]"
|
||||||
flight.points.append(point)
|
ascend.pretty_name = "Ascend to alt [" + str(meter_to_feet(patrol_alt)) + " ft]"
|
||||||
|
ascend.waypoint_type = FlightWaypointType.ASCEND_POINT
|
||||||
|
flight.points.append(ascend)
|
||||||
|
|
||||||
|
orbit0 = FlightWaypoint(orbit0p.x, orbit0p.y, patrol_alt)
|
||||||
|
orbit0.name = "ORBIT 0"
|
||||||
|
orbit0.description = "Standby between this point and the next one"
|
||||||
|
orbit0.pretty_name = "Orbit race-track start"
|
||||||
|
orbit0.waypoint_type = FlightWaypointType.PATROL_TRACK
|
||||||
|
flight.points.append(orbit0)
|
||||||
|
|
||||||
|
orbit1 = FlightWaypoint(orbit1p.x, orbit1p.y, patrol_alt)
|
||||||
|
orbit1.name = "ORBIT 1"
|
||||||
|
orbit1.description = "Standby between this point and the previous one"
|
||||||
|
orbit1.pretty_name = "Orbit race-track end"
|
||||||
|
orbit1.waypoint_type = FlightWaypointType.PATROL
|
||||||
|
flight.points.append(orbit1)
|
||||||
|
|
||||||
|
orbit0.targets.append(self.from_cp)
|
||||||
|
obj_added = []
|
||||||
|
for ground_object in self.from_cp.ground_objects:
|
||||||
|
if ground_object.obj_name not in obj_added and not ground_object.airbase_group:
|
||||||
|
orbit0.targets.append(ground_object)
|
||||||
|
obj_added.append(ground_object.obj_name)
|
||||||
|
|
||||||
|
descend = self.from_cp.position.point_from_heading(ascend_heading-180, 30000)
|
||||||
|
descend = FlightWaypoint(descend.x, descend.y, PATTERN_ALTITUDE)
|
||||||
|
descend.name = "DESCEND"
|
||||||
|
descend.description = "Descend to pattern alt [5000ft]"
|
||||||
|
descend.pretty_name = "Descend to pattern alt [5000ft]"
|
||||||
|
descend.waypoint_type = FlightWaypointType.DESCENT_POINT
|
||||||
|
flight.points.append(descend)
|
||||||
|
|
||||||
|
rtb = self.from_cp.position.point_from_heading(ascend_heading - 180, 30000)
|
||||||
|
rtb = FlightWaypoint(rtb.x, rtb.y, PATTERN_ALTITUDE)
|
||||||
|
rtb.name = "LANDING"
|
||||||
|
rtb.description = "RTB"
|
||||||
|
rtb.pretty_name = "RTB"
|
||||||
|
rtb.waypoint_type = FlightWaypointType.LANDING_POINT
|
||||||
|
flight.points.append(rtb)
|
||||||
|
|
||||||
self.cap_flights.append(flight)
|
self.cap_flights.append(flight)
|
||||||
self.flights.append(flight)
|
self.flights.append(flight)
|
||||||
@ -203,18 +275,21 @@ class FlightPlanner:
|
|||||||
ingress_point.name = "INGRESS"
|
ingress_point.name = "INGRESS"
|
||||||
ingress_point.pretty_name = "INGRESS"
|
ingress_point.pretty_name = "INGRESS"
|
||||||
ingress_point.description = "Ingress into CAS area"
|
ingress_point.description = "Ingress into CAS area"
|
||||||
|
ingress_point.waypoint_type = FlightWaypointType.INGRESS_CAS
|
||||||
flight.points.append(ingress_point)
|
flight.points.append(ingress_point)
|
||||||
|
|
||||||
center_point = FlightWaypoint(center.x, center.y, 1000)
|
center_point = FlightWaypoint(center.x, center.y, 1000)
|
||||||
center_point.description = "Provide CAS"
|
center_point.description = "Provide CAS"
|
||||||
center_point.name = "CAS"
|
center_point.name = "CAS"
|
||||||
center_point.pretty_name = "INGRESS"
|
center_point.pretty_name = "INGRESS"
|
||||||
|
center_point.waypoint_type = FlightWaypointType.CAS
|
||||||
flight.points.append(center_point)
|
flight.points.append(center_point)
|
||||||
|
|
||||||
egress_point = FlightWaypoint(egress.x, egress.y, 1000)
|
egress_point = FlightWaypoint(egress.x, egress.y, 1000)
|
||||||
egress_point.description = "Egress from CAS area"
|
egress_point.description = "Egress from CAS area"
|
||||||
egress_point.name = "EGRESS"
|
egress_point.name = "EGRESS"
|
||||||
egress_point.pretty_name = "EGRESS"
|
egress_point.pretty_name = "EGRESS"
|
||||||
|
egress_point.waypoint_type = FlightWaypointType.EGRESS
|
||||||
flight.points.append(egress_point)
|
flight.points.append(egress_point)
|
||||||
|
|
||||||
self.cas_flights.append(flight)
|
self.cas_flights.append(flight)
|
||||||
@ -262,23 +337,27 @@ class FlightPlanner:
|
|||||||
ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, INGRESS_ALT)
|
ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, INGRESS_ALT)
|
||||||
ingress_point.pretty_name = "INGRESS on " + location.obj_name
|
ingress_point.pretty_name = "INGRESS on " + location.obj_name
|
||||||
ingress_point.description = "INGRESS on " + location.obj_name
|
ingress_point.description = "INGRESS on " + location.obj_name
|
||||||
|
ingress_point.waypoint_type = FlightWaypointType.INGRESS_SEAD
|
||||||
flight.points.append(ingress_point)
|
flight.points.append(ingress_point)
|
||||||
|
|
||||||
point = FlightWaypoint(location.position.x, location.position.y, 1000)
|
point = FlightWaypoint(location.position.x, location.position.y, 0)
|
||||||
if flight.flight_type == FlightType.DEAD:
|
if flight.flight_type == FlightType.DEAD:
|
||||||
point.description = "SEAD on " + location.obj_name
|
point.description = "SEAD on " + location.obj_name
|
||||||
point.pretty_name = "SEAD on " + location.obj_name
|
point.pretty_name = "SEAD on " + location.obj_name
|
||||||
|
point.only_for_player = True
|
||||||
else:
|
else:
|
||||||
point.description = "DEAD on " + location.obj_name
|
point.description = "DEAD on " + location.obj_name
|
||||||
point.pretty_name = "DEAD on " + location.obj_name
|
point.pretty_name = "DEAD on " + location.obj_name
|
||||||
|
point.only_for_player = True
|
||||||
|
|
||||||
point.targets.append(location)
|
ingress_point.targets.append(location)
|
||||||
flight.points.append(point)
|
flight.points.append(point)
|
||||||
|
|
||||||
egress_pos = location.position.point_from_heading(egress_heading, INGRESS_EGRESS_DISTANCE)
|
egress_pos = location.position.point_from_heading(egress_heading, INGRESS_EGRESS_DISTANCE)
|
||||||
egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, EGRESS_ALT)
|
egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, EGRESS_ALT)
|
||||||
egress_point.pretty_name = "EGRESS on " + location.obj_name
|
egress_point.pretty_name = "EGRESS on " + location.obj_name
|
||||||
egress_point.description = "EGRESS on " + location.obj_name
|
egress_point.description = "EGRESS on " + location.obj_name
|
||||||
|
egress_point.waypoint_type = FlightWaypointType.EGRESS
|
||||||
flight.points.append(egress_point)
|
flight.points.append(egress_point)
|
||||||
|
|
||||||
self.sead_flights.append(flight)
|
self.sead_flights.append(flight)
|
||||||
|
|||||||
@ -30,6 +30,24 @@ class FlightType(Enum):
|
|||||||
EWAR = 16
|
EWAR = 16
|
||||||
|
|
||||||
|
|
||||||
|
class FlightWaypointType(Enum):
|
||||||
|
TAKEOFF = 0 # Take off point
|
||||||
|
ASCEND_POINT = 1 # Ascension point after take off
|
||||||
|
PATROL = 2 # Patrol point
|
||||||
|
PATROL_TRACK = 3 # Patrol race track
|
||||||
|
NAV = 4 # Nav point
|
||||||
|
INGRESS_STRIKE = 5 # Ingress strike (For generator, means that this should have bombing on next TARGET_POINT points)
|
||||||
|
INGRESS_SEAD = 6 # Ingress sead (For generator, means that this should attack groups on TARGET_GROUP_LOC points)
|
||||||
|
INGRESS_CAS = 7 # Ingress cas (should start CAS task)
|
||||||
|
CAS = 8 # Should do CAS there
|
||||||
|
EGRESS = 9 # Should stop attack
|
||||||
|
DESCENT_POINT = 10 # Should start descending to pattern alt
|
||||||
|
LANDING_POINT = 11 # Should land there
|
||||||
|
TARGET_POINT = 12 # A target building or static object, position
|
||||||
|
TARGET_GROUP_LOC = 13 # A target group approximate location
|
||||||
|
TARGET_SHIP = 14 # A target ship known location
|
||||||
|
|
||||||
|
|
||||||
class FlightWaypoint:
|
class FlightWaypoint:
|
||||||
|
|
||||||
def __init__(self, x: float, y: float, alt=0):
|
def __init__(self, x: float, y: float, alt=0):
|
||||||
@ -41,6 +59,8 @@ class FlightWaypoint:
|
|||||||
self.targets = []
|
self.targets = []
|
||||||
self.obj_name = ""
|
self.obj_name = ""
|
||||||
self.pretty_name = ""
|
self.pretty_name = ""
|
||||||
|
self.waypoint_type = FlightWaypointType.TAKEOFF # type: FlightWaypointType
|
||||||
|
self.only_for_player = False
|
||||||
|
|
||||||
|
|
||||||
class Flight:
|
class Flight:
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
pydcs>=0.9.4
|
pydcs>=0.9.4
|
||||||
Pyside2>=5.13.0
|
Pyside2>=5.13.0
|
||||||
pyinstaller==3.5
|
pyinstaller==3.5
|
||||||
|
pyproj==2.6.1.post1
|
||||||
|
|||||||
@ -2,156 +2,150 @@ local unitPayloads = {
|
|||||||
["name"] = "Su-24M",
|
["name"] = "Su-24M",
|
||||||
["payloads"] = {
|
["payloads"] = {
|
||||||
[1] = {
|
[1] = {
|
||||||
["name"] = "ANTISHIP",
|
|
||||||
["pylons"] = {
|
|
||||||
[1] = {
|
|
||||||
["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}",
|
|
||||||
["num"] = 1,
|
|
||||||
},
|
|
||||||
[2] = {
|
|
||||||
["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}",
|
|
||||||
["num"] = 2,
|
|
||||||
},
|
|
||||||
[3] = {
|
|
||||||
["CLSID"] = "{0519A264-0AB6-11d6-9193-00A0249B6F00}",
|
|
||||||
["num"] = 5,
|
|
||||||
},
|
|
||||||
[4] = {
|
|
||||||
["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}",
|
|
||||||
["num"] = 7,
|
|
||||||
},
|
|
||||||
[5] = {
|
|
||||||
["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}",
|
|
||||||
["num"] = 8,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
["tasks"] = {
|
|
||||||
[1] = 29,
|
|
||||||
[2] = 30,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[2] = {
|
|
||||||
["name"] = "CAS",
|
|
||||||
["pylons"] = {
|
|
||||||
[1] = {
|
|
||||||
["CLSID"] = "{292960BB-6518-41AC-BADA-210D65D5073C}",
|
|
||||||
["num"] = 1,
|
|
||||||
},
|
|
||||||
[2] = {
|
|
||||||
["CLSID"] = "{292960BB-6518-41AC-BADA-210D65D5073C}",
|
|
||||||
["num"] = 2,
|
|
||||||
},
|
|
||||||
[3] = {
|
|
||||||
["CLSID"] = "{292960BB-6518-41AC-BADA-210D65D5073C}",
|
|
||||||
["num"] = 7,
|
|
||||||
},
|
|
||||||
[4] = {
|
|
||||||
["CLSID"] = "{292960BB-6518-41AC-BADA-210D65D5073C}",
|
|
||||||
["num"] = 8,
|
|
||||||
},
|
|
||||||
[5] = {
|
|
||||||
["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}",
|
|
||||||
["num"] = 6,
|
|
||||||
},
|
|
||||||
[6] = {
|
|
||||||
["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}",
|
|
||||||
["num"] = 3,
|
|
||||||
},
|
|
||||||
[7] = {
|
|
||||||
["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}",
|
|
||||||
["num"] = 4,
|
|
||||||
},
|
|
||||||
[8] = {
|
|
||||||
["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}",
|
|
||||||
["num"] = 5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
["tasks"] = {
|
|
||||||
[1] = 31,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[3] = {
|
|
||||||
["name"] = "STRIKE",
|
|
||||||
["pylons"] = {
|
|
||||||
[1] = {
|
|
||||||
["CLSID"] = "{4203753F-8198-4E85-9924-6F8FF679F9FF}",
|
|
||||||
["num"] = 1,
|
|
||||||
},
|
|
||||||
[2] = {
|
|
||||||
["CLSID"] = "{4203753F-8198-4E85-9924-6F8FF679F9FF}",
|
|
||||||
["num"] = 2,
|
|
||||||
},
|
|
||||||
[3] = {
|
|
||||||
["CLSID"] = "{4203753F-8198-4E85-9924-6F8FF679F9FF}",
|
|
||||||
["num"] = 3,
|
|
||||||
},
|
|
||||||
[4] = {
|
|
||||||
["CLSID"] = "{4203753F-8198-4E85-9924-6F8FF679F9FF}",
|
|
||||||
["num"] = 4,
|
|
||||||
},
|
|
||||||
[5] = {
|
|
||||||
["CLSID"] = "{4203753F-8198-4E85-9924-6F8FF679F9FF}",
|
|
||||||
["num"] = 5,
|
|
||||||
},
|
|
||||||
[6] = {
|
|
||||||
["CLSID"] = "{4203753F-8198-4E85-9924-6F8FF679F9FF}",
|
|
||||||
["num"] = 6,
|
|
||||||
},
|
|
||||||
[7] = {
|
|
||||||
["CLSID"] = "{4203753F-8198-4E85-9924-6F8FF679F9FF}",
|
|
||||||
["num"] = 7,
|
|
||||||
},
|
|
||||||
[8] = {
|
|
||||||
["CLSID"] = "{4203753F-8198-4E85-9924-6F8FF679F9FF}",
|
|
||||||
["num"] = 8,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
["tasks"] = {
|
|
||||||
[1] = 31,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[4] = {
|
|
||||||
["name"] = "SEAD",
|
["name"] = "SEAD",
|
||||||
["pylons"] = {
|
["pylons"] = {
|
||||||
[1] = {
|
[1] = {
|
||||||
["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}",
|
|
||||||
["num"] = 1,
|
|
||||||
},
|
|
||||||
[2] = {
|
|
||||||
["CLSID"] = "{FE382A68-8620-4AC0-BDF5-709BFE3977D7}",
|
|
||||||
["num"] = 2,
|
|
||||||
},
|
|
||||||
[3] = {
|
|
||||||
["CLSID"] = "{0519A264-0AB6-11d6-9193-00A0249B6F00}",
|
|
||||||
["num"] = 5,
|
|
||||||
},
|
|
||||||
[4] = {
|
|
||||||
["CLSID"] = "{FE382A68-8620-4AC0-BDF5-709BFE3977D7}",
|
["CLSID"] = "{FE382A68-8620-4AC0-BDF5-709BFE3977D7}",
|
||||||
["num"] = 7,
|
["num"] = 7,
|
||||||
},
|
},
|
||||||
[5] = {
|
[2] = {
|
||||||
["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}",
|
["CLSID"] = "{E86C5AA5-6D49-4F00-AD2E-79A62D6DDE26}",
|
||||||
["num"] = 8,
|
["num"] = 8,
|
||||||
},
|
},
|
||||||
|
[3] = {
|
||||||
|
["CLSID"] = "{E86C5AA5-6D49-4F00-AD2E-79A62D6DDE26}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
["CLSID"] = "{FE382A68-8620-4AC0-BDF5-709BFE3977D7}",
|
||||||
|
["num"] = 2,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
["tasks"] = {
|
["tasks"] = {
|
||||||
[1] = 29,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[5] = {
|
[2] = {
|
||||||
|
["name"] = "STRIKE",
|
||||||
|
["pylons"] = {
|
||||||
|
[1] = {
|
||||||
|
["CLSID"] = "{KAB_1500LG_LOADOUT}",
|
||||||
|
["num"] = 7,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}",
|
||||||
|
["num"] = 8,
|
||||||
|
},
|
||||||
|
[3] = {
|
||||||
|
["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
["CLSID"] = "{KAB_1500LG_LOADOUT}",
|
||||||
|
["num"] = 2,
|
||||||
|
},
|
||||||
|
[5] = {
|
||||||
|
["CLSID"] = "{E2C426E3-8B10-4E09-B733-9CDC26520F48}",
|
||||||
|
["num"] = 3,
|
||||||
|
},
|
||||||
|
[6] = {
|
||||||
|
["CLSID"] = "{E2C426E3-8B10-4E09-B733-9CDC26520F48}",
|
||||||
|
["num"] = 6,
|
||||||
|
},
|
||||||
|
[7] = {
|
||||||
|
["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}",
|
||||||
|
["num"] = 4,
|
||||||
|
},
|
||||||
|
[8] = {
|
||||||
|
["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}",
|
||||||
|
["num"] = 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tasks"] = {
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[3] = {
|
||||||
["name"] = "CAP",
|
["name"] = "CAP",
|
||||||
["pylons"] = {
|
["pylons"] = {
|
||||||
[1] = {
|
[1] = {
|
||||||
["CLSID"] = "{B0DBC591-0F52-4F7D-AD7B-51E67725FB81}",
|
["CLSID"] = "{7D7EC917-05F6-49D4-8045-61FC587DD019}",
|
||||||
["num"] = 1,
|
["num"] = 7,
|
||||||
},
|
},
|
||||||
[2] = {
|
[2] = {
|
||||||
["CLSID"] = "{275A2855-4A79-4B2D-B082-91EA2ADF4691}",
|
["CLSID"] = "{275A2855-4A79-4B2D-B082-91EA2ADF4691}",
|
||||||
["num"] = 8,
|
["num"] = 8,
|
||||||
},
|
},
|
||||||
|
[3] = {
|
||||||
|
["CLSID"] = "{B0DBC591-0F52-4F7D-AD7B-51E67725FB81}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
["CLSID"] = "{7D7EC917-05F6-49D4-8045-61FC587DD019}",
|
||||||
|
["num"] = 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tasks"] = {
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
["name"] = "ANTISHIP",
|
||||||
|
["pylons"] = {
|
||||||
|
[1] = {
|
||||||
|
["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}",
|
||||||
|
["num"] = 7,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
["CLSID"] = "{E86C5AA5-6D49-4F00-AD2E-79A62D6DDE26}",
|
||||||
|
["num"] = 8,
|
||||||
|
},
|
||||||
|
[3] = {
|
||||||
|
["CLSID"] = "{E86C5AA5-6D49-4F00-AD2E-79A62D6DDE26}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}",
|
||||||
|
["num"] = 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tasks"] = {
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[5] = {
|
||||||
|
["name"] = "CAS",
|
||||||
|
["pylons"] = {
|
||||||
|
[1] = {
|
||||||
|
["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}",
|
||||||
|
["num"] = 8,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
[3] = {
|
||||||
|
["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}",
|
||||||
|
["num"] = 2,
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}",
|
||||||
|
["num"] = 7,
|
||||||
|
},
|
||||||
|
[5] = {
|
||||||
|
["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}",
|
||||||
|
["num"] = 6,
|
||||||
|
},
|
||||||
|
[6] = {
|
||||||
|
["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}",
|
||||||
|
["num"] = 3,
|
||||||
|
},
|
||||||
|
[7] = {
|
||||||
|
["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}",
|
||||||
|
["num"] = 5,
|
||||||
|
},
|
||||||
|
[8] = {
|
||||||
|
["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}",
|
||||||
|
["num"] = 4,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
["tasks"] = {
|
["tasks"] = {
|
||||||
[1] = 32,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -38,6 +38,7 @@ class ControlPoint:
|
|||||||
cptype: ControlPointType = None
|
cptype: ControlPointType = None
|
||||||
|
|
||||||
ICLS_counter = 1
|
ICLS_counter = 1
|
||||||
|
alt = 0
|
||||||
|
|
||||||
def __init__(self, id: int, name: str, position: Point, at, radials: typing.Collection[int], size: int, importance: float,
|
def __init__(self, id: int, name: str, position: Point, at, radials: typing.Collection[int], size: int, importance: float,
|
||||||
has_frontline=True, cptype=ControlPointType.AIRBASE):
|
has_frontline=True, cptype=ControlPointType.AIRBASE):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user