Merge remote-tracking branch 'upstream/develop' into new-plugin-system

This commit is contained in:
David Pierron
2020-10-20 22:10:19 +02:00
12 changed files with 188 additions and 87 deletions

View File

@@ -1140,8 +1140,9 @@ class HoldPointBuilder(PydcsWaypointBuilder):
altitude=waypoint.alt,
pattern=OrbitAction.OrbitPattern.Circle
))
loiter.stop_after_time(
self.timing.push_time(self.flight, self.waypoint))
push_time = self.timing.push_time(self.flight, self.waypoint)
self.waypoint.departure_time = push_time
loiter.stop_after_time(push_time)
waypoint.add_task(loiter)
return waypoint

View File

@@ -390,9 +390,6 @@ class CoalitionMissionPlanner:
MAX_SEAD_RANGE = nm_to_meter(150)
MAX_STRIKE_RANGE = nm_to_meter(150)
NON_CAP_MIN_DELAY = 1
NON_CAP_MAX_DELAY = 5
def __init__(self, game: Game, is_player: bool) -> None:
self.game = game
self.is_player = is_player

View File

@@ -1,9 +1,11 @@
from enum import Enum
from typing import Dict, Iterable, Optional
from typing import Dict, Iterable, List, Optional
from dcs.mapping import Point
from dcs.point import MovingPoint, PointAction
from dcs.unittype import UnitType
from game import db
from dcs.unittype import UnitType
from dcs.point import MovingPoint, PointAction
from theater.controlpoint import ControlPoint, MissionTarget
@@ -91,17 +93,22 @@ class FlightWaypoint:
self.only_for_player = False
self.data = None
# This is set very late by the air conflict generator (part of mission
# These are set very late by the air conflict generator (part of mission
# generation). We do it late so that we don't need to propagate changes
# to waypoint times whenever the player alters the package TOT or the
# flight's offset in the UI.
self.tot: Optional[int] = None
self.departure_time: Optional[int] = None
@property
def position(self) -> Point:
return Point(self.x, self.y)
@classmethod
def from_pydcs(cls, point: MovingPoint,
from_cp: ControlPoint) -> "FlightWaypoint":
waypoint = FlightWaypoint(point.position.x, point.position.y,
point.alt)
waypoint = FlightWaypoint(FlightWaypointType.NAV, point.position.x,
point.position.y, point.alt)
waypoint.alt_type = point.alt_type
# Other actions exist... but none of them *should* be the first
# waypoint for a flight.
@@ -159,14 +166,3 @@ class Flight:
if waypoint.waypoint_type in types:
return waypoint
return None
# Test
if __name__ == '__main__':
from dcs.planes import A_10C
from theater import ControlPoint, Point, List
from_cp = ControlPoint(0, "AA", Point(0, 0), Point(0, 0), [], 0, 0)
f = Flight(A_10C(), 4, from_cp, FlightType.CAS, "Cold")
f.scheduled_in = 50
print(f)

View File

