Remove the old map.

The new map has no open bugs.
This commit is contained in:
Dan Albert
2022-03-20 16:13:07 -07:00
parent 3af3bd606c
commit f72b2a21f7
28 changed files with 10 additions and 61785 deletions

View File

@@ -2,22 +2,16 @@ from __future__ import annotations
import logging
from pathlib import Path
from typing import (
Optional,
)
from PySide2.QtCore import QUrl
from PySide2.QtWebChannel import QWebChannel
from PySide2.QtWebEngineWidgets import (
QWebEnginePage,
QWebEngineSettings,
QWebEngineView,
)
from game import Game
from game.server.settings import ServerSettings
from qt_ui.models import GameModel
from .model import MapModel
class LoggingWebPage(QWebEnginePage):
@@ -37,14 +31,10 @@ class LoggingWebPage(QWebEnginePage):
class QLiberationMap(QWebEngineView):
def __init__(self, game_model: GameModel, new_map: bool, dev: bool, parent) -> None:
def __init__(self, game_model: GameModel, dev: bool, parent) -> None:
super().__init__(parent)
self.game_model = game_model
self.setMinimumSize(800, 600)
self.map_model = MapModel(game_model)
self.channel = QWebChannel()
self.channel.registerObject("game", self.map_model)
self.page = LoggingWebPage(self)
# Required to allow "cross-origin" access from file:// scoped canvas.html to the
@@ -52,16 +42,11 @@ class QLiberationMap(QWebEngineView):
self.page.settings().setAttribute(
QWebEngineSettings.LocalContentCanAccessRemoteUrls, True
)
self.page.setWebChannel(self.channel)
if new_map and dev:
if dev:
url = QUrl("http://localhost:3000")
elif new_map:
url = QUrl.fromLocalFile(str(Path("client/build/index.html").resolve()))
else:
url = QUrl.fromLocalFile(
str(Path("resources/ui/map/canvas.html").resolve())
)
url = QUrl.fromLocalFile(str(Path("client/build/index.html").resolve()))
server_settings = ServerSettings.get()
host = server_settings.server_bind_address
if host.startswith("::"):
@@ -70,9 +55,3 @@ class QLiberationMap(QWebEngineView):
url.setQuery(f"server={host}:{port}")
self.page.load(url)
self.setPage(self.page)
def set_game(self, game: Optional[Game]) -> None:
if game is None:
self.map_model.clear()
else:
self.map_model.reset()

View File

@@ -1 +0,0 @@
from .mapmodel import MapModel

View File

