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.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

View File

@ -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

View File

@ -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

View File

@ -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: <b>${}M</b>"
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("<b>" + db.unit_type_name_2(unit_type) + "</b>")
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("<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(
@ -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
self.recruitables_types = recruitables_types

View File

@ -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:

View File

@ -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)
self.setLayout(main_layout)