* Fixes #1310 by only refunding GUs if no faction CP has an attached factory.  Previously it would refund all units at the CP, including aircraft.

Also changes the CP CAPTURE cheat to work at any CP regardless of adjacency to frontline or BLUEFOR/OPFOR state.

* Fixing typing issues, changint all Dict[] types to dict[]

* Updating changelog
This commit is contained in:
bgreman 2021-06-23 17:09:17 -04:00 committed by GitHub
parent d365094616
commit c3b8c48ca2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 21 deletions

View File

@ -28,6 +28,7 @@ Saves from 3.x are not compatible with 4.0.
* **[UI]** Multiple waypoints can now be deleted simultaneously if multiple waypoints are selected.
* **[UI]** Carriers and LHAs now match the colour of airfields, and their destination icons are translucent.
* **[UI]** Updated intel box text for first turn.
* **[UI]** Base Capture Cheat is now usable at all bases and can also be used to transfer player-owned bases to OPFOR.
* **[Units/Factions/Mods]** Removes MB-339PAN support, as the mod is now deprecated and no longer works with DCS 2.7+.
* **[New Game Wizard]** Mods are now selected via checkboxes in the new game wizard, not as separate factions.
@ -35,6 +36,7 @@ Saves from 3.x are not compatible with 4.0.
* **[Campaign AI]** Fix procurement for factions that lack some unit types.
* **[Campaign AI]** Fix auto purchase of aircraft for factions that have no transport aircraft.
* **[Campaign AI]** Fix refunding of pending aircraft purchases when a side has no factory available.
* **[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.

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import logging
from collections import defaultdict
from dataclasses import dataclass
from typing import Dict, Optional, TYPE_CHECKING, Any
from typing import Optional, TYPE_CHECKING, Any
from game.theater import ControlPoint
from .dcs.groundunittype import GroundUnitType
@ -28,16 +28,16 @@ class PendingUnitDeliveries:
self.destination = destination
# Maps unit type to order quantity.
self.units: Dict[UnitType, int] = defaultdict(int)
self.units: dict[UnitType, int] = defaultdict(int)
def __str__(self) -> str:
return f"Pending delivery to {self.destination}"
def order(self, units: Dict[UnitType, int]) -> None:
def order(self, units: dict[UnitType, int]) -> None:
for k, v in units.items():
self.units[k] += v
def sell(self, units: Dict[UnitType, int]) -> None:
def sell(self, units: dict[UnitType, int]) -> None:
for k, v in units.items():
self.units[k] -= v
@ -45,7 +45,15 @@ class PendingUnitDeliveries:
self.refund(game, self.units)
self.units = defaultdict(int)
def refund(self, game: Game, units: Dict[UnitType, int]) -> None:
def refund_ground_units(self, game: Game) -> None:
ground_units: dict[UnitType[Any], int] = {
u: self.units[u] for u in self.units.keys() if isinstance(u, GroundUnitType)
}
self.refund(game, ground_units)
for gu in ground_units.keys():
del self.units[gu]
def refund(self, game: Game, units: dict[UnitType, int]) -> None:
for unit_type, count in units.items():
logging.info(f"Refunding {count} {unit_type} at {self.destination.name}")
game.adjust_budget(
@ -69,12 +77,11 @@ class PendingUnitDeliveries:
f"{self.destination.name} lost its source for ground unit "
"reinforcements. Refunding purchase price."
)
self.refund_all(game)
return
self.refund_ground_units(game)
bought_units: Dict[UnitType, int] = {}
units_needing_transfer: Dict[GroundUnitType, int] = {}
sold_units: Dict[UnitType, int] = {}
bought_units: dict[UnitType, int] = {}
units_needing_transfer: dict[GroundUnitType, int] = {}
sold_units: dict[UnitType, int] = {}
for unit_type, count in self.units.items():
coalition = "Ally" if self.destination.captured else "Enemy"
d: dict[Any, int]
@ -102,11 +109,16 @@ class PendingUnitDeliveries:
self.destination.base.commit_losses(sold_units)
if units_needing_transfer:
if ground_unit_source is None:
raise RuntimeError(
f"ground unit source could not be found for {self.destination} but still tried to "
f"transfer units to there"
)
ground_unit_source.base.commission_units(units_needing_transfer)
self.create_transfer(game, ground_unit_source, units_needing_transfer)
def create_transfer(
self, game: Game, source: ControlPoint, units: Dict[GroundUnitType, int]
self, game: Game, source: ControlPoint, units: dict[GroundUnitType, int]
) -> None:
game.transfers.new_transfer(TransferOrder(source, self.destination, units))

View File

@ -118,18 +118,10 @@ class QBaseMenu2(QDialog):
@property
def cheat_capturable(self) -> bool:
if not self.game_model.game.settings.enable_base_capture_cheat:
return False
if self.cp.captured:
return False
for connected in self.cp.connected_points:
if connected.captured:
return True
return False
return self.game_model.game.settings.enable_base_capture_cheat
def cheat_capture(self) -> None:
self.cp.capture(self.game_model.game, for_player=True)
self.cp.capture(self.game_model.game, for_player=not self.cp.captured)
# Reinitialized ground planners and the like. The ATO needs to be reset because
# missions planned against the flipped base are no longer valid.
self.game_model.game.reset_ato()