mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Fix empty convoys (#1327)
* Hopefully getting rid of empty convoys for good * changing Dict to dict for type checks
This commit is contained in:
parent
c3b8c48ca2
commit
3274f3ec35
@ -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 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 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 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]** Made non-interactive map elements less obstructive.
|
||||||
* **[UI]** Added support for Neutral Dot difficulty label
|
* **[UI]** Added support for Neutral Dot difficulty label
|
||||||
* **[UI]** Clear skies at night no longer described as "Sunny" by the weather widget.
|
* **[UI]** Clear skies at night no longer described as "Sunny" by the weather widget.
|
||||||
|
|||||||
@ -6,7 +6,6 @@ from collections import defaultdict
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from functools import singledispatchmethod
|
from functools import singledispatchmethod
|
||||||
from typing import (
|
from typing import (
|
||||||
Dict,
|
|
||||||
Generic,
|
Generic,
|
||||||
Iterator,
|
Iterator,
|
||||||
List,
|
List,
|
||||||
@ -72,10 +71,18 @@ class TransferOrder:
|
|||||||
player: bool = field(init=False)
|
player: bool = field(init=False)
|
||||||
|
|
||||||
#: The units being transferred.
|
#: The units being transferred.
|
||||||
units: Dict[GroundUnitType, int]
|
units: dict[GroundUnitType, int]
|
||||||
|
|
||||||
transport: Optional[Transport] = field(default=None)
|
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:
|
def __post_init__(self) -> None:
|
||||||
self.position = self.origin
|
self.position = self.origin
|
||||||
self.player = self.origin.is_friendly(to_player=True)
|
self.player = self.origin.is_friendly(to_player=True)
|
||||||
@ -91,12 +98,12 @@ class TransferOrder:
|
|||||||
|
|
||||||
def kill_unit(self, unit_type: GroundUnitType) -> None:
|
def kill_unit(self, unit_type: GroundUnitType) -> None:
|
||||||
if unit_type not in self.units or not self.units[unit_type]:
|
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
|
self.units[unit_type] -= 1
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
return sum(c for c in self.units.values())
|
return sum(self.units.values())
|
||||||
|
|
||||||
def iter_units(self) -> Iterator[GroundUnitType]:
|
def iter_units(self) -> Iterator[GroundUnitType]:
|
||||||
for unit_type, count in self.units.items():
|
for unit_type, count in self.units.items():
|
||||||
@ -105,7 +112,7 @@ class TransferOrder:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def completed(self) -> bool:
|
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:
|
def disband_at(self, location: ControlPoint) -> None:
|
||||||
logging.info(f"Units halting at {location}.")
|
logging.info(f"Units halting at {location}.")
|
||||||
@ -156,7 +163,7 @@ class Airlift(Transport):
|
|||||||
self.flight = flight
|
self.flight = flight
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def units(self) -> Dict[GroundUnitType, int]:
|
def units(self) -> dict[GroundUnitType, int]:
|
||||||
return self.transfer.units
|
return self.transfer.units
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -334,11 +341,11 @@ class MultiGroupTransport(MissionTarget, Transport):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def size(self) -> int:
|
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
|
@property
|
||||||
def units(self) -> dict[GroundUnitType, int]:
|
def units(self) -> dict[GroundUnitType, int]:
|
||||||
units: Dict[GroundUnitType, int] = defaultdict(int)
|
units: dict[GroundUnitType, int] = defaultdict(int)
|
||||||
for transfer in self.transfers:
|
for transfer in self.transfers:
|
||||||
for unit_type, count in transfer.units.items():
|
for unit_type, count in transfer.units.items():
|
||||||
units[unit_type] += count
|
units[unit_type] += count
|
||||||
@ -414,8 +421,8 @@ TransportType = TypeVar("TransportType", bound=MultiGroupTransport)
|
|||||||
class TransportMap(Generic[TransportType]):
|
class TransportMap(Generic[TransportType]):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
# Dict of origin -> destination -> transport.
|
# Dict of origin -> destination -> transport.
|
||||||
self.transports: Dict[
|
self.transports: dict[
|
||||||
ControlPoint, Dict[ControlPoint, TransportType]
|
ControlPoint, dict[ControlPoint, TransportType]
|
||||||
] = defaultdict(dict)
|
] = defaultdict(dict)
|
||||||
|
|
||||||
def create_transport(
|
def create_transport(
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from typing import Any, Callable, Dict, Iterator, Optional, TypeVar
|
from typing import Any, Callable, Iterator, Optional, TypeVar
|
||||||
|
|
||||||
from PySide2.QtCore import (
|
from PySide2.QtCore import (
|
||||||
QAbstractListModel,
|
QAbstractListModel,
|
||||||
@ -51,7 +51,7 @@ class DeletableChildModelManager:
|
|||||||
#: The type of model managed by this class.
|
#: The type of model managed by this class.
|
||||||
ModelType = TypeVar("ModelType")
|
ModelType = TypeVar("ModelType")
|
||||||
|
|
||||||
ModelDict = Dict[DataType, ModelType]
|
ModelDict = dict[DataType, ModelType]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -334,11 +334,7 @@ class TransferModel(QAbstractListModel):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def text_for_transfer(transfer: TransferOrder) -> str:
|
def text_for_transfer(transfer: TransferOrder) -> str:
|
||||||
"""Returns the text that should be displayed for the transfer."""
|
"""Returns the text that should be displayed for the transfer."""
|
||||||
count = sum(transfer.units.values())
|
return str(transfer)
|
||||||
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}"
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def icon_for_transfer(_transfer: TransferOrder) -> Optional[QIcon]:
|
def icon_for_transfer(_transfer: TransferOrder) -> Optional[QIcon]:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user