mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Move unculled zones out of MapModel.
This commit is contained in:
parent
95836a217c
commit
1c543666b5
@ -18,6 +18,7 @@ class GameUpdateEventsJs(BaseModel):
|
|||||||
new_combats: list[FrozenCombatJs] = []
|
new_combats: list[FrozenCombatJs] = []
|
||||||
updated_combats: list[FrozenCombatJs] = []
|
updated_combats: list[FrozenCombatJs] = []
|
||||||
navmesh_updates: set[bool] = set()
|
navmesh_updates: set[bool] = set()
|
||||||
|
unculled_zones_updated: bool = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_events(cls, events: GameUpdateEvents, game: Game) -> GameUpdateEventsJs:
|
def from_events(cls, events: GameUpdateEvents, game: Game) -> GameUpdateEventsJs:
|
||||||
@ -33,4 +34,5 @@ class GameUpdateEventsJs(BaseModel):
|
|||||||
for c in events.updated_combats
|
for c in events.updated_combats
|
||||||
],
|
],
|
||||||
navmesh_updates=events.navmesh_updates,
|
navmesh_updates=events.navmesh_updates,
|
||||||
|
unculled_zones_updated=events.unculled_zones_updated,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dcs.mapping import LatLng
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from game.server.leaflet import LeafletPoly
|
from game.server.leaflet import LeafletPoly
|
||||||
@ -9,3 +10,8 @@ class MapZonesJs(BaseModel):
|
|||||||
inclusion: list[LeafletPoly]
|
inclusion: list[LeafletPoly]
|
||||||
exclusion: list[LeafletPoly]
|
exclusion: list[LeafletPoly]
|
||||||
sea: list[LeafletPoly]
|
sea: list[LeafletPoly]
|
||||||
|
|
||||||
|
|
||||||
|
class UnculledZoneJs(BaseModel):
|
||||||
|
position: LatLng
|
||||||
|
radius: float
|
||||||
|
|||||||
@ -2,14 +2,14 @@ from fastapi import APIRouter, Depends, HTTPException, status
|
|||||||
|
|
||||||
from game import Game
|
from game import Game
|
||||||
from game.server import GameContext
|
from game.server import GameContext
|
||||||
from .models import MapZonesJs
|
from .models import MapZonesJs, UnculledZoneJs
|
||||||
from ..leaflet import ShapelyUtil
|
from ..leaflet import ShapelyUtil
|
||||||
|
|
||||||
router: APIRouter = APIRouter(prefix="/map-zones")
|
router: APIRouter = APIRouter(prefix="/map-zones")
|
||||||
|
|
||||||
|
|
||||||
@router.get("/")
|
@router.get("/terrain")
|
||||||
def get(game: Game = Depends(GameContext.get)) -> MapZonesJs:
|
def get_terrain(game: Game = Depends(GameContext.get)) -> MapZonesJs:
|
||||||
zones = game.theater.landmap
|
zones = game.theater.landmap
|
||||||
if zones is None:
|
if zones is None:
|
||||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||||
@ -19,3 +19,13 @@ def get(game: Game = Depends(GameContext.get)) -> MapZonesJs:
|
|||||||
exclusion=ShapelyUtil.polys_to_leaflet(zones.exclusion_zones, game.theater),
|
exclusion=ShapelyUtil.polys_to_leaflet(zones.exclusion_zones, game.theater),
|
||||||
sea=ShapelyUtil.polys_to_leaflet(zones.sea_zones, game.theater),
|
sea=ShapelyUtil.polys_to_leaflet(zones.sea_zones, game.theater),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/unculled")
|
||||||
|
def get_unculled_zones(game: Game = Depends(GameContext.get)) -> list[UnculledZoneJs]:
|
||||||
|
return [
|
||||||
|
UnculledZoneJs(
|
||||||
|
position=zone.latlng(), radius=game.settings.perf_culling_distance * 1000
|
||||||
|
)
|
||||||
|
for zone in game.get_culling_zones()
|
||||||
|
]
|
||||||
|
|||||||
@ -16,6 +16,7 @@ class GameUpdateEvents:
|
|||||||
self.updated_combats: list[FrozenCombat] = []
|
self.updated_combats: list[FrozenCombat] = []
|
||||||
self.updated_flights: list[tuple[Flight, Point]] = []
|
self.updated_flights: list[tuple[Flight, Point]] = []
|
||||||
self.navmesh_updates: set[bool] = set()
|
self.navmesh_updates: set[bool] = set()
|
||||||
|
self.unculled_zones_updated: bool = False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def empty(self) -> bool:
|
def empty(self) -> bool:
|
||||||
@ -26,6 +27,7 @@ class GameUpdateEvents:
|
|||||||
self.updated_combats,
|
self.updated_combats,
|
||||||
self.updated_flights,
|
self.updated_flights,
|
||||||
self.navmesh_updates,
|
self.navmesh_updates,
|
||||||
|
self.unculled_zones_updated,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,3 +45,6 @@ class GameUpdateEvents:
|
|||||||
|
|
||||||
def update_navmesh(self, player: bool) -> None:
|
def update_navmesh(self, player: bool) -> None:
|
||||||
self.navmesh_updates.add(player)
|
self.navmesh_updates.add(player)
|
||||||
|
|
||||||
|
def update_unculled_zones(self) -> None:
|
||||||
|
self.unculled_zones_updated = True
|
||||||
|
|||||||
@ -16,12 +16,13 @@ from game.ato.airtaaskingorder import AirTaskingOrder
|
|||||||
from game.ato.flight import Flight
|
from game.ato.flight import Flight
|
||||||
from game.ato.flighttype import FlightType
|
from game.ato.flighttype import FlightType
|
||||||
from game.ato.package import Package
|
from game.ato.package import Package
|
||||||
|
from game.ato.traveltime import TotEstimator
|
||||||
from game.game import Game
|
from game.game import Game
|
||||||
|
from game.server import EventStream
|
||||||
from game.sim.gameupdateevents import GameUpdateEvents
|
from game.sim.gameupdateevents import GameUpdateEvents
|
||||||
from game.squadrons.squadron import Pilot, Squadron
|
from game.squadrons.squadron import Pilot, Squadron
|
||||||
from game.theater.missiontarget import MissionTarget
|
from game.theater.missiontarget import MissionTarget
|
||||||
from game.transfers import PendingTransfers, TransferOrder
|
from game.transfers import PendingTransfers, TransferOrder
|
||||||
from game.ato.traveltime import TotEstimator
|
|
||||||
from qt_ui.simcontroller import SimController
|
from qt_ui.simcontroller import SimController
|
||||||
from qt_ui.uiconstants import AIRCRAFT_ICONS
|
from qt_ui.uiconstants import AIRCRAFT_ICONS
|
||||||
|
|
||||||
@ -279,7 +280,9 @@ class AtoModel(QAbstractListModel):
|
|||||||
def on_packages_changed(self) -> None:
|
def on_packages_changed(self) -> None:
|
||||||
if self.game is not None:
|
if self.game is not None:
|
||||||
self.game.compute_unculled_zones()
|
self.game.compute_unculled_zones()
|
||||||
self.packages_changed.emit()
|
events = GameUpdateEvents()
|
||||||
|
events.update_unculled_zones()
|
||||||
|
EventStream.put_nowait(events)
|
||||||
|
|
||||||
def package_at_index(self, index: QModelIndex) -> Package:
|
def package_at_index(self, index: QModelIndex) -> Package:
|
||||||
"""Returns the package at the given index."""
|
"""Returns the package at the given index."""
|
||||||
|
|||||||
@ -23,7 +23,6 @@ from .groundobjectjs import GroundObjectJs
|
|||||||
from .supplyroutejs import SupplyRouteJs
|
from .supplyroutejs import SupplyRouteJs
|
||||||
from .threatzonecontainerjs import ThreatZoneContainerJs
|
from .threatzonecontainerjs import ThreatZoneContainerJs
|
||||||
from .threatzonesjs import ThreatZonesJs
|
from .threatzonesjs import ThreatZonesJs
|
||||||
from .unculledzonejs import UnculledZone
|
|
||||||
|
|
||||||
|
|
||||||
# **EVERY PROPERTY NEEDS A NOTIFY SIGNAL**
|
# **EVERY PROPERTY NEEDS A NOTIFY SIGNAL**
|
||||||
@ -53,7 +52,6 @@ class MapModel(QObject):
|
|||||||
flightsChanged = Signal()
|
flightsChanged = Signal()
|
||||||
frontLinesChanged = Signal()
|
frontLinesChanged = Signal()
|
||||||
threatZonesChanged = Signal()
|
threatZonesChanged = Signal()
|
||||||
unculledZonesChanged = Signal()
|
|
||||||
selectedFlightChanged = Signal(str)
|
selectedFlightChanged = Signal(str)
|
||||||
|
|
||||||
def __init__(self, game_model: GameModel) -> None:
|
def __init__(self, game_model: GameModel) -> None:
|
||||||
@ -68,7 +66,6 @@ class MapModel(QObject):
|
|||||||
self._threat_zones = ThreatZoneContainerJs(
|
self._threat_zones = ThreatZoneContainerJs(
|
||||||
ThreatZonesJs.empty(), ThreatZonesJs.empty()
|
ThreatZonesJs.empty(), ThreatZonesJs.empty()
|
||||||
)
|
)
|
||||||
self._unculled_zones = []
|
|
||||||
self._selected_flight_index: Optional[Tuple[int, int]] = None
|
self._selected_flight_index: Optional[Tuple[int, int]] = None
|
||||||
|
|
||||||
GameUpdateSignal.get_instance().game_loaded.connect(self.on_game_load)
|
GameUpdateSignal.get_instance().game_loaded.connect(self.on_game_load)
|
||||||
@ -79,12 +76,6 @@ class MapModel(QObject):
|
|||||||
GameUpdateSignal.get_instance().flight_selection_changed.connect(
|
GameUpdateSignal.get_instance().flight_selection_changed.connect(
|
||||||
self.set_flight_selection
|
self.set_flight_selection
|
||||||
)
|
)
|
||||||
self.game_model.ato_model_for(True).packages_changed.connect(
|
|
||||||
self.on_package_change
|
|
||||||
),
|
|
||||||
self.game_model.ato_model_for(False).packages_changed.connect(
|
|
||||||
self.on_package_change
|
|
||||||
),
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
def clear(self) -> None:
|
def clear(self) -> None:
|
||||||
@ -96,7 +87,6 @@ class MapModel(QObject):
|
|||||||
self._threat_zones = ThreatZoneContainerJs(
|
self._threat_zones = ThreatZoneContainerJs(
|
||||||
ThreatZonesJs.empty(), ThreatZonesJs.empty()
|
ThreatZonesJs.empty(), ThreatZonesJs.empty()
|
||||||
)
|
)
|
||||||
self._unculled_zones = []
|
|
||||||
self.cleared.emit()
|
self.cleared.emit()
|
||||||
|
|
||||||
def set_package_selection(self, index: int) -> None:
|
def set_package_selection(self, index: int) -> None:
|
||||||
@ -160,7 +150,6 @@ class MapModel(QObject):
|
|||||||
self.reset_atos()
|
self.reset_atos()
|
||||||
self.reset_front_lines()
|
self.reset_front_lines()
|
||||||
self.reset_threat_zones()
|
self.reset_threat_zones()
|
||||||
self.reset_unculled_zones()
|
|
||||||
|
|
||||||
def on_game_load(self, game: Optional[Game]) -> None:
|
def on_game_load(self, game: Optional[Game]) -> None:
|
||||||
if game is not None:
|
if game is not None:
|
||||||
@ -292,17 +281,6 @@ class MapModel(QObject):
|
|||||||
def threatZones(self) -> ThreatZoneContainerJs:
|
def threatZones(self) -> ThreatZoneContainerJs:
|
||||||
return self._threat_zones
|
return self._threat_zones
|
||||||
|
|
||||||
def on_package_change(self) -> None:
|
|
||||||
self.reset_unculled_zones()
|
|
||||||
|
|
||||||
def reset_unculled_zones(self) -> None:
|
|
||||||
self._unculled_zones = list(UnculledZone.each_from_game(self.game))
|
|
||||||
self.unculledZonesChanged.emit()
|
|
||||||
|
|
||||||
@Property(list, notify=unculledZonesChanged)
|
|
||||||
def unculledZones(self) -> list[UnculledZone]:
|
|
||||||
return self._unculled_zones
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def game(self) -> Game:
|
def game(self) -> Game:
|
||||||
if self.game_model.game is None:
|
if self.game_model.game is None:
|
||||||
|
|||||||
@ -1,33 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from typing import Iterator
|
|
||||||
|
|
||||||
from PySide2.QtCore import Property, QObject, Signal
|
|
||||||
|
|
||||||
from game import Game
|
|
||||||
from game.server.leaflet import LeafletLatLon
|
|
||||||
|
|
||||||
|
|
||||||
class UnculledZone(QObject):
|
|
||||||
positionChanged = Signal()
|
|
||||||
radiusChanged = Signal()
|
|
||||||
|
|
||||||
def __init__(self, position: LeafletLatLon, radius: float) -> None:
|
|
||||||
super().__init__()
|
|
||||||
self._position = position
|
|
||||||
self._radius = radius
|
|
||||||
|
|
||||||
@Property(list, notify=positionChanged)
|
|
||||||
def position(self) -> LeafletLatLon:
|
|
||||||
return self._position
|
|
||||||
|
|
||||||
@Property(float, notify=radiusChanged)
|
|
||||||
def radius(self) -> float:
|
|
||||||
return self._radius
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def each_from_game(cls, game: Game) -> Iterator[UnculledZone]:
|
|
||||||
for zone in game.get_culling_zones():
|
|
||||||
yield UnculledZone(
|
|
||||||
zone.latlng().as_list(), game.settings.perf_culling_distance * 1000
|
|
||||||
)
|
|
||||||
@ -385,7 +385,6 @@ new QWebChannel(qt.webChannelTransport, function (channel) {
|
|||||||
game.flightsChanged.connect(drawAircraft);
|
game.flightsChanged.connect(drawAircraft);
|
||||||
game.threatZonesChanged.connect(drawThreatZones);
|
game.threatZonesChanged.connect(drawThreatZones);
|
||||||
game.mapZonesChanged.connect(drawMapZones);
|
game.mapZonesChanged.connect(drawMapZones);
|
||||||
game.unculledZonesChanged.connect(drawUnculledZones);
|
|
||||||
game.selectedFlightChanged.connect(updateSelectedFlight);
|
game.selectedFlightChanged.connect(updateSelectedFlight);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -402,6 +401,9 @@ function handleStreamedEvents(events) {
|
|||||||
for (const player of events.navmesh_updates) {
|
for (const player of events.navmesh_updates) {
|
||||||
drawNavmesh(player);
|
drawNavmesh(player);
|
||||||
}
|
}
|
||||||
|
if (events.unculled_zones_updated) {
|
||||||
|
drawUnculledZones();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function recenterMap(center) {
|
function recenterMap(center) {
|
||||||
@ -1124,7 +1126,7 @@ function drawMapZones() {
|
|||||||
inclusionZones.clearLayers();
|
inclusionZones.clearLayers();
|
||||||
exclusionZones.clearLayers();
|
exclusionZones.clearLayers();
|
||||||
|
|
||||||
getJson("/map-zones").then((zones) => {
|
getJson("/map-zones/terrain").then((zones) => {
|
||||||
for (const zone of zones.sea) {
|
for (const zone of zones.sea) {
|
||||||
L.polygon(zone, {
|
L.polygon(zone, {
|
||||||
color: "#344455",
|
color: "#344455",
|
||||||
@ -1157,7 +1159,8 @@ function drawMapZones() {
|
|||||||
function drawUnculledZones() {
|
function drawUnculledZones() {
|
||||||
unculledZones.clearLayers();
|
unculledZones.clearLayers();
|
||||||
|
|
||||||
for (const zone of game.unculledZones) {
|
getJson("/map-zones/unculled").then((zones) => {
|
||||||
|
for (const zone of zones) {
|
||||||
L.circle(zone.position, {
|
L.circle(zone.position, {
|
||||||
radius: zone.radius,
|
radius: zone.radius,
|
||||||
color: "#b4ff8c",
|
color: "#b4ff8c",
|
||||||
@ -1165,6 +1168,7 @@ function drawUnculledZones() {
|
|||||||
interactive: false,
|
interactive: false,
|
||||||
}).addTo(unculledZones);
|
}).addTo(unculledZones);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawIpZones(id) {
|
function drawIpZones(id) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user