Push full navmesh/threatzone info in the event stream.

https://github.com/dcs-liberation/dcs_liberation/issues/2253
https://github.com/dcs-liberation/dcs_liberation/issues/2263
This commit is contained in:
Raffson 2022-07-06 22:27:06 +02:00 committed by GitHub
parent a20b95bb26
commit 9823f7b96f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 41 deletions

View File

@ -17,12 +17,13 @@ import {
} from "./frontLinesSlice"; } from "./frontLinesSlice";
import reloadGameState from "./gamestate"; import reloadGameState from "./gamestate";
import { import {
liberationApi,
ControlPoint, ControlPoint,
Flight, Flight,
FrontLine, FrontLine,
IadsConnection, IadsConnection,
NavMesh,
Tgo, Tgo,
ThreatZones,
UnculledZone, UnculledZone,
} from "./liberationApi"; } from "./liberationApi";
import { navMeshUpdated } from "./navMeshSlice"; import { navMeshUpdated } from "./navMeshSlice";
@ -37,9 +38,9 @@ interface GameUpdateEvents {
new_combats: Combat[]; new_combats: Combat[];
updated_combats: Combat[]; updated_combats: Combat[];
ended_combats: string[]; ended_combats: string[];
navmesh_updates: boolean[]; navmesh_updates: {blue: boolean, mesh: NavMesh}[];
updated_unculled_zones: UnculledZone[]; updated_unculled_zones: UnculledZone[];
threat_zones_updated: boolean; threat_zones_updated: {blue: boolean, zones: ThreatZones}[];
new_flights: Flight[]; new_flights: Flight[];
updated_flights: Flight[]; updated_flights: Flight[];
deleted_flights: string[]; deleted_flights: string[];
@ -78,28 +79,16 @@ export const handleStreamedEvents = (
dispatch(endCombat(id)); dispatch(endCombat(id));
} }
for (const blue of events.navmesh_updates) { if (Object.keys(events.navmesh_updates).length > 0) {
dispatch( dispatch(navMeshUpdated(events.navmesh_updates));
liberationApi.endpoints.getNavmesh.initiate({ forPlayer: blue })
).then((result) => {
if (result.data) {
dispatch(navMeshUpdated({ blue: blue, mesh: result.data }));
}
});
} }
if (events.updated_unculled_zones.length > 0) { if (events.updated_unculled_zones.length > 0) {
dispatch(unculledZonesUpdated(events.updated_unculled_zones)); dispatch(unculledZonesUpdated(events.updated_unculled_zones));
} }
if (events.threat_zones_updated) { if (Object.keys(events.threat_zones_updated).length > 0) {
dispatch(liberationApi.endpoints.getThreatZones.initiate()).then( dispatch(threatZonesUpdated(events.threat_zones_updated));
(result) => {
if (result.data) {
dispatch(threatZonesUpdated(result.data));
}
}
);
} }
if (events.new_flights.length > 0) { if (events.new_flights.length > 0) {

View File

@ -13,7 +13,7 @@ const initialState: NavMeshState = {
red: [], red: [],
}; };
interface INavMeshUpdate { export interface INavMeshUpdate {
blue: boolean; blue: boolean;
mesh: NavMesh; mesh: NavMesh;
} }
@ -22,12 +22,15 @@ const navMeshSlice = createSlice({
name: "navmesh", name: "navmesh",
initialState: initialState, initialState: initialState,
reducers: { reducers: {
updated: (state, action: PayloadAction<INavMeshUpdate>) => { updated: (state, action: PayloadAction<INavMeshUpdate[]>) => {
const polys = action.payload.mesh.polys; for (const [blue, navmesh] of Object.entries(action.payload)) {
if (action.payload.blue) { const data = {blue: (blue === "true"), mesh: navmesh} as unknown as INavMeshUpdate
state.blue = polys; const polys = data.mesh.polys;
} else { if (data.blue) {
state.red = polys; state.blue = polys;
} else {
state.red = polys;
}
} }
}, },
}, },

View File

@ -1,6 +1,6 @@
import { RootState } from "../app/store"; import { RootState } from "../app/store";
import { gameLoaded, gameUnloaded } from "./actions"; import { gameLoaded, gameUnloaded } from "./actions";
import { ThreatZoneContainer } from "./liberationApi"; import { ThreatZoneContainer, ThreatZones } from "./liberationApi";
import { PayloadAction, createSlice } from "@reduxjs/toolkit"; import { PayloadAction, createSlice } from "@reduxjs/toolkit";
interface ThreatZonesState { interface ThreatZonesState {
@ -24,12 +24,24 @@ const initialState: ThreatZonesState = {
}, },
}; };
export interface IThreatZoneUpdate {
blue: boolean;
zones: ThreatZones;
}
export const threatZonesSlice = createSlice({ export const threatZonesSlice = createSlice({
name: "threatZonesState", name: "threatZonesState",
initialState, initialState,
reducers: { reducers: {
updated: (state, action: PayloadAction<ThreatZoneContainer>) => { updated: (state, action: PayloadAction<IThreatZoneUpdate[]>) => {
state.zones = action.payload; for (const [blue, zones] of Object.entries(action.payload)) {
const data = {blue: (blue === "true"), zones: zones} as unknown as IThreatZoneUpdate
if (data.blue) {
state.zones.blue = data.zones;
} else {
state.zones.red = data.zones;
}
}
}, },
}, },
extraReducers: (builder) => { extraReducers: (builder) => {

View File

@ -121,13 +121,13 @@ class Coalition:
def compute_threat_zones(self, events: GameUpdateEvents) -> None: def compute_threat_zones(self, events: GameUpdateEvents) -> None:
self._threat_zone = ThreatZones.for_faction(self.game, self.player) self._threat_zone = ThreatZones.for_faction(self.game, self.player)
events.update_threat_zones() events.update_threat_zones(self.player, self._threat_zone)
def compute_nav_meshes(self, events: GameUpdateEvents) -> None: def compute_nav_meshes(self, events: GameUpdateEvents) -> None:
self._navmesh = NavMesh.from_threat_zones( self._navmesh = NavMesh.from_threat_zones(
self.opponent.threat_zone, self.game.theater self.opponent.threat_zone, self.game.theater
) )
events.update_navmesh(self.player) events.update_navmesh(self.player, self._navmesh)
def update_transit_network(self) -> None: def update_transit_network(self) -> None:
self.transit_network = TransitNetworkBuilder( self.transit_network = TransitNetworkBuilder(

View File

@ -11,6 +11,8 @@ from game.server.flights.models import FlightJs
from game.server.frontlines.models import FrontLineJs from game.server.frontlines.models import FrontLineJs
from game.server.iadsnetwork.models import IadsConnectionJs from game.server.iadsnetwork.models import IadsConnectionJs
from game.server.leaflet import LeafletPoint from game.server.leaflet import LeafletPoint
from game.server.mapzones.models import ThreatZonesJs
from game.server.navmesh.models import NavMeshJs
from game.server.tgos.models import TgoJs from game.server.tgos.models import TgoJs
from game.server.mapzones.models import UnculledZoneJs from game.server.mapzones.models import UnculledZoneJs
@ -24,9 +26,9 @@ class GameUpdateEventsJs(BaseModel):
new_combats: list[FrozenCombatJs] new_combats: list[FrozenCombatJs]
updated_combats: list[FrozenCombatJs] updated_combats: list[FrozenCombatJs]
ended_combats: list[UUID] ended_combats: list[UUID]
navmesh_updates: set[bool] navmesh_updates: dict[bool, NavMeshJs]
updated_unculled_zones: list[UnculledZoneJs] updated_unculled_zones: list[UnculledZoneJs]
threat_zones_updated: bool threat_zones_updated: dict[bool, ThreatZonesJs]
new_flights: list[FlightJs] new_flights: list[FlightJs]
updated_flights: list[FlightJs] updated_flights: list[FlightJs]
deleted_flights: set[UUID] deleted_flights: set[UUID]
@ -51,6 +53,8 @@ class GameUpdateEventsJs(BaseModel):
# because we need to send the unload event. # because we need to send the unload event.
new_combats = [] new_combats = []
updated_combats = [] updated_combats = []
updated_navmeshes = {}
updated_threat_zones = {}
updated_unculled_zones = [] updated_unculled_zones = []
updated_iads = [] updated_iads = []
if game is not None: if game is not None:
@ -61,6 +65,14 @@ class GameUpdateEventsJs(BaseModel):
FrozenCombatJs.for_combat(c, game.theater) FrozenCombatJs.for_combat(c, game.theater)
for c in events.updated_combats for c in events.updated_combats
] ]
updated_navmeshes = {
player: NavMeshJs.from_navmesh(mesh, game)
for player, mesh in events.navmesh_updates.items()
}
updated_threat_zones = {
player: ThreatZonesJs.from_zones(zones, game.theater)
for player, zones in events.threat_zones_updated.items()
}
updated_unculled_zones = UnculledZoneJs.from_game(game) updated_unculled_zones = UnculledZoneJs.from_game(game)
for node in events.updated_iads: for node in events.updated_iads:
updated_iads.extend(IadsConnectionJs.connections_for_node(node)) updated_iads.extend(IadsConnectionJs.connections_for_node(node))
@ -72,9 +84,9 @@ class GameUpdateEventsJs(BaseModel):
new_combats=new_combats, new_combats=new_combats,
updated_combats=updated_combats, updated_combats=updated_combats,
ended_combats=[c.id for c in events.ended_combats], ended_combats=[c.id for c in events.ended_combats],
navmesh_updates=events.navmesh_updates, navmesh_updates=updated_navmeshes,
updated_unculled_zones=updated_unculled_zones, updated_unculled_zones=updated_unculled_zones,
threat_zones_updated=events.threat_zones_updated, threat_zones_updated=updated_threat_zones,
new_flights=[ new_flights=[
FlightJs.for_flight(f, with_waypoints=True) for f in events.new_flights FlightJs.for_flight(f, with_waypoints=True) for f in events.new_flights
], ],

View File

@ -10,8 +10,10 @@ from dcs.mapping import LatLng
if TYPE_CHECKING: if TYPE_CHECKING:
from game import Game from game import Game
from game.ato import Flight, Package from game.ato import Flight, Package
from game.navmesh import NavMesh
from game.sim.combat import FrozenCombat from game.sim.combat import FrozenCombat
from game.theater import ControlPoint, FrontLine, TheaterGroundObject from game.theater import ControlPoint, FrontLine, TheaterGroundObject
from game.threatzones import ThreatZones
from game.theater.iadsnetwork.iadsnetwork import IadsNetworkNode from game.theater.iadsnetwork.iadsnetwork import IadsNetworkNode
@ -22,9 +24,9 @@ class GameUpdateEvents:
updated_combats: list[FrozenCombat] = field(default_factory=list) updated_combats: list[FrozenCombat] = field(default_factory=list)
ended_combats: list[FrozenCombat] = field(default_factory=list) ended_combats: list[FrozenCombat] = field(default_factory=list)
updated_flight_positions: list[tuple[Flight, Point]] = field(default_factory=list) updated_flight_positions: list[tuple[Flight, Point]] = field(default_factory=list)
navmesh_updates: set[bool] = field(default_factory=set) navmesh_updates: dict[bool, NavMesh] = field(default_factory=dict)
unculled_zones_updated: list[Point] = field(default_factory=list) unculled_zones_updated: list[Point] = field(default_factory=list)
threat_zones_updated: bool = False threat_zones_updated: dict[bool, ThreatZones] = field(default_factory=dict)
new_flights: set[Flight] = field(default_factory=set) new_flights: set[Flight] = field(default_factory=set)
updated_flights: set[Flight] = field(default_factory=set) updated_flights: set[Flight] = field(default_factory=set)
deleted_flights: set[UUID] = field(default_factory=set) deleted_flights: set[UUID] = field(default_factory=set)
@ -67,16 +69,16 @@ class GameUpdateEvents:
self.updated_flight_positions.append((flight, new_position)) self.updated_flight_positions.append((flight, new_position))
return self return self
def update_navmesh(self, player: bool) -> GameUpdateEvents: def update_navmesh(self, player: bool, navmesh: NavMesh) -> GameUpdateEvents:
self.navmesh_updates.add(player) self.navmesh_updates[player] = navmesh
return self return self
def update_unculled_zones(self, zones: list[Point]) -> GameUpdateEvents: def update_unculled_zones(self, zones: list[Point]) -> GameUpdateEvents:
self.unculled_zones_updated = zones self.unculled_zones_updated = zones
return self return self
def update_threat_zones(self) -> GameUpdateEvents: def update_threat_zones(self, player: bool, zones: ThreatZones) -> GameUpdateEvents:
self.threat_zones_updated = True self.threat_zones_updated[player] = zones
return self return self
def new_flight(self, flight: Flight) -> GameUpdateEvents: def new_flight(self, flight: Flight) -> GameUpdateEvents: