diff --git a/changelog.md b/changelog.md index 0fc7d44e..59c6c646 100644 --- a/changelog.md +++ b/changelog.md @@ -40,6 +40,7 @@ Saves from 3.x are not compatible with 4.0. * **[Mission Generation]** Fixed problem with mission load when control point name contained an apostrophe. * **[Mission Generation]** Fixed EWR group names so they contribute to Skynet again. * **[Mission Generation]** Fixed duplicate name error when generating convoys and cargo ships when creating manual transfers after loading a game. +* **[Mission Generation]** Fixed empty convoys not being disbanded when all units are killed/removed. * **[UI]** Made non-interactive map elements less obstructive. * **[UI]** Added support for Neutral Dot difficulty label * **[UI]** Clear skies at night no longer described as "Sunny" by the weather widget. diff --git a/game/transfers.py b/game/transfers.py index 0fd432f4..3c6f2cee 100644 --- a/game/transfers.py +++ b/game/transfers.py @@ -6,7 +6,6 @@ from collections import defaultdict from dataclasses import dataclass, field from functools import singledispatchmethod from typing import ( - Dict, Generic, Iterator, List, @@ -72,10 +71,18 @@ class TransferOrder: player: bool = field(init=False) #: The units being transferred. - units: Dict[GroundUnitType, int] + units: dict[GroundUnitType, int] transport: Optional[Transport] = field(default=None) + def __str__(self) -> str: + """Returns the text that should be displayed for the transfer.""" + count = self.size + origin = self.origin.name + destination = self.destination.name + description = "Transfer" if self.player else "Enemy transfer" + return f"{description} of {count} units from {origin} to {destination}" + def __post_init__(self) -> None: self.position = self.origin self.player = self.origin.is_friendly(to_player=True) @@ -91,12 +98,12 @@ class TransferOrder: def kill_unit(self, unit_type: GroundUnitType) -> None: if unit_type not in self.units or not self.units[unit_type]: - raise KeyError(f"{self.destination} has no {unit_type} remaining") + raise KeyError(f"{self} has no {unit_type} remaining") self.units[unit_type] -= 1 @property def size(self) -> int: - return sum(c for c in self.units.values()) + return sum(self.units.values()) def iter_units(self) -> Iterator[GroundUnitType]: for unit_type, count in self.units.items(): @@ -105,7 +112,7 @@ class TransferOrder: @property def completed(self) -> bool: - return self.destination == self.position or not self.units + return self.destination == self.position or not self.size def disband_at(self, location: ControlPoint) -> None: logging.info(f"Units halting at {location}.") @@ -156,7 +163,7 @@ class Airlift(Transport): self.flight = flight @property - def units(self) -> Dict[GroundUnitType, int]: + def units(self) -> dict[GroundUnitType, int]: return self.transfer.units @property @@ -334,11 +341,11 @@ class MultiGroupTransport(MissionTarget, Transport): @property def size(self) -> int: - return sum(sum(t.units.values()) for t in self.transfers) + return sum(t.size for t in self.transfers) @property def units(self) -> dict[GroundUnitType, int]: - units: Dict[GroundUnitType, int] = defaultdict(int) + units: dict[GroundUnitType, int] = defaultdict(int) for transfer in self.transfers: for unit_type, count in transfer.units.items(): units[unit_type] += count @@ -414,8 +421,8 @@ TransportType = TypeVar("TransportType", bound=MultiGroupTransport) class TransportMap(Generic[TransportType]): def __init__(self) -> None: # Dict of origin -> destination -> transport. - self.transports: Dict[ - ControlPoint, Dict[ControlPoint, TransportType] + self.transports: dict[ + ControlPoint, dict[ControlPoint, TransportType] ] = defaultdict(dict) def create_transport( diff --git a/qt_ui/models.py b/qt_ui/models.py index dd214e84..4e5f46b3 100644 --- a/qt_ui/models.py +++ b/qt_ui/models.py @@ -2,7 +2,7 @@ from __future__ import annotations import datetime -from typing import Any, Callable, Dict, Iterator, Optional, TypeVar +from typing import Any, Callable, Iterator, Optional, TypeVar from PySide2.QtCore import ( QAbstractListModel, @@ -51,7 +51,7 @@ class DeletableChildModelManager: #: The type of model managed by this class. ModelType = TypeVar("ModelType") - ModelDict = Dict[DataType, ModelType] + ModelDict = dict[DataType, ModelType] def __init__( self, @@ -334,11 +334,7 @@ class TransferModel(QAbstractListModel): @staticmethod def text_for_transfer(transfer: TransferOrder) -> str: """Returns the text that should be displayed for the transfer.""" - count = sum(transfer.units.values()) - origin = transfer.origin.name - destination = transfer.destination.name - description = "Transfer" if transfer.player else "Enemy transfer" - return f"{description} of {count} units from {origin} to {destination}" + return str(transfer) @staticmethod def icon_for_transfer(_transfer: TransferOrder) -> Optional[QIcon]: