From c3b8c48ca25df1cd5f77a353775410450952e2a6 Mon Sep 17 00:00:00 2001 From: bgreman <47828384+bgreman@users.noreply.github.com> Date: Wed, 23 Jun 2021 17:09:17 -0400 Subject: [PATCH] Fixes #1310 (#1325) * 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 --- changelog.md | 2 ++ game/unitdelivery.py | 34 +++++++++++++++++++--------- qt_ui/windows/basemenu/QBaseMenu2.py | 12 ++-------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/changelog.md b/changelog.md index b0dc6293..0fc7d44e 100644 --- a/changelog.md +++ b/changelog.md @@ -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. diff --git a/game/unitdelivery.py b/game/unitdelivery.py index 4de3addf..a6de6a71 100644 --- a/game/unitdelivery.py +++ b/game/unitdelivery.py @@ -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)) diff --git a/qt_ui/windows/basemenu/QBaseMenu2.py b/qt_ui/windows/basemenu/QBaseMenu2.py index 4b8265c8..8a913280 100644 --- a/qt_ui/windows/basemenu/QBaseMenu2.py +++ b/qt_ui/windows/basemenu/QBaseMenu2.py @@ -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()