From f8b2dbe2833ee03a1559cd65b4608b2c5a513e85 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Fri, 20 Nov 2020 18:04:27 -0800 Subject: [PATCH] Move unit delivery ownership out of the UI. Breaks save compat, but we need to have this knowledge outside the UI so we can know whether or not we can ferry aircraft to the airfield without overflowing parking. --- game/event/event.py | 2 +- game/game.py | 8 +--- game/theater/controlpoint.py | 6 +++ qt_ui/windows/basemenu/QRecruitBehaviour.py | 42 +++++++++---------- .../airfield/QAircraftRecruitmentMenu.py | 10 +---- .../ground_forces/QArmorRecruitmentMenu.py | 9 +--- 6 files changed, 31 insertions(+), 46 deletions(-) diff --git a/game/event/event.py b/game/event/event.py index 44fc37e2..ea5f3b80 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -11,12 +11,12 @@ from dcs.unittype import UnitType from game import db, persistency from game.debriefing import Debriefing from game.infos.information import Information -from game.operation.operation import Operation from game.theater import ControlPoint from gen.ground_forces.combat_stance import CombatStance if TYPE_CHECKING: from ..game import Game + from game.operation.operation import Operation DIFFICULTY_LOG_BASE = 1.1 EVENT_DEPARTURE_MAX_DISTANCE = 340000 diff --git a/game/game.py b/game/game.py index 44c0ef3e..3b29c46c 100644 --- a/game/game.py +++ b/game/game.py @@ -160,9 +160,6 @@ class Game: def _budget_player(self): self.budget += self.budget_reward_amount - def awacs_expense_commit(self): - self.budget -= AWACS_BUDGET_COST - def units_delivery_event(self, to_cp: ControlPoint) -> UnitsDeliveryEvent: event = UnitsDeliveryEvent(attacker_name=self.player_name, defender_name=self.player_name, @@ -172,10 +169,6 @@ class Game: self.events.append(event) return event - def units_delivery_remove(self, event: Event): - if event in self.events: - self.events.remove(event) - def initiate_event(self, event: Event): #assert event in self.events logging.info("Generating {} (regular)".format(event)) @@ -242,6 +235,7 @@ class Game: self.aircraft_inventory.reset() for cp in self.theater.controlpoints: + cp.pending_unit_deliveries = self.units_delivery_event(cp) self.aircraft_inventory.set_from_control_point(cp) # Plan flights & combat for next turn diff --git a/game/theater/controlpoint.py b/game/theater/controlpoint.py index dc2097c1..ca21d463 100644 --- a/game/theater/controlpoint.py +++ b/game/theater/controlpoint.py @@ -33,6 +33,7 @@ from .theatergroundobject import ( if TYPE_CHECKING: from game import Game from gen.flights.flight import FlightType + from ..event import UnitsDeliveryEvent class ControlPointType(Enum): @@ -158,6 +159,7 @@ class ControlPoint(MissionTarget): self.cptype = cptype self.stances: Dict[int, CombatStance] = {} self.airport = None + self.pending_unit_deliveries: Optional[UnitsDeliveryEvent] = None @property def ground_objects(self) -> List[TheaterGroundObject]: @@ -387,3 +389,7 @@ class OffMapSpawn(ControlPoint): def mission_types(self, for_player: bool) -> Iterator[FlightType]: yield from [] + + @property + def available_aircraft_slots(self) -> int: + return 1000 diff --git a/qt_ui/windows/basemenu/QRecruitBehaviour.py b/qt_ui/windows/basemenu/QRecruitBehaviour.py index 5fdd1289..5cb26a81 100644 --- a/qt_ui/windows/basemenu/QRecruitBehaviour.py +++ b/qt_ui/windows/basemenu/QRecruitBehaviour.py @@ -11,12 +11,14 @@ from PySide2.QtWidgets import ( from dcs.unittype import UnitType from game import db +from game.event import UnitsDeliveryEvent +from game.theater import ControlPoint +from qt_ui.models import GameModel class QRecruitBehaviour: - game = None - cp = None - deliveryEvent = None + game_model: GameModel + cp: ControlPoint existing_units_labels = None bought_amount_labels = None maximum_units = -1 @@ -24,12 +26,16 @@ class QRecruitBehaviour: BUDGET_FORMAT = "Available Budget: ${}M" def __init__(self) -> None: - self.deliveryEvent = None self.bought_amount_labels = {} self.existing_units_labels = {} self.recruitable_types = [] self.update_available_budget() + @property + def pending_deliveries(self) -> UnitsDeliveryEvent: + assert self.cp.pending_unit_deliveries + return self.cp.pending_unit_deliveries + @property def budget(self) -> int: return self.game_model.game.budget @@ -47,7 +53,7 @@ class QRecruitBehaviour: exist.setLayout(existLayout) existing_units = self.cp.base.total_units_of_type(unit_type) - scheduled_units = self.deliveryEvent.units.get(unit_type, 0) + scheduled_units = self.pending_deliveries.units.get(unit_type, 0) unitName = QLabel("" + db.unit_type_name_2(unit_type) + "") unitName.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) @@ -103,7 +109,7 @@ class QRecruitBehaviour: def _update_count_label(self, unit_type: UnitType): self.bought_amount_labels[unit_type].setText("{}".format( - unit_type in self.deliveryEvent.units and "{}".format(self.deliveryEvent.units[unit_type]) or "0" + 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( @@ -129,7 +135,7 @@ class QRecruitBehaviour: price = db.PRICES[unit_type] if self.budget >= price: - self.deliveryEvent.deliver({unit_type: 1}) + self.pending_deliveries.deliver({unit_type: 1}) self.budget -= price else: # TODO : display modal warning @@ -138,12 +144,12 @@ class QRecruitBehaviour: self.update_available_budget() def sell(self, unit_type): - if self.deliveryEvent.units.get(unit_type, 0) > 0: + if self.pending_deliveries.units.get(unit_type, 0) > 0: price = db.PRICES[unit_type] self.budget += price - self.deliveryEvent.units[unit_type] = self.deliveryEvent.units[unit_type] - 1 - if self.deliveryEvent.units[unit_type] == 0: - del self.deliveryEvent.units[unit_type] + self.pending_deliveries.units[unit_type] = self.pending_deliveries.units[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 @@ -154,20 +160,14 @@ class QRecruitBehaviour: @property def total_units(self): - total = 0 for unit_type in self.recruitables_types: total += self.cp.base.total_units(unit_type) - print(unit_type, total, self.cp.base.total_units(unit_type)) - print("--------------------------------") - if self.deliveryEvent: - for unit_bought in self.deliveryEvent.units: + if self.pending_deliveries: + for unit_bought in self.pending_deliveries.units: if db.unit_task(unit_bought) in self.recruitables_types: - total += self.deliveryEvent.units[unit_bought] - print(unit_bought, total, self.deliveryEvent.units[unit_bought]) - - print("=============================") + total += self.pending_deliveries.units[unit_bought] return total @@ -181,4 +181,4 @@ class QRecruitBehaviour: """ Set the maximum number of units that can be bought """ - self.recruitables_types = recruitables_types \ No newline at end of file + self.recruitables_types = recruitables_types diff --git a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py index 2dbbd3ca..3e8fef9f 100644 --- a/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/airfield/QAircraftRecruitmentMenu.py @@ -15,7 +15,6 @@ from dcs.task import CAP, CAS from dcs.unittype import UnitType from game import db -from game.event.event import UnitsDeliveryEvent from game.theater import ControlPoint from qt_ui.models import GameModel from qt_ui.uiconstants import ICONS @@ -27,17 +26,10 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour): QFrame.__init__(self) self.cp = cp self.game_model = game_model - self.deliveryEvent: Optional[UnitsDeliveryEvent] = None self.bought_amount_labels = {} self.existing_units_labels = {} - for event in self.game_model.game.events: - if event.__class__ == UnitsDeliveryEvent and event.from_cp == self.cp: - self.deliveryEvent = event - if not self.deliveryEvent: - self.deliveryEvent = self.game_model.game.units_delivery_event(self.cp) - # Determine maximum number of aircrafts that can be bought self.set_maximum_units(self.cp.available_aircraft_slots) self.set_recruitable_types([CAP, CAS]) @@ -94,7 +86,7 @@ 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.deliveryEvent.units.get(unit_type, 0) <= 0: + 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: diff --git a/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py b/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py index d00c6b9d..c359eaaf 100644 --- a/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py +++ b/qt_ui/windows/basemenu/ground_forces/QArmorRecruitmentMenu.py @@ -9,7 +9,6 @@ from PySide2.QtWidgets import ( from dcs.task import PinpointStrike from game import db -from game.event import UnitsDeliveryEvent from game.theater import ControlPoint from qt_ui.models import GameModel from qt_ui.windows.basemenu.QRecruitBehaviour import QRecruitBehaviour @@ -25,12 +24,6 @@ class QArmorRecruitmentMenu(QFrame, QRecruitBehaviour): self.bought_amount_labels = {} self.existing_units_labels = {} - for event in self.game_model.game.events: - if event.__class__ == UnitsDeliveryEvent and event.from_cp == self.cp: - self.deliveryEvent = event - if not self.deliveryEvent: - self.deliveryEvent = self.game_model.game.units_delivery_event(self.cp) - self.init_ui() def init_ui(self): @@ -63,4 +56,4 @@ class QArmorRecruitmentMenu(QFrame, QRecruitBehaviour): scroll.setWidgetResizable(True) scroll.setWidget(scroll_content) main_layout.addWidget(scroll) - self.setLayout(main_layout) \ No newline at end of file + self.setLayout(main_layout)