Move waypoints and commit boundaries to FastAPI.

This commit is contained in:
Dan Albert
2022-02-19 18:25:45 -08:00
parent b533633494
commit c16ca40894
25 changed files with 360 additions and 328 deletions

View File

@@ -98,6 +98,10 @@ class Flight:
state["id"] = uuid.uuid4()
self.__dict__.update(state)
@property
def blue(self) -> bool:
return self.squadron.player
@property
def departure(self) -> ControlPoint:
return self.squadron.location

View File

@@ -1,20 +1,115 @@
from __future__ import annotations
from collections.abc import Sequence
from dataclasses import field
from datetime import timedelta
from typing import Optional, Sequence, TYPE_CHECKING, Union
from typing import Optional, TYPE_CHECKING
from dcs import Point
from dcs.point import MovingPoint, PointAction
from dcs.unit import Unit
from pydantic.dataclasses import dataclass
from game.utils import Distance, meters
from game.ato.flightwaypointtype import FlightWaypointType
from game.theater import LatLon
from game.utils import Distance, meters
if TYPE_CHECKING:
from game.theater import ControlPoint, MissionTarget
from game.theater import ConflictTheater, ControlPoint, MissionTarget
class FlightWaypoint:
@dataclass
class BaseFlightWaypoint:
name: str
waypoint_type: FlightWaypointType
x: float
y: float
alt: Distance
alt_type: str
is_movable: bool = field(init=False)
should_mark: bool = field(init=False)
include_in_path: bool = field(init=False)
# Do not use unless you're sure it's up to date. Pydantic doesn't have support for
# serializing lazy properties so this needs to be stored in the class, but because
# updating it requires a reference to the ConflictTheater it may not always be set,
# or up to date. Call update_latlng to refresh.
latlng: LatLon | None = None
def __post_init__(self) -> None:
# Target *points* are the exact location of a unit, whereas the target area is
# only the center of the objective. Allow moving the latter since its exact
# location isn't very important.
#
# Landing, and divert should be changed in the flight settings UI, takeoff
# cannot be changed because that's where the plane is.
#
# Moving the bullseye reference only makes it wrong.
self.is_movable = self.waypoint_type not in {
FlightWaypointType.BULLSEYE,
FlightWaypointType.DIVERT,
FlightWaypointType.LANDING_POINT,
FlightWaypointType.TAKEOFF,
FlightWaypointType.TARGET_POINT,
}
# We don't need a marker for the departure waypoint (and it's likely
# coincident with the landing waypoint, so hard to see). We do want to draw
# the path from it though.
#
# We also don't need the landing waypoint since we'll be drawing that path
# as well, and it's clear what it is, and only obscured the CP icon.
#
# The divert waypoint also obscures the CP. We don't draw the path to it,
# but it can be seen in the flight settings page, so it's not really a
# problem to exclude it.
#
# Bullseye ought to be (but currently isn't) drawn *once* rather than as a
# flight waypoint.
self.should_mark = self.waypoint_type not in {
FlightWaypointType.BULLSEYE,
FlightWaypointType.DIVERT,
FlightWaypointType.LANDING_POINT,
FlightWaypointType.TAKEOFF,
}
self.include_in_path = self.waypoint_type not in {
FlightWaypointType.BULLSEYE,
FlightWaypointType.DIVERT,
}
@property
def position(self) -> Point:
return Point(self.x, self.y)
def update_latlng(self, theater: ConflictTheater) -> None:
self.latlng = theater.point_to_ll(self.position)
class FlightWaypoint(BaseFlightWaypoint):
control_point: ControlPoint | None = None
# TODO: Merge with pretty_name.
# Only used in the waypoint list in the flight edit page. No sense
# having three names. A short and long form is enough.
description: str = ""
targets: Sequence[MissionTarget | Unit] = []
obj_name: str = ""
pretty_name: str = ""
only_for_player: bool = False
flyover: bool = False
# The minimum amount of fuel remaining at this waypoint in pounds.
min_fuel: float | None = None
# 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.
tot: timedelta | None = None
departure_time: timedelta | None = None
def __init__(
self,
waypoint_type: FlightWaypointType,
@@ -34,32 +129,10 @@ class FlightWaypoint:
control_point: The control point to associate with this waypoint. Needed for
landing points.
"""
self.waypoint_type = waypoint_type
self.x = x
self.y = y
self.alt = alt
super().__init__(
name="", waypoint_type=waypoint_type, x=x, y=y, alt=alt, alt_type="BARO"
)
self.control_point = control_point
self.alt_type = "BARO"
self.name = ""
# TODO: Merge with pretty_name.
# Only used in the waypoint list in the flight edit page. No sense
# having three names. A short and long form is enough.
self.description = ""
self.targets: Sequence[Union[MissionTarget, Unit]] = []
self.obj_name = ""
self.pretty_name = ""
self.only_for_player = False
self.flyover = False
# The minimum amount of fuel remaining at this waypoint in pounds.
self.min_fuel: Optional[float] = None
# 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[timedelta] = None
self.departure_time: Optional[timedelta] = None
@property
def position(self) -> Point:
return Point(self.x, self.y)
def __hash__(self) -> int:
return hash(id(self))

View File

@@ -1,7 +1,8 @@
from enum import Enum
from enum import IntEnum, unique
class FlightWaypointType(Enum):
@unique
class FlightWaypointType(IntEnum):
"""Enumeration of waypoint types.
The value of the enum has no meaning but should remain stable to prevent breaking