@@ -1,108 +0,0 @@
from __future__ import annotations
from typing import Optional
from PySide2.QtCore import Property, QObject, Signal, Slot
from dcs import Point
from dcs.mapping import LatLng
from game.theater import ConflictTheater, ControlPoint
from game.utils import meters, nautical_miles
from qt_ui.dialogs import Dialog
from qt_ui.models import GameModel
from qt_ui.windows.basemenu.QBaseMenu2 import QBaseMenu2
from .leaflet import LeafletLatLon
MAX_SHIP_DISTANCE = nautical_miles(80)
class ControlPointJs(QObject):
nameChanged = Signal()
blueChanged = Signal()
positionChanged = Signal()
mobileChanged = Signal()
destinationChanged = Signal(list)
sidcChanged = Signal()
def __init__(
self,
control_point: ControlPoint,
game_model: GameModel,
theater: ConflictTheater,
) -> None:
super().__init__()
self.control_point = control_point
self.game_model = game_model
self.theater = theater
self.dialog: Optional[QBaseMenu2] = None
@Property(str, notify=nameChanged)
def name(self) -> str:
return self.control_point.name
@Property(bool, notify=blueChanged)
def blue(self) -> bool:
return self.control_point.captured
@Property(str, notify=sidcChanged)
def sidc(self) -> str:
return str(self.control_point.sidc())
@Property(list, notify=positionChanged)
def position(self) -> LeafletLatLon:
return self.control_point.position.latlng().as_list()
@Property(bool, notify=mobileChanged)
def mobile(self) -> bool:
return self.control_point.moveable and self.control_point.captured
@Property(list, notify=destinationChanged)
def destination(self) -> LeafletLatLon:
if self.control_point.target_position is None:
# Qt seems to convert None to [] for list Properties :(
return []
return self.control_point.target_position.latlng().as_list()
def destination_in_range(self, destination: Point) -> bool:
move_distance = meters(
destination.distance_to_point(self.control_point.position)
)
return move_distance <= MAX_SHIP_DISTANCE
@Slot(list, result=bool)
def destinationInRange(self, destination: LeafletLatLon) -> bool:
return self.destination_in_range(
Point.from_latlng(LatLng(*destination), self.theater.terrain)
)
@Slot(list, result=str)
def setDestination(self, destination: LeafletLatLon) -> str:
if not self.control_point.moveable:
return f"{self.control_point} is not mobile"
if not self.control_point.captured:
return f"{self.control_point} is not owned by player"
point = Point.from_latlng(LatLng(*destination), self.theater.terrain)
if not self.destination_in_range(point):
return (
f"Cannot move {self.control_point} more than "
f"{MAX_SHIP_DISTANCE.nautical_miles}nm."
)
self.control_point.target_position = point
self.destinationChanged.emit(destination)
return ""
@Slot()
def cancelTravel(self) -> None:
self.control_point.target_position = None
self.destinationChanged.emit([])
@Slot()
def showInfoDialog(self) -> None:
if self.dialog is None:
self.dialog = QBaseMenu2(None, self.control_point, self.game_model)
self.dialog.show()
@Slot()
def showPackageDialog(self) -> None:
Dialog.open_new_package_dialog(self.control_point)

View File

@@ -1,2 +0,0 @@
LeafletLatLon = list[float]
LeafletPoly = list[LeafletLatLon]

View File

@@ -1,132 +0,0 @@
from __future__ import annotations
from typing import List, Optional
from PySide2.QtCore import Property, QObject, Signal
from dcs.mapping import LatLng
from game import Game
from game.profiling import logged_duration
from game.theater import (
ConflictTheater,
)
from qt_ui.models import GameModel
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from .controlpointjs import ControlPointJs
from .leaflet import LeafletLatLon
from .supplyroutejs import SupplyRouteJs
# **EVERY PROPERTY NEEDS A NOTIFY SIGNAL**
#
# https://bugreports.qt.io/browse/PYSIDE-1426
#
# PySide2 5.15.2 released 6 days before the fix for this was merged, but presumably we
# can clean up after 5.15.3 (or a future version) is released.
#
# Until then, all properties must use a notify signal. For some reason the error doesn't
# show up when running from source, and member properties also are not sufficient.
# Failing to do this will cause every sync of the property to emit an expensive log
# message. This can prevent the UI from being responsive.
#
# A local signal (i.e. `@Property(t, notify=Signal())`) is not sufficient. The class
# needs a named signal for every property, even if it is constant.
class MapModel(QObject):
cleared = Signal()
apiKeyChanged = Signal(str)
mapCenterChanged = Signal(list)
controlPointsChanged = Signal()
supplyRoutesChanged = Signal()
mapReset = Signal()
def __init__(self, game_model: GameModel) -> None:
super().__init__()
self.game_model = game_model
self._map_center = LatLng(0, 0)
self._control_points = []
self._supply_routes = []
GameUpdateSignal.get_instance().game_loaded.connect(self.on_game_load)
self.reset()
def clear(self) -> None:
self._control_points = []
self._supply_routes = []
self.cleared.emit()
def reset(self) -> None:
if self.game_model.game is None:
self.clear()
return
with logged_duration("Map reset"):
self.reset_control_points()
self.reset_routes()
self.mapReset.emit()
def on_game_load(self, game: Optional[Game]) -> None:
if game is not None:
self.reset_map_center(game.theater)
def reset_map_center(self, theater: ConflictTheater) -> None:
self._map_center = theater.terrain.map_view_default.position.latlng()
self.mapCenterChanged.emit(self._map_center.as_list())
@Property(list, notify=mapCenterChanged)
def mapCenter(self) -> LeafletLatLon:
return self._map_center.as_list()
def reset_control_points(self) -> None:
self._control_points = [
ControlPointJs(c, self.game_model, self.game.theater)
for c in self.game.theater.controlpoints
]
self.controlPointsChanged.emit()
@Property(list, notify=controlPointsChanged)
def controlPoints(self) -> List[ControlPointJs]:
return self._control_points
def reset_routes(self) -> None:
seen = set()
self._supply_routes = []
for control_point in self.game.theater.controlpoints:
seen.add(control_point)
for destination, convoy_route in control_point.convoy_routes.items():
if destination in seen:
continue
self._supply_routes.append(
SupplyRouteJs(
control_point,
destination,
[p.latlng().as_list() for p in convoy_route],
sea_route=False,
game=self.game,
)
)
for destination, shipping_lane in control_point.shipping_lanes.items():
if destination in seen:
continue
if control_point.is_friendly(destination.captured):
self._supply_routes.append(
SupplyRouteJs(
control_point,
destination,
[p.latlng().as_list() for p in shipping_lane],
sea_route=True,
game=self.game,
)
)
self.supplyRoutesChanged.emit()
@Property(list, notify=supplyRoutesChanged)
def supplyRoutes(self) -> List[SupplyRouteJs]:
return self._supply_routes
@property
def game(self) -> Game:
if self.game_model.game is None:
raise RuntimeError("No game loaded")
return self.game_model.game

