mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Implement advanced skynet functions
- factor out own class for the iadsnetwork within the conflicttheater - This class will handle all Skynet related things - no specific group_name handling necessary in future - make iadsbuilding own TGO class because SAM & EWRs are Vehicle Groups. IADS Elements dont have any groups attached. - added command center, connection node and power source as Ground objects which can be added by the campaign designer - adjust lua generator to support new iads units - parse the campaign yaml to get the iads network information - use the range as fallback if no yaml information was found - complete rewrite of the skynet lua script - allow destruction of iads network to be persistent over all rounds - modified the presetlocation handling: the wrapper PresetLocation for PointWithHeading now stores the original name from the campaign miz to have the ability to process campaign yaml configurations based on the ground unit - Implementation of the UI representation for the IADS Network - Give user the option to enable or disable advanced iads - Extended the layout system: Implement Sub task handling to support PD
This commit is contained in:
@@ -198,6 +198,18 @@ const injectedRtkApi = api.injectEndpoints({
|
||||
body: queryArg.leafletPoint,
|
||||
}),
|
||||
}),
|
||||
getIadsNetwork: build.query<
|
||||
GetIadsNetworkApiResponse,
|
||||
GetIadsNetworkApiArg
|
||||
>({
|
||||
query: () => ({ url: `/iads-network/` }),
|
||||
}),
|
||||
getIadsConnectionsForTgo: build.query<
|
||||
GetIadsConnectionsForTgoApiResponse,
|
||||
GetIadsConnectionsForTgoApiArg
|
||||
>({
|
||||
query: (queryArg) => ({ url: `/iads-network/for-tgo/${queryArg.tgoId}` }),
|
||||
}),
|
||||
}),
|
||||
overrideExisting: false,
|
||||
});
|
||||
@@ -330,6 +342,14 @@ export type SetWaypointPositionApiArg = {
|
||||
waypointIdx: number;
|
||||
leafletPoint: LatLng;
|
||||
};
|
||||
export type GetIadsNetworkApiResponse =
|
||||
/** status 200 Successful Response */ IadsNetwork;
|
||||
export type GetIadsNetworkApiArg = void;
|
||||
export type GetIadsConnectionsForTgoApiResponse =
|
||||
/** status 200 Successful Response */ IadsConnection[];
|
||||
export type GetIadsConnectionsForTgoApiArg = {
|
||||
tgoId: string;
|
||||
};
|
||||
export type LatLng = {
|
||||
lat: number;
|
||||
lng: number;
|
||||
@@ -414,6 +434,19 @@ export type SupplyRoute = {
|
||||
blue: boolean;
|
||||
active_transports: string[];
|
||||
};
|
||||
export type IadsConnection = {
|
||||
id: string;
|
||||
points: LatLng[];
|
||||
node: string;
|
||||
connected: string;
|
||||
active: boolean;
|
||||
blue: boolean;
|
||||
is_power: boolean;
|
||||
};
|
||||
export type IadsNetwork = {
|
||||
advanced: boolean;
|
||||
connections: IadsConnection[];
|
||||
};
|
||||
export type ThreatZones = {
|
||||
full: LatLng[][];
|
||||
aircraft: LatLng[][];
|
||||
@@ -441,6 +474,7 @@ export type Game = {
|
||||
supply_routes: SupplyRoute[];
|
||||
front_lines: FrontLine[];
|
||||
flights: Flight[];
|
||||
iads_network: IadsNetwork;
|
||||
threat_zones: ThreatZoneContainer;
|
||||
navmeshes: NavMeshes;
|
||||
map_center?: LatLng;
|
||||
@@ -483,4 +517,6 @@ export const {
|
||||
useGetTgoByIdQuery,
|
||||
useListAllWaypointsForFlightQuery,
|
||||
useSetWaypointPositionMutation,
|
||||
useGetIadsNetworkQuery,
|
||||
useGetIadsConnectionsForTgoQuery,
|
||||
} = injectedRtkApi;
|
||||
|
||||
@@ -29,6 +29,8 @@ import { navMeshUpdated } from "./navMeshSlice";
|
||||
import { updateTgo } from "./tgosSlice";
|
||||
import { threatZonesUpdated } from "./threatZonesSlice";
|
||||
import { LatLng } from "leaflet";
|
||||
import { updateIadsConnection } from "./iadsNetworkSlice";
|
||||
import { IadsConnection } from "./_liberationApi";
|
||||
|
||||
interface GameUpdateEvents {
|
||||
updated_flight_positions: { [id: string]: LatLng };
|
||||
@@ -138,6 +140,11 @@ export const handleStreamedEvents = (
|
||||
const tgo = response.data as Tgo;
|
||||
dispatch(updateTgo(tgo));
|
||||
});
|
||||
backend.get(`/iads-network/for-tgo/${id}`).then((response) => {
|
||||
for (const connection of response.data) {
|
||||
dispatch(updateIadsConnection(connection as IadsConnection));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (const id of events.updated_control_points) {
|
||||
|
||||
43
client/src/api/iadsNetworkSlice.ts
Normal file
43
client/src/api/iadsNetworkSlice.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { RootState } from "../app/store";
|
||||
import { gameLoaded, gameUnloaded } from "./actions";
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { IadsConnection} from "./_liberationApi";
|
||||
|
||||
interface IadsNetworkState {
|
||||
connections: {[key: string]: IadsConnection}
|
||||
}
|
||||
|
||||
const initialState: IadsNetworkState = {
|
||||
connections: {},
|
||||
};
|
||||
|
||||
export const IadsNetworkSlice = createSlice({
|
||||
name: "iadsNetwork",
|
||||
initialState,
|
||||
reducers: {
|
||||
updateIadsConnection: (state, action: PayloadAction<IadsConnection>) => {
|
||||
const connection = action.payload;
|
||||
state.connections[connection.id] = connection
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder.addCase(gameLoaded, (state, action) => {
|
||||
state.connections = action.payload.iads_network.connections.reduce(
|
||||
(acc: { [key: string]: IadsConnection }, curr) => {
|
||||
acc[curr.id] = curr;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
});
|
||||
builder.addCase(gameUnloaded, (state) => {
|
||||
state.connections = {};
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const { updateIadsConnection } = IadsNetworkSlice.actions;
|
||||
|
||||
export const selectIadsNetwork = (state: RootState) => state.iadsNetwork;
|
||||
|
||||
export default IadsNetworkSlice.reducer;
|
||||
@@ -7,6 +7,7 @@ import mapReducer from "../api/mapSlice";
|
||||
import navMeshReducer from "../api/navMeshSlice";
|
||||
import supplyRoutesReducer from "../api/supplyRoutesSlice";
|
||||
import tgosReducer from "../api/tgosSlice";
|
||||
import iadsNetworkReducer from "../api/iadsNetworkSlice";
|
||||
import threatZonesReducer from "../api/threatZonesSlice";
|
||||
import { Action, ThunkAction, configureStore } from "@reduxjs/toolkit";
|
||||
|
||||
@@ -19,6 +20,7 @@ export const store = configureStore({
|
||||
map: mapReducer,
|
||||
navmeshes: navMeshReducer,
|
||||
supplyRoutes: supplyRoutesReducer,
|
||||
iadsNetwork: iadsNetworkReducer,
|
||||
tgos: tgosReducer,
|
||||
threatZones: threatZonesReducer,
|
||||
[baseApi.reducerPath]: baseApi.reducer,
|
||||
|
||||
39
client/src/components/iadsnetwork/IadsNetwork.tsx
Normal file
39
client/src/components/iadsnetwork/IadsNetwork.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { IadsConnection as IadsConnectionModel } from "../../api/liberationApi";
|
||||
import { Polyline as LPolyline } from "leaflet";
|
||||
import { useRef } from "react";
|
||||
import { Polyline, Tooltip } from "react-leaflet";
|
||||
|
||||
interface IadsConnectionProps {
|
||||
iads_connection: IadsConnectionModel;
|
||||
}
|
||||
|
||||
function IadsConnectionTooltip(props: IadsConnectionProps) {
|
||||
var status = props.iads_connection.active ? "Active" : "Inactive";
|
||||
if (props.iads_connection.is_power) {
|
||||
return <Tooltip>Power Connection ({status})</Tooltip>;
|
||||
} else {
|
||||
return <Tooltip>Communication Connection ({status})</Tooltip>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default function IadsConnection(props: IadsConnectionProps) {
|
||||
const color = props.iads_connection.is_power ? "#FFD580" : "#87CEEB";
|
||||
const path = useRef<LPolyline | null>();
|
||||
const weight = 1
|
||||
var opacity = props.iads_connection.active ? 1.0 : 0.5
|
||||
var dashArray = props.iads_connection.active ? "" : "20"
|
||||
|
||||
return (
|
||||
<Polyline
|
||||
positions={props.iads_connection.points}
|
||||
color={color}
|
||||
weight={weight}
|
||||
opacity={opacity}
|
||||
dashArray={dashArray}
|
||||
ref={(ref) => (path.current = ref)}
|
||||
>
|
||||
<IadsConnectionTooltip {...props} />
|
||||
</Polyline>
|
||||
);
|
||||
}
|
||||
1
client/src/components/iadsnetwork/index.ts
Normal file
1
client/src/components/iadsnetwork/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from "./IadsNetwork";
|
||||
26
client/src/components/iadsnetworklayer/IadsNetworkLayer.tsx
Normal file
26
client/src/components/iadsnetworklayer/IadsNetworkLayer.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { useAppSelector } from "../../app/hooks";
|
||||
import { LayerGroup } from "react-leaflet";
|
||||
import IadsConnection from "../iadsnetwork/IadsNetwork";
|
||||
import { selectIadsNetwork } from "../../api/iadsNetworkSlice";
|
||||
|
||||
|
||||
interface IadsNetworkLayerProps {
|
||||
blue: boolean;
|
||||
}
|
||||
|
||||
export const IadsNetworkLayer = (props: IadsNetworkLayerProps) => {
|
||||
const connections = Object.values(useAppSelector(selectIadsNetwork).connections);
|
||||
var iadsConnectionsForSide = connections.filter((connection) => connection.blue === props.blue);
|
||||
|
||||
return (
|
||||
<LayerGroup>
|
||||
{iadsConnectionsForSide.map((connection) => {
|
||||
return (
|
||||
<IadsConnection key={connection.id} iads_connection={connection} />
|
||||
);
|
||||
})}
|
||||
</LayerGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export default IadsNetworkLayer;
|
||||
1
client/src/components/iadsnetworklayer/index.ts
Normal file
1
client/src/components/iadsnetworklayer/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from "./IadsNetworkLayer";
|
||||
@@ -17,6 +17,7 @@ import { Map } from "leaflet";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { BasemapLayer } from "react-esri-leaflet";
|
||||
import { LayersControl, MapContainer, ScaleControl } from "react-leaflet";
|
||||
import Iadsnetworklayer from "../iadsnetworklayer";
|
||||
|
||||
export default function LiberationMap() {
|
||||
const map = useRef<Map>();
|
||||
@@ -74,12 +75,18 @@ export default function LiberationMap() {
|
||||
<LayersControl.Overlay name="Enemy SAM detection range">
|
||||
<AirDefenseRangeLayer blue={false} detection />
|
||||
</LayersControl.Overlay>
|
||||
<LayersControl.Overlay name="Enemy IADS Network">
|
||||
<Iadsnetworklayer blue={false} />
|
||||
</LayersControl.Overlay>
|
||||
<LayersControl.Overlay name="Allied SAM threat range">
|
||||
<AirDefenseRangeLayer blue={true} />
|
||||
</LayersControl.Overlay>
|
||||
<LayersControl.Overlay name="Allied SAM detection range">
|
||||
<AirDefenseRangeLayer blue={true} detection />
|
||||
</LayersControl.Overlay>
|
||||
<LayersControl.Overlay name="Allied IADS Network">
|
||||
<Iadsnetworklayer blue={true} />
|
||||
</LayersControl.Overlay>
|
||||
<LayersControl.Overlay name="Selected blue flight plan">
|
||||
<FlightPlansLayer blue={true} selectedOnly />
|
||||
</LayersControl.Overlay>
|
||||
|
||||
Reference in New Issue
Block a user