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.
This commit is contained in:
Dan Albert 2020-11-20 18:04:27 -08:00
parent 20091292f4
commit f8b2dbe283
6 changed files with 31 additions and 46 deletions

View File

@ -11,12 +11,12 @@ from dcs.unittype import UnitType
from game import db, persistency from game import db, persistency
from game.debriefing import Debriefing from game.debriefing import Debriefing
from game.infos.information import Information from game.infos.information import Information
from game.operation.operation import Operation
from game.theater import ControlPoint from game.theater import ControlPoint
from gen.ground_forces.combat_stance import CombatStance from gen.ground_forces.combat_stance import CombatStance
if TYPE_CHECKING: if TYPE_CHECKING:
from ..game import Game from ..game import Game
from game.operation.operation import Operation
DIFFICULTY_LOG_BASE = 1.1 DIFFICULTY_LOG_BASE = 1.1
EVENT_DEPARTURE_MAX_DISTANCE = 340000 EVENT_DEPARTURE_MAX_DISTANCE = 340000

View File

@ -160,9 +160,6 @@ class Game:
def _budget_player(self): def _budget_player(self):
self.budget += self.budget_reward_amount 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: def units_delivery_event(self, to_cp: ControlPoint) -> UnitsDeliveryEvent:
event = UnitsDeliveryEvent(attacker_name=self.player_name, event = UnitsDeliveryEvent(attacker_name=self.player_name,
defender_name=self.player_name, defender_name=self.player_name,
@ -172,10 +169,6 @@ class Game:
self.events.append(event) self.events.append(event)
return 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): def initiate_event(self, event: Event):
#assert event in self.events #assert event in self.events
logging.info("Generating {} (regular)".format(event)) logging.info("Generating {} (regular)".format(event))
@ -242,6 +235,7 @@ class Game:
self.aircraft_inventory.reset() self.aircraft_inventory.reset()
for cp in self.theater.controlpoints: for cp in self.theater.controlpoints:
cp.pending_unit_deliveries = self.units_delivery_event(cp)
self.aircraft_inventory.set_from_control_point(cp) self.aircraft_inventory.set_from_control_point(cp)
# Plan flights & combat for next turn # Plan flights & combat for next turn

View File

@ -33,6 +33,7 @@ from .theatergroundobject import (
if TYPE_CHECKING: if TYPE_CHECKING:
from game import Game from game import Game
from gen.flights.flight import FlightType from gen.flights.flight import FlightType
from ..event import UnitsDeliveryEvent
class ControlPointType(Enum): class ControlPointType(Enum):
@ -158,6 +159,7 @@ class ControlPoint(MissionTarget):
self.cptype = cptype self.cptype = cptype
self.stances: Dict[int, CombatStance] = {} self.stances: Dict[int, CombatStance] = {}
self.airport = None self.airport = None
self.pending_unit_deliveries: Optional[UnitsDeliveryEvent] = None
@property @property
def ground_objects(self) -> List[TheaterGroundObject]: def ground_objects(self) -> List[TheaterGroundObject]:
@ -387,3 +389,7 @@ class OffMapSpawn(ControlPoint):
def mission_types(self, for_player: bool) -> Iterator[FlightType]: def mission_types(self, for_player: bool) -> Iterator[FlightType]:
yield from [] yield from []
@property
def available_aircraft_slots(self) -> int:
return 1000

View File

@ -11,12 +11,14 @@ from PySide2.QtWidgets import (
from dcs.unittype import UnitType from dcs.unittype import UnitType
from game import db from game import db
from game.event import UnitsDeliveryEvent
from game.theater import ControlPoint
from qt_ui.models import GameModel
class QRecruitBehaviour: class QRecruitBehaviour:
game = None game_model: GameModel
cp = None cp: ControlPoint
deliveryEvent = None
existing_units_labels = None existing_units_labels = None
bought_amount_labels = None bought_amount_labels = None
maximum_units = -1 maximum_units = -1
@ -24,12 +26,16 @@ class QRecruitBehaviour:
BUDGET_FORMAT = "Available Budget: <b>${}M</b>" BUDGET_FORMAT = "Available Budget: <b>${}M</b>"
def __init__(self) -> None: def __init__(self) -> None:
self.deliveryEvent = None
self.bought_amount_labels = {} self.bought_amount_labels = {}
self.existing_units_labels = {} self.existing_units_labels = {}
self.recruitable_types = [] self.recruitable_types = []
self.update_available_budget() self.update_available_budget()
@property
def pending_deliveries(self) -> UnitsDeliveryEvent:
assert self.cp.pending_unit_deliveries
return self.cp.pending_unit_deliveries
@property @property
def budget(self) -> int: def budget(self) -> int:
return self.game_model.game.budget return self.game_model.game.budget
@ -47,7 +53,7 @@ class QRecruitBehaviour:
exist.setLayout(existLayout) exist.setLayout(existLayout)
existing_units = self.cp.base.total_units_of_type(unit_type) 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("<b>" + db.unit_type_name_2(unit_type) + "</b>") unitName = QLabel("<b>" + db.unit_type_name_2(unit_type) + "</b>")
unitName.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) unitName.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
@ -103,7 +109,7 @@ class QRecruitBehaviour:
def _update_count_label(self, unit_type: UnitType): def _update_count_label(self, unit_type: UnitType):
self.bought_amount_labels[unit_type].setText("<b>{}</b>".format( self.bought_amount_labels[unit_type].setText("<b>{}</b>".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("<b>{}</b>".format( self.existing_units_labels[unit_type].setText("<b>{}</b>".format(
@ -129,7 +135,7 @@ class QRecruitBehaviour:
price = db.PRICES[unit_type] price = db.PRICES[unit_type]
if self.budget >= price: if self.budget >= price:
self.deliveryEvent.deliver({unit_type: 1}) self.pending_deliveries.deliver({unit_type: 1})
self.budget -= price self.budget -= price
else: else:
# TODO : display modal warning # TODO : display modal warning
@ -138,12 +144,12 @@ class QRecruitBehaviour:
self.update_available_budget() self.update_available_budget()
def sell(self, unit_type): 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] price = db.PRICES[unit_type]
self.budget += price self.budget += price
self.deliveryEvent.units[unit_type] = self.deliveryEvent.units[unit_type] - 1 self.pending_deliveries.units[unit_type] = self.pending_deliveries.units[unit_type] - 1
if self.deliveryEvent.units[unit_type] == 0: if self.pending_deliveries.units[unit_type] == 0:
del self.deliveryEvent.units[unit_type] del self.pending_deliveries.units[unit_type]
elif self.cp.base.total_units_of_type(unit_type) > 0: elif self.cp.base.total_units_of_type(unit_type) > 0:
price = db.PRICES[unit_type] price = db.PRICES[unit_type]
self.budget += price self.budget += price
@ -154,20 +160,14 @@ class QRecruitBehaviour:
@property @property
def total_units(self): def total_units(self):
total = 0 total = 0
for unit_type in self.recruitables_types: for unit_type in self.recruitables_types:
total += self.cp.base.total_units(unit_type) total += self.cp.base.total_units(unit_type)
print(unit_type, total, self.cp.base.total_units(unit_type))
print("--------------------------------")
if self.deliveryEvent: if self.pending_deliveries:
for unit_bought in self.deliveryEvent.units: for unit_bought in self.pending_deliveries.units:
if db.unit_task(unit_bought) in self.recruitables_types: if db.unit_task(unit_bought) in self.recruitables_types:
total += self.deliveryEvent.units[unit_bought] total += self.pending_deliveries.units[unit_bought]
print(unit_bought, total, self.deliveryEvent.units[unit_bought])
print("=============================")
return total return total
@ -181,4 +181,4 @@ class QRecruitBehaviour:
""" """
Set the maximum number of units that can be bought Set the maximum number of units that can be bought
""" """
self.recruitables_types = recruitables_types self.recruitables_types = recruitables_types

View File

@ -15,7 +15,6 @@ from dcs.task import CAP, CAS
from dcs.unittype import UnitType from dcs.unittype import UnitType
from game import db from game import db
from game.event.event import UnitsDeliveryEvent
from game.theater import ControlPoint from game.theater import ControlPoint
from qt_ui.models import GameModel from qt_ui.models import GameModel
from qt_ui.uiconstants import ICONS from qt_ui.uiconstants import ICONS
@ -27,17 +26,10 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour):
QFrame.__init__(self) QFrame.__init__(self)
self.cp = cp self.cp = cp
self.game_model = game_model self.game_model = game_model
self.deliveryEvent: Optional[UnitsDeliveryEvent] = None
self.bought_amount_labels = {} self.bought_amount_labels = {}
self.existing_units_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 # Determine maximum number of aircrafts that can be bought
self.set_maximum_units(self.cp.available_aircraft_slots) self.set_maximum_units(self.cp.available_aircraft_slots)
self.set_recruitable_types([CAP, CAS]) self.set_recruitable_types([CAP, CAS])
@ -94,7 +86,7 @@ class QAircraftRecruitmentMenu(QFrame, QRecruitBehaviour):
def sell(self, unit_type: UnitType): def sell(self, unit_type: UnitType):
# Don't need to remove aircraft from the inventory if we're canceling # Don't need to remove aircraft from the inventory if we're canceling
# orders. # 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 global_inventory = self.game_model.game.aircraft_inventory
inventory = global_inventory.for_control_point(self.cp) inventory = global_inventory.for_control_point(self.cp)
try: try:

View File

@ -9,7 +9,6 @@ from PySide2.QtWidgets import (
from dcs.task import PinpointStrike from dcs.task import PinpointStrike
from game import db from game import db
from game.event import UnitsDeliveryEvent
from game.theater import ControlPoint from game.theater import ControlPoint
from qt_ui.models import GameModel from qt_ui.models import GameModel
from qt_ui.windows.basemenu.QRecruitBehaviour import QRecruitBehaviour from qt_ui.windows.basemenu.QRecruitBehaviour import QRecruitBehaviour
@ -25,12 +24,6 @@ class QArmorRecruitmentMenu(QFrame, QRecruitBehaviour):
self.bought_amount_labels = {} self.bought_amount_labels = {}
self.existing_units_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() self.init_ui()
def init_ui(self): def init_ui(self):
@ -63,4 +56,4 @@ class QArmorRecruitmentMenu(QFrame, QRecruitBehaviour):
scroll.setWidgetResizable(True) scroll.setWidgetResizable(True)
scroll.setWidget(scroll_content) scroll.setWidget(scroll_content)
main_layout.addWidget(scroll) main_layout.addWidget(scroll)
self.setLayout(main_layout) self.setLayout(main_layout)