View File

@@ -1,91 +0,0 @@
from __future__ import annotations
from typing import List
from PySide2.QtCore import Property, QObject, Signal
from game import Game
from game.theater import ControlPoint
from game.transfers import MultiGroupTransport, TransportMap
from .leaflet import LeafletLatLon
class SupplyRouteJs(QObject):
pointsChanged = Signal()
frontActiveChanged = Signal()
isSeaChanged = Signal()
blueChanged = Signal()
activeTransportsChanged = Signal()
def __init__(
self,
a: ControlPoint,
b: ControlPoint,
points: List[LeafletLatLon],
sea_route: bool,
game: Game,
) -> None:
super().__init__()
self.control_point_a = a
self.control_point_b = b
self._points = points
self.sea_route = sea_route
self.game = game
def find_in_transport_map(
self, transport_map: TransportMap
) -> List[MultiGroupTransport]:
transports = []
transport = transport_map.find_transport(
self.control_point_a, self.control_point_b
)
if transport is not None:
transports.append(transport)
transport = transport_map.find_transport(
self.control_point_b, self.control_point_a
)
if transport is not None:
transports.append(transport)
return transports
def find_transports(self) -> List[MultiGroupTransport]:
if self.sea_route:
return self.find_in_transport_map(
self.game.blue.transfers.cargo_ships
) + self.find_in_transport_map(self.game.red.transfers.cargo_ships)
return self.find_in_transport_map(
self.game.blue.transfers.convoys
) + self.find_in_transport_map(self.game.red.transfers.convoys)
@Property(list, notify=activeTransportsChanged)
def activeTransports(self) -> List[str]:
transports = self.find_transports()
if not transports:
return []
descriptions = []
for transport in transports:
units = "units" if transport.size > 1 else "unit"
descriptions.append(
f"{transport.size} {units} transferring from {transport.origin} to "
f"{transport.destination}"
)
return descriptions
@Property(list, notify=pointsChanged)
def points(self) -> List[LeafletLatLon]:
return self._points
@Property(bool, notify=frontActiveChanged)
def frontActive(self) -> bool:
if self.sea_route:
return False
return self.control_point_a.front_is_active(self.control_point_b)
@Property(bool, notify=isSeaChanged)
def isSea(self) -> bool:
return self.sea_route
@Property(bool, notify=blueChanged)
def blue(self) -> bool:
return self.control_point_a.captured