@@ -187,6 +187,10 @@ class FlightPlanBuilder:
closest_cache = ObjectiveDistanceCache.get_closest_airfields(location)
for airfield in closest_cache.closest_airfields:
# If the mission is a BARCAP of an enemy airfield, find the *next*
# closest enemy airfield.
if airfield == self.package.target:
continue
if airfield.captured != self.is_player:
closest_airfield = airfield
break
@@ -198,10 +202,19 @@ class FlightPlanBuilder:
closest_airfield.position
)
min_distance_from_enemy = nm_to_meter(20)
distance_to_airfield = int(closest_airfield.position.distance_to_point(
self.package.target.position
))
distance_to_no_fly = distance_to_airfield - min_distance_from_enemy
min_cap_distance = min(self.doctrine.cap_min_distance_from_cp,
distance_to_no_fly)
max_cap_distance = min(self.doctrine.cap_max_distance_from_cp,
distance_to_no_fly)
end = location.position.point_from_heading(
heading,
random.randint(self.doctrine.cap_min_distance_from_cp,
self.doctrine.cap_max_distance_from_cp)
random.randint(min_cap_distance, max_cap_distance)
)
diameter = random.randint(
self.doctrine.cap_min_track_length,

View File

@@ -29,16 +29,19 @@ from pathlib import Path
from typing import Dict, List, Optional, Tuple
from PIL import Image, ImageDraw, ImageFont
from dcs.mapping import Point
from dcs.mission import Mission
from dcs.unittype import FlyingType
from tabulate import tabulate
from game.utils import meter_to_nm
from . import units
from .aircraft import AIRCRAFT_DATA, FlightData
from .airfields import RunwayData
from .airsupportgen import AwacsInfo, TankerInfo
from .briefinggen import CommInfo, JtacInfo, MissionInfoGenerator
from .flights.flight import FlightWaypoint, FlightWaypointType
from .flights.traveltime import TravelTime
from .radios import RadioFrequency
@@ -111,6 +114,7 @@ class FlightPlanBuilder:
self.start_time = start_time
self.rows: List[List[str]] = []
self.target_points: List[NumberedWaypoint] = []
self.last_waypoint: Optional[FlightWaypoint] = None
def add_waypoint(self, waypoint_num: int, waypoint: FlightWaypoint) -> None:
if waypoint.waypoint_type == FlightWaypointType.TARGET_POINT:
@@ -136,22 +140,59 @@ class FlightPlanBuilder:
f"{first_waypoint_num}-{last_waypoint_num}",
"Target points",
"0",
self._waypoint_distance(self.target_points[0].waypoint),
self._ground_speed(self.target_points[0].waypoint),
self._format_time(self.target_points[0].waypoint.tot),
self._format_time(self.target_points[0].waypoint.departure_time),
])
self.last_waypoint = self.target_points[-1].waypoint
def add_waypoint_row(self, waypoint: NumberedWaypoint) -> None:
self.rows.append([
str(waypoint.number),
waypoint.waypoint.pretty_name,
str(int(units.meters_to_feet(waypoint.waypoint.alt))),
self._waypoint_distance(waypoint.waypoint),
self._ground_speed(waypoint.waypoint),
self._format_time(waypoint.waypoint.tot),
self._format_time(waypoint.waypoint.departure_time),
])
self.last_waypoint = waypoint.waypoint
def _format_time(self, time: Optional[int]) -> str:
if time is None:
return ""
local_time = self.start_time + datetime.timedelta(seconds=time)
return local_time.strftime(f"%H:%M:%S LOCAL")
return local_time.strftime(f"%H:%M:%S")
def _waypoint_distance(self, waypoint: FlightWaypoint) -> str:
if self.last_waypoint is None:
return "-"
distance = meter_to_nm(self.last_waypoint.position.distance_to_point(
waypoint.position
))
return f"{distance} NM"
def _ground_speed(self, waypoint: FlightWaypoint) -> str:
if self.last_waypoint is None:
return "-"
if waypoint.tot is None:
return "-"
if self.last_waypoint.departure_time is not None:
last_time = self.last_waypoint.departure_time
elif self.last_waypoint.tot is not None:
last_time = self.last_waypoint.tot
else:
return "-"
distance = meter_to_nm(self.last_waypoint.position.distance_to_point(
waypoint.position
))
duration = (waypoint.tot - last_time) / 3600
return f"{int(distance / duration)} kt"
def build(self) -> List[List[str]]:
return self.rows
@@ -186,8 +227,9 @@ class BriefingPage(KneeboardPage):
flight_plan_builder = FlightPlanBuilder(self.start_time)
for num, waypoint in enumerate(self.flight.waypoints):
flight_plan_builder.add_waypoint(num, waypoint)
writer.table(flight_plan_builder.build(),
headers=["STPT", "Action", "Alt", "TOT"])
writer.table(flight_plan_builder.build(), headers=[
"#", "Action", "Alt", "Dist", "GSPD", "Time", "Departure"
])
writer.heading("Comm Ladder")
comms = []