98 lines
3.2 KiB
Python

from dcs import Point
from dcs.mapping import LatLng
from fastapi import APIRouter, Depends, HTTPException, status
from game import Game
from .models import ControlPointJs
from .. import EventStream
from ..dependencies import GameContext
from ..leaflet import LeafletPoint
from ...sim import GameUpdateEvents
router: APIRouter = APIRouter(prefix="/control-points")
@router.get("/")
def list_control_points(game: Game = Depends(GameContext.get)) -> list[ControlPointJs]:
control_points = []
for control_point in game.theater.controlpoints:
control_points.append(ControlPointJs.for_control_point(control_point))
return control_points
@router.get("/{cp_id}")
def get_control_point(
cp_id: int, game: Game = Depends(GameContext.get)
) -> ControlPointJs:
cp = game.theater.find_control_point_by_id(cp_id)
if cp is None:
raise HTTPException(
status.HTTP_404_NOT_FOUND,
detail=f"Game has no control point with ID {cp_id}",
)
return ControlPointJs.for_control_point(cp)
@router.get("/{cp_id}/destination-in-range")
def destination_in_range(
cp_id: int, lat: float, lng: float, game: Game = Depends(GameContext.get)
) -> bool:
cp = game.theater.find_control_point_by_id(cp_id)
if cp is None:
raise HTTPException(
status.HTTP_404_NOT_FOUND,
detail=f"Game has no control point with ID {cp_id}",
)
point = Point.from_latlng(LatLng(lat, lng), game.theater.terrain)
return cp.destination_in_range(point)
@router.put("/{cp_id}/destination")
def set_destination(
cp_id: int, destination: LeafletPoint, game: Game = Depends(GameContext.get)
) -> None:
cp = game.theater.find_control_point_by_id(cp_id)
if cp is None:
raise HTTPException(
status.HTTP_404_NOT_FOUND,
detail=f"Game has no control point with ID {cp_id}",
)
if not cp.moveable:
raise HTTPException(status.HTTP_403_FORBIDDEN, detail=f"{cp} is not mobile")
if not cp.captured:
raise HTTPException(
status.HTTP_403_FORBIDDEN, detail=f"{cp} is not owned by the player"
)
point = Point.from_latlng(
LatLng(destination.lat, destination.lng), game.theater.terrain
)
if not cp.destination_in_range(point):
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
detail=f"Cannot move {cp} more than "
f"{cp.max_move_distance.nautical_miles}nm.",
)
cp.target_position = point
EventStream.put_nowait(GameUpdateEvents().update_control_point(cp))
@router.put("/{cp_id}/cancel-travel")
def cancel_travel(cp_id: int, game: Game = Depends(GameContext.get)) -> None:
cp = game.theater.find_control_point_by_id(cp_id)
if cp is None:
raise HTTPException(
status.HTTP_404_NOT_FOUND,
detail=f"Game has no control point with ID {cp_id}",
)
if not cp.moveable:
raise HTTPException(status.HTTP_403_FORBIDDEN, detail=f"{cp} is not mobile")
if not cp.captured:
raise HTTPException(
status.HTTP_403_FORBIDDEN, detail=f"{cp} is not owned by the player"
)
cp.target_position = None
EventStream.put_nowait(GameUpdateEvents().update_control_point(cp))