From 366ac4ee14198f03038b5724091ee5e6fe5005e5 Mon Sep 17 00:00:00 2001 From: Simon Clark Date: Mon, 4 Jan 2021 19:27:29 +0000 Subject: [PATCH 1/5] Adds a buffer for sold aircraft/vehicles. This feature allows you to cancel the sales of aircraft or ground vehicles if needed. Upon clicking the minus button, a count of sold units will be appended to the unit count. This count responds to both further presses of the minus button, and also to presses of the plus button. No further units will be requested for the next turn until all sold units have been re-bought. I've tested a bunch of different scenarios with this: - Selling and rebuying a unit - the budget increases and decreases as expected. - Selling one unit, buying a unit worth the new player budget, and then trying to rebuy the old unit - the old unit cannot be rebought until the budget has been freed up for it. - Closing the base window and re-opening it - the sold unit count is retained. - Ending the turn - the sold unit count is reset back to 0 as expected. Contributes to Khopa/dcs_liberation#365 --- game/inventory.py | 1 + game/theater/base.py | 1 + gen/ground_forces/ai_ground_planner.py | 1 + qt_ui/windows/basemenu/QRecruitBehaviour.py | 35 +++++++++++++++---- .../airfield/QAircraftRecruitmentMenu.py | 8 ++++- 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/game/inventory.py b/game/inventory.py index b369ad8b..ff09618b 100644 --- a/game/inventory.py +++ b/game/inventory.py @@ -98,6 +98,7 @@ class GlobalAircraftInventory: inventory = self.inventories[control_point] for aircraft, count in control_point.base.aircraft.items(): inventory.add_aircraft(aircraft, count) + control_point.base.sold_units[aircraft] = 0 def for_control_point( self, diff --git a/game/theater/base.py b/game/theater/base.py index 88ede52f..5b89248e 100644 --- a/game/theater/base.py +++ b/game/theater/base.py @@ -29,6 +29,7 @@ class Base: self.aa: Dict[AirDefence, int] = {} self.commision_points: Dict[Type, float] = {} self.strength = 1 + self.sold_units = {} @property def total_aircraft(self) -> int: diff --git a/gen/ground_forces/ai_ground_planner.py b/gen/ground_forces/ai_ground_planner.py index e98d82d2..9215a5b0 100644 --- a/gen/ground_forces/ai_ground_planner.py +++ b/gen/ground_forces/ai_ground_planner.py @@ -117,6 +117,7 @@ class GroundPlanner: print(key) continue + self.cp.base.sold_units[key] = 0 available = self.cp.base.armor[key] while available > 0: diff --git a/qt_ui/windows/basemenu/QRecruitBehaviour.py b/qt_ui/windows/basemenu/QRecruitBehaviour.py index 0cccd16d..ab3f3f21 100644 --- a/qt_ui/windows/basemenu/QRecruitBehaviour.py +++ b/qt_ui/windows/basemenu/QRecruitBehaviour.py @@ -61,7 +61,13 @@ class QRecruitBehaviour: unitName = QLabel("" + db.unit_type_name_2(unit_type) + "") unitName.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) - existing_units = QLabel(str(existing_units)) + sold_count = self.cp.base.sold_units.get(unit_type) + if sold_count is None: + sold_count = 0 + if sold_count > 0: + existing_units = QLabel("{} (-{})".format(existing_units, sold_count)) + else: + existing_units = QLabel(str(existing_units)) existing_units.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) amount_bought = QLabel("{}".format(str(scheduled_units))) @@ -117,9 +123,17 @@ class QRecruitBehaviour: unit_type in self.pending_deliveries.units and "{}".format(self.pending_deliveries.units[unit_type]) or "0" )) - self.existing_units_labels[unit_type].setText("{}".format( - self.cp.base.total_units_of_type(unit_type) - )) + sold_count = self.cp.base.sold_units.get(unit_type) + if sold_count is None: + sold_count = 0 + if sold_count > 0: + self.existing_units_labels[unit_type].setText("{} (-{})".format( + self.cp.base.total_units_of_type(unit_type), self.cp.base.sold_units[unit_type] + )) + else: + self.existing_units_labels[unit_type].setText("{}".format( + self.cp.base.total_units_of_type(unit_type) + )) def update_available_budget(self) -> None: GameUpdateSignal.get_instance().updateBudget(self.game_model.game) @@ -127,8 +141,16 @@ class QRecruitBehaviour: def buy(self, unit_type: Type[UnitType]): price = db.PRICES[unit_type] if self.budget >= price: - self.pending_deliveries.order({unit_type: 1}) - self.budget -= price + sold_count = self.cp.base.sold_units.get(unit_type) + if sold_count is None: + sold_count = 0 + if sold_count > 0: + self.cp.base.sold_units[unit_type] -= 1 + self.cp.base.commision_units({unit_type: 1}) + self.budget -= price + else: + self.pending_deliveries.order({unit_type: 1}) + self.budget -= price else: # TODO : display modal warning logging.info("Not enough money !") @@ -146,6 +168,7 @@ class QRecruitBehaviour: price = db.PRICES[unit_type] self.budget += price self.cp.base.commit_losses({unit_type: 1}) + self.cp.base.sold_units[unit_type] += 1 self._update_count_label(unit_type) self.update_available_budget() diff --git a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py index 79ba0d1f..4e92e61c 100644 --- a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py @@ -85,6 +85,8 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): self.setLayout(main_layout) def buy(self, unit_type): + global_inventory = self.game_model.game.aircraft_inventory + inventory = global_inventory.for_control_point(self.cp) if self.maximum_units > 0: if self.cp.unclaimed_parking(self.game_model.game) <= 0: logging.debug(f"No space for additional aircraft at {self.cp}.") @@ -92,7 +94,11 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): self, "No space for additional aircraft", f"There is no parking space left at {self.cp.name} to accommodate another plane.", QMessageBox.Ok) return - + sold_count = self.cp.base.sold_units.get(unit_type) + if sold_count is None: + sold_count = 0 + if sold_count > 0: + inventory.add_aircraft(unit_type, 1) super().buy(unit_type) self.hangar_status.update_label() From ab2046a2c2a3d2de83fb647361680ce308953dfb Mon Sep 17 00:00:00 2001 From: SimonC6R Date: Tue, 5 Jan 2021 00:26:40 +0000 Subject: [PATCH 2/5] Refactor the sell unit changes as requested. It works more simply now, and also doesn't immediately sell the unit. Also adds a matching UI dialog popup for selling too many ground units. --- game/event/event.py | 21 +++++++-- game/inventory.py | 1 - game/theater/base.py | 1 - gen/ground_forces/ai_ground_planner.py | 1 - qt_ui/windows/basemenu/QRecruitBehaviour.py | 44 ++++--------------- .../airfield/QAircraftRecruitmentMenu.py | 26 +++-------- .../ground_forces/QArmorRecruitmentMenu.py | 14 ++++++ 7 files changed, 47 insertions(+), 61 deletions(-) diff --git a/game/event/event.py b/game/event/event.py index c00ab477..a3dc7ae5 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -342,6 +342,8 @@ class UnitsDeliveryEvent: def __init__(self, control_point: ControlPoint) -> None: self.to_cp = control_point self.units: Dict[Type[UnitType], int] = {} + self.bought_units = {} + self.sold_units = {} def __str__(self) -> str: return "Pending delivery to {}".format(self.to_cp) @@ -350,6 +352,10 @@ class UnitsDeliveryEvent: for k, v in units.items(): self.units[k] = self.units.get(k, 0) + v + def sell(self, units: Dict[Type[UnitType], int]) -> None: + for k, v in units.items(): + self.units[k] = self.units.get(k, 0) - v + def consume_each_order(self) -> Iterator[Tuple[Type[UnitType], int]]: while self.units: yield self.units.popitem() @@ -371,7 +377,16 @@ class UnitsDeliveryEvent: coalition = "Ally" if self.to_cp.captured else "Enemy" aircraft = unit_type.id name = self.to_cp.name - game.message( - f"{coalition} reinforcements: {aircraft} x {count} at {name}") - self.to_cp.base.commision_units(self.units) + if count >= 0: + self.bought_units[unit_type] = count + game.message( + f"{coalition} reinforcements: {aircraft} x {count} at {name}") + else: + self.sold_units[unit_type] = 0 - count + game.message( + f"{coalition} sold: {aircraft} x {0 - count} at {name}") + self.to_cp.base.commision_units(self.bought_units) + self.to_cp.base.commit_losses(self.sold_units) self.units = {} + self.bought_units = {} + self.sold_units = {} diff --git a/game/inventory.py b/game/inventory.py index ff09618b..b369ad8b 100644 --- a/game/inventory.py +++ b/game/inventory.py @@ -98,7 +98,6 @@ class GlobalAircraftInventory: inventory = self.inventories[control_point] for aircraft, count in control_point.base.aircraft.items(): inventory.add_aircraft(aircraft, count) - control_point.base.sold_units[aircraft] = 0 def for_control_point( self, diff --git a/game/theater/base.py b/game/theater/base.py index 5b89248e..88ede52f 100644 --- a/game/theater/base.py +++ b/game/theater/base.py @@ -29,7 +29,6 @@ class Base: self.aa: Dict[AirDefence, int] = {} self.commision_points: Dict[Type, float] = {} self.strength = 1 - self.sold_units = {} @property def total_aircraft(self) -> int: diff --git a/gen/ground_forces/ai_ground_planner.py b/gen/ground_forces/ai_ground_planner.py index 9215a5b0..e98d82d2 100644 --- a/gen/ground_forces/ai_ground_planner.py +++ b/gen/ground_forces/ai_ground_planner.py @@ -117,7 +117,6 @@ class GroundPlanner: print(key) continue - self.cp.base.sold_units[key] = 0 available = self.cp.base.armor[key] while available > 0: diff --git a/qt_ui/windows/basemenu/QRecruitBehaviour.py b/qt_ui/windows/basemenu/QRecruitBehaviour.py index ab3f3f21..7e8b06da 100644 --- a/qt_ui/windows/basemenu/QRecruitBehaviour.py +++ b/qt_ui/windows/basemenu/QRecruitBehaviour.py @@ -61,13 +61,7 @@ class QRecruitBehaviour: unitName = QLabel("" + db.unit_type_name_2(unit_type) + "") unitName.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) - sold_count = self.cp.base.sold_units.get(unit_type) - if sold_count is None: - sold_count = 0 - if sold_count > 0: - existing_units = QLabel("{} (-{})".format(existing_units, sold_count)) - else: - existing_units = QLabel(str(existing_units)) + existing_units = QLabel(str(existing_units)) existing_units.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) amount_bought = QLabel("{}".format(str(scheduled_units))) @@ -123,17 +117,9 @@ class QRecruitBehaviour: unit_type in self.pending_deliveries.units and "{}".format(self.pending_deliveries.units[unit_type]) or "0" )) - sold_count = self.cp.base.sold_units.get(unit_type) - if sold_count is None: - sold_count = 0 - if sold_count > 0: - self.existing_units_labels[unit_type].setText("{} (-{})".format( - self.cp.base.total_units_of_type(unit_type), self.cp.base.sold_units[unit_type] - )) - else: - self.existing_units_labels[unit_type].setText("{}".format( - self.cp.base.total_units_of_type(unit_type) - )) + self.existing_units_labels[unit_type].setText("{}".format( + self.cp.base.total_units_of_type(unit_type) + )) def update_available_budget(self) -> None: GameUpdateSignal.get_instance().updateBudget(self.game_model.game) @@ -141,16 +127,8 @@ class QRecruitBehaviour: def buy(self, unit_type: Type[UnitType]): price = db.PRICES[unit_type] if self.budget >= price: - sold_count = self.cp.base.sold_units.get(unit_type) - if sold_count is None: - sold_count = 0 - if sold_count > 0: - self.cp.base.sold_units[unit_type] -= 1 - self.cp.base.commision_units({unit_type: 1}) - self.budget -= price - else: - self.pending_deliveries.order({unit_type: 1}) - self.budget -= price + self.pending_deliveries.order({unit_type: 1}) + self.budget -= price else: # TODO : display modal warning logging.info("Not enough money !") @@ -158,18 +136,12 @@ class QRecruitBehaviour: self.update_available_budget() def sell(self, unit_type): - if self.pending_deliveries.units.get(unit_type, 0) > 0: + if self.pending_deliveries.units.get(unit_type, 0) > 0 or self.cp.base.total_units_of_type(unit_type) > 0: price = db.PRICES[unit_type] self.budget += price - self.pending_deliveries.units[unit_type] = self.pending_deliveries.units[unit_type] - 1 + self.pending_deliveries.sell({unit_type: 1}) if self.pending_deliveries.units[unit_type] == 0: del self.pending_deliveries.units[unit_type] - elif self.cp.base.total_units_of_type(unit_type) > 0: - price = db.PRICES[unit_type] - self.budget += price - self.cp.base.commit_losses({unit_type: 1}) - self.cp.base.sold_units[unit_type] += 1 - self._update_count_label(unit_type) self.update_available_budget() diff --git a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py index 4e92e61c..52005865 100644 --- a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py @@ -85,8 +85,6 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): self.setLayout(main_layout) def buy(self, unit_type): - global_inventory = self.game_model.game.aircraft_inventory - inventory = global_inventory.for_control_point(self.cp) if self.maximum_units > 0: if self.cp.unclaimed_parking(self.game_model.game) <= 0: logging.debug(f"No space for additional aircraft at {self.cp}.") @@ -94,29 +92,19 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): self, "No space for additional aircraft", f"There is no parking space left at {self.cp.name} to accommodate another plane.", QMessageBox.Ok) return - sold_count = self.cp.base.sold_units.get(unit_type) - if sold_count is None: - sold_count = 0 - if sold_count > 0: - inventory.add_aircraft(unit_type, 1) super().buy(unit_type) self.hangar_status.update_label() def sell(self, unit_type: UnitType): # Don't need to remove aircraft from the inventory if we're canceling # orders. - if self.pending_deliveries.units.get(unit_type, 0) <= 0: - global_inventory = self.game_model.game.aircraft_inventory - inventory = global_inventory.for_control_point(self.cp) - try: - inventory.remove_aircraft(unit_type, 1) - except ValueError: - QMessageBox.critical( - self, "Could not sell aircraft", - f"Attempted to sell one {unit_type.id} at {self.cp.name} " - "but none are available. Are all aircraft currently " - "assigned to a mission?", QMessageBox.Ok) - return + if self.pending_deliveries.units.get(unit_type, 0) <= 0 - self.cp.base.total_units_of_type(unit_type): + QMessageBox.critical( + self, "Could not sell aircraft", + f"Attempted to sell one {unit_type.id} at {self.cp.name} " + "but none are available. Are all aircraft currently " + "assigned to a mission?", QMessageBox.Ok) + return super().sell(unit_type) self.hangar_status.update_label() diff --git a/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py b/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py index c359eaaf..c04cf4cc 100644 --- a/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py @@ -5,8 +5,10 @@ from PySide2.QtWidgets import ( QScrollArea, QVBoxLayout, QWidget, + QMessageBox, ) from dcs.task import PinpointStrike +from dcs.unittype import FlyingType, UnitType from game import db from game.theater import ControlPoint @@ -57,3 +59,15 @@ class QArmorRecruitmentMenu(QFrame, QRecruitBehaviour): scroll.setWidget(scroll_content) main_layout.addWidget(scroll) self.setLayout(main_layout) + + def sell(self, unit_type: UnitType): + # Don't need to remove aircraft from the inventory if we're canceling + # orders. + if self.pending_deliveries.units.get(unit_type, 0) <= 0 - self.cp.base.total_units_of_type(unit_type): + QMessageBox.critical( + self, "Could not sell ground unit", + f"Attempted to sell one {unit_type.id} at {self.cp.name} " + "but none are available.", QMessageBox.Ok) + return + super().sell(unit_type) + self.hangar_status.update_label() \ No newline at end of file From d10b4c1e13d48692441960b1cb88fcd0ede68b7c Mon Sep 17 00:00:00 2001 From: SimonC6R Date: Tue, 5 Jan 2021 00:27:26 +0000 Subject: [PATCH 3/5] Re-add whitespace. --- qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py index 52005865..0f497773 100644 --- a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py @@ -92,6 +92,7 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): self, "No space for additional aircraft", f"There is no parking space left at {self.cp.name} to accommodate another plane.", QMessageBox.Ok) return + super().buy(unit_type) self.hangar_status.update_label() From 03a29aeedfbbd4d5b056763b1448400080f2f8b6 Mon Sep 17 00:00:00 2001 From: SimonC6R Date: Tue, 5 Jan 2021 00:31:54 +0000 Subject: [PATCH 4/5] Type annotations. --- game/event/event.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/game/event/event.py b/game/event/event.py index a3dc7ae5..2eb107f4 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -342,8 +342,8 @@ class UnitsDeliveryEvent: def __init__(self, control_point: ControlPoint) -> None: self.to_cp = control_point self.units: Dict[Type[UnitType], int] = {} - self.bought_units = {} - self.sold_units = {} + self.bought_units: Dict[Type[UnitType], int] = {} + self.sold_units: Dict[Type[UnitType], int] = {} def __str__(self) -> str: return "Pending delivery to {}".format(self.to_cp) From 7c3f7d4b8ea065f15fa85961c72e46a9e8204d93 Mon Sep 17 00:00:00 2001 From: Simon Clark Date: Tue, 5 Jan 2021 09:42:05 +0000 Subject: [PATCH 5/5] Addresses review comments. --- game/event/event.py | 25 ++++++++++++------- qt_ui/windows/basemenu/QRecruitBehaviour.py | 2 +- .../airfield/QAircraftRecruitmentMenu.py | 25 +++++++++++++------ .../ground_forces/QArmorRecruitmentMenu.py | 7 ++---- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/game/event/event.py b/game/event/event.py index 2eb107f4..ea7702c9 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -342,8 +342,6 @@ class UnitsDeliveryEvent: def __init__(self, control_point: ControlPoint) -> None: self.to_cp = control_point self.units: Dict[Type[UnitType], int] = {} - self.bought_units: Dict[Type[UnitType], int] = {} - self.sold_units: Dict[Type[UnitType], int] = {} def __str__(self) -> str: return "Pending delivery to {}".format(self.to_cp) @@ -372,21 +370,30 @@ class UnitsDeliveryEvent: f"Refunding {count} {unit_type.id} at {self.to_cp.name}") game.adjust_budget(price * count, player=self.to_cp.captured) + def available_next_turn(self, unit_type: Type[UnitType]) -> int: + pending_units = self.units.get(unit_type) + if pending_units is None: + pending_units = 0 + current_units = self.to_cp.base.total_units_of_type(unit_type) + return pending_units + current_units + def process(self, game: Game) -> None: + bought_units: Dict[Type[UnitType], int] = {} + sold_units: Dict[Type[UnitType], int] = {} for unit_type, count in self.units.items(): coalition = "Ally" if self.to_cp.captured else "Enemy" aircraft = unit_type.id name = self.to_cp.name if count >= 0: - self.bought_units[unit_type] = count + bought_units[unit_type] = count game.message( f"{coalition} reinforcements: {aircraft} x {count} at {name}") else: - self.sold_units[unit_type] = 0 - count + sold_units[unit_type] = -count game.message( - f"{coalition} sold: {aircraft} x {0 - count} at {name}") - self.to_cp.base.commision_units(self.bought_units) - self.to_cp.base.commit_losses(self.sold_units) + f"{coalition} sold: {aircraft} x {-count} at {name}") + self.to_cp.base.commision_units(bought_units) + self.to_cp.base.commit_losses(sold_units) self.units = {} - self.bought_units = {} - self.sold_units = {} + bought_units = {} + sold_units = {} diff --git a/qt_ui/windows/basemenu/QRecruitBehaviour.py b/qt_ui/windows/basemenu/QRecruitBehaviour.py index 7e8b06da..968d2b2a 100644 --- a/qt_ui/windows/basemenu/QRecruitBehaviour.py +++ b/qt_ui/windows/basemenu/QRecruitBehaviour.py @@ -136,7 +136,7 @@ class QRecruitBehaviour: self.update_available_budget() def sell(self, unit_type): - if self.pending_deliveries.units.get(unit_type, 0) > 0 or self.cp.base.total_units_of_type(unit_type) > 0: + if self.pending_deliveries.available_next_turn(unit_type) > 0: price = db.PRICES[unit_type] self.budget += price self.pending_deliveries.sell({unit_type: 1}) diff --git a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py index 0f497773..4fa2530e 100644 --- a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py @@ -92,6 +92,12 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): self, "No space for additional aircraft", f"There is no parking space left at {self.cp.name} to accommodate another plane.", QMessageBox.Ok) return + # If we change our mind about selling, we want the aircraft to be put + # back in the inventory immediately. + elif self.pending_deliveries.units.get(unit_type, 0) < 0: + global_inventory = self.game_model.game.aircraft_inventory + inventory = global_inventory.for_control_point(self.cp) + inventory.add_aircraft(unit_type, 1) super().buy(unit_type) self.hangar_status.update_label() @@ -99,13 +105,18 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): def sell(self, unit_type: UnitType): # Don't need to remove aircraft from the inventory if we're canceling # orders. - if self.pending_deliveries.units.get(unit_type, 0) <= 0 - self.cp.base.total_units_of_type(unit_type): - QMessageBox.critical( - self, "Could not sell aircraft", - f"Attempted to sell one {unit_type.id} at {self.cp.name} " - "but none are available. Are all aircraft currently " - "assigned to a mission?", QMessageBox.Ok) - return + if self.pending_deliveries.units.get(unit_type, 0) <= 0: + global_inventory = self.game_model.game.aircraft_inventory + inventory = global_inventory.for_control_point(self.cp) + try: + inventory.remove_aircraft(unit_type, 1) + except ValueError: + QMessageBox.critical( + self, "Could not sell aircraft", + f"Attempted to sell one {unit_type.id} at {self.cp.name} " + "but none are available. Are all aircraft currently " + "assigned to a mission?", QMessageBox.Ok) + return super().sell(unit_type) self.hangar_status.update_label() diff --git a/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py b/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py index c04cf4cc..14801ba4 100644 --- a/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py @@ -61,13 +61,10 @@ class QArmorRecruitmentMenu(QFrame, QRecruitBehaviour): self.setLayout(main_layout) def sell(self, unit_type: UnitType): - # Don't need to remove aircraft from the inventory if we're canceling - # orders. - if self.pending_deliveries.units.get(unit_type, 0) <= 0 - self.cp.base.total_units_of_type(unit_type): + if self.pending_deliveries.available_next_turn(unit_type) <= 0: QMessageBox.critical( self, "Could not sell ground unit", f"Attempted to sell one {unit_type.id} at {self.cp.name} " "but none are available.", QMessageBox.Ok) return - super().sell(unit_type) - self.hangar_status.update_label() \ No newline at end of file + super().sell(unit_type) \ No newline at end of file