Draw aircraft locations in the new map.

https://github.com/dcs-liberation/dcs_liberation/issues/2039
This commit is contained in:
Dan Albert 2022-03-04 18:34:01 -08:00
parent 980d8f3092
commit 88cd9e19c5
9 changed files with 72 additions and 2 deletions

View File

@ -9,6 +9,7 @@ import {
selectFlight,
unregisterFlight,
updateFlight,
updateFlightPosition,
} from "./flightsSlice";
import {
addFrontLine,
@ -48,6 +49,12 @@ export const handleStreamedEvents = (
dispatch: AppDispatch,
events: GameUpdateEvents
) => {
for (const [id, position] of Object.entries(
events.updated_flight_positions
)) {
dispatch(updateFlightPosition([id, position]));
}
for (const flight of events.new_flights) {
dispatch(registerFlight(flight));
}

View File

@ -4,7 +4,7 @@ import { LatLng } from "leaflet";
export interface Flight {
id: string;
blue: boolean;
position: LatLng;
position: LatLng | null;
sidc: string;
waypoints: Waypoint[] | null;
}

View File

@ -1,6 +1,7 @@
import { RootState } from "../app/store";
import { Flight } from "./flight";
import { PayloadAction, createSlice } from "@reduxjs/toolkit";
import { LatLng } from "leaflet";
interface FlightsState {
blue: { [id: string]: Flight };
@ -55,6 +56,11 @@ export const flightsSlice = createSlice({
const id = action.payload;
state.selected = state.blue[id];
},
updateFlightPosition: (state, action: PayloadAction<[string, LatLng]>) => {
const [id, position] = action.payload;
const ato = id in state.blue ? state.blue : state.red;
ato[id].position = position;
},
},
});
@ -65,6 +71,7 @@ export const {
updateFlight,
deselectFlight,
selectFlight,
updateFlightPosition,
} = flightsSlice.actions;
export const selectFlights = (state: RootState) => state.flights;

View File

@ -15,7 +15,7 @@ export const store = configureStore({
tgos: tgosReducer,
},
// The logger middleware must be last or it won't log actions.
middleware: [logger],
//middleware: [logger],
});
export type AppDispatch = typeof store.dispatch;

View File

@ -0,0 +1,32 @@
import { Flight } from "../../api/flight";
import { Icon, Point } from "leaflet";
import { Symbol } from "milsymbol";
import { Marker } from "react-leaflet";
function iconForFlight(flight: Flight) {
const symbol = new Symbol(flight.sidc, {
size: 16,
});
return new Icon({
iconUrl: symbol.toDataURL(),
iconAnchor: new Point(symbol.getAnchor().x, symbol.getAnchor().y),
});
}
interface AircraftProps {
flight: Flight;
}
export default function Aircraft(props: AircraftProps) {
if (!props.flight.position) {
return <></>;
}
return (
<Marker
position={props.flight.position}
icon={iconForFlight(props.flight)}
/>
);
}

View File

@ -0,0 +1 @@
export { default } from "./Aircraft";

View File

@ -0,0 +1,18 @@
import { selectFlights } from "../../api/flightsSlice";
import { useAppSelector } from "../../app/hooks";
import Aircraft from "../aircraft";
import { LayerGroup } from "react-leaflet";
export default function AircraftLayer() {
const atos = useAppSelector(selectFlights);
return (
<LayerGroup>
{Object.values(atos.blue).map((flight) => {
return <Aircraft key={flight.id} flight={flight} />;
})}
{Object.values(atos.red).map((flight) => {
return <Aircraft key={flight.id} flight={flight} />;
})}
</LayerGroup>
);
}

View File

@ -0,0 +1 @@
export { default } from "./AircraftLayer";

View File

@ -1,3 +1,4 @@
import AircraftLayer from "../aircraftlayer";
import AirDefenseRangeLayer from "../airdefenserangelayer";
import ControlPointsLayer from "../controlpointslayer";
import FlightPlansLayer from "../flightplanslayer";
@ -30,6 +31,9 @@ export default function LiberationMap(props: GameProps) {
<LayersControl.Overlay name="Control points" checked>
<ControlPointsLayer />
</LayersControl.Overlay>
<LayersControl.Overlay name="Aircraft" checked>
<AircraftLayer />
</LayersControl.Overlay>
<LayersControl.Overlay name="Air defenses" checked>
<TgosLayer categories={["aa"]} />
</LayersControl.Overlay>