replan opfor mission on sell or buy of tgos

This commit is contained in:
RndName 2021-06-24 19:06:32 +02:00 committed by Dan Albert
parent 8b70d2674f
commit 7229b886e0
5 changed files with 77 additions and 45 deletions

View File

@ -28,6 +28,7 @@ Saves from 4.0.0 are compatible with 4.1.0.
* **[Economy]** EWRs can now be bought and sold for the correct price and can no longer be used to generate money
* **[Flight Planning]** Fixed potential issue with angles > 360° or < 0° being generated when summing two angles.
* **[Mission Generation]** The lua data for other plugins is now generated correctly
* **[Mission Generation]** Fixed problem with opfor planning missions against sold ground objects like SAMs
* **[Mission Generation]** The legacy always-available tanker option no longer prevents mission creation.
* **[Mission Generation]** Fix occasional KeyError preventing mission generation when all units of the same type in a convoy were killed.
* **[UI]** Statistics window tick marks are now always integers.

View File

@ -386,26 +386,49 @@ class Game:
self.blue_bullseye = Bullseye(enemy_cp.position)
self.red_bullseye = Bullseye(player_cp.position)
def initialize_turn(self) -> None:
def initialize_turn(self, for_red: bool = True, for_blue: bool = True):
self.events = []
self._generate_events()
self.set_bullseye()
# Update statistics
self.game_stats.update(self)
self.blue_air_wing.reset()
self.red_air_wing.reset()
self.aircraft_inventory.reset()
for cp in self.theater.controlpoints:
self.aircraft_inventory.set_from_control_point(cp)
# Check for win or loss condition
turn_state = self.check_win_loss()
if turn_state in (TurnState.LOSS, TurnState.WIN):
return self.process_win_loss(turn_state)
# Plan Coalition specific turn
if for_red:
self.initialize_turn_for(player=False)
if for_blue:
self.initialize_turn_for(player=True)
# Plan GroundWar
for cp in self.theater.controlpoints:
if cp.has_frontline:
gplanner = GroundPlanner(cp, self)
gplanner.plan_groundwar()
self.ground_planners[cp.id] = gplanner
def initialize_turn_for(self, player: bool) -> None:
self.ato_for(player).clear()
self.air_wing_for(player).reset()
self.aircraft_inventory.reset()
for cp in self.theater.controlpoints:
self.aircraft_inventory.set_from_control_point(cp)
# Refund all pending deliveries for opfor and if player
# has automate_aircraft_reinforcements
if (not player and not cp.captured) or (
player
and cp.captured
and self.settings.automate_aircraft_reinforcements
):
cp.pending_unit_deliveries.refund_all(self)
# Plan flights & combat for next turn
with logged_duration("Computing conflict positions"):
self.compute_conflicts_position()
@ -415,38 +438,31 @@ class Game:
self.compute_transit_networks()
self.ground_planners = {}
self.blue_procurement_requests.clear()
self.red_procurement_requests.clear()
self.procurement_requests_for(player).clear()
with logged_duration("Procurement of airlift assets"):
self.transfers.order_airlift_assets()
with logged_duration("Transport planning"):
self.transfers.plan_transports()
with logged_duration("Blue mission planning"):
if self.settings.auto_ato_behavior is not AutoAtoBehavior.Disabled:
blue_planner = CoalitionMissionPlanner(self, is_player=True)
blue_planner.plan_missions()
if not player or (
player and self.settings.auto_ato_behavior is not AutoAtoBehavior.Disabled
):
color = "Blue" if player else "Red"
with logged_duration(f"{color} mission planning"):
mission_planner = CoalitionMissionPlanner(self, player)
mission_planner.plan_missions()
with logged_duration("Red mission planning"):
red_planner = CoalitionMissionPlanner(self, is_player=False)
red_planner.plan_missions()
self.plan_procurement_for(player)
for cp in self.theater.controlpoints:
if cp.has_frontline:
gplanner = GroundPlanner(cp, self)
gplanner.plan_groundwar()
self.ground_planners[cp.id] = gplanner
self.plan_procurement()
def plan_procurement(self) -> None:
def plan_procurement_for(self, for_player: bool) -> None:
# The first turn needs to buy a *lot* of aircraft to fill CAPs, so it
# gets much more of the budget that turn. Otherwise budget (after
# repairs) is split evenly between air and ground. For the default
# starting budget of 2000 this gives 600 to ground forces and 1400 to
# aircraft. After that the budget will be spend proportionally based on how much is already invested
if for_player:
self.budget = ProcurementAi(
self,
for_player=True,
@ -455,7 +471,7 @@ class Game:
manage_front_line=self.settings.automate_front_line_reinforcements,
manage_aircraft=self.settings.automate_aircraft_reinforcements,
).spend_budget(self.budget)
else:
self.enemy_budget = ProcurementAi(
self,
for_player=False,

View File

@ -124,7 +124,6 @@ class QBaseMenu2(QDialog):
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()
self.game_model.game.initialize_turn()
GameUpdateSignal.get_instance().updateGame(self.game_model.game)

View File

@ -56,6 +56,5 @@ class QGroundForcesStrategy(QGroupBox):
self.cp.base.affect_strength(amount)
enemy_point.base.affect_strength(-amount)
# Clear the ATO to replan missions affected by the front line.
self.game.reset_ato()
self.game.initialize_turn()
GameUpdateSignal.get_instance().updateGame(self.game)

View File

@ -259,6 +259,14 @@ class QGroundObjectMenu(QDialog):
self.update_total_value()
self.game.budget = self.game.budget + self.total_value
self.ground_object.groups = []
# Replan if the tgo was a target of the redfor
if any(
package.target == self.ground_object
for package in self.game.ato_for(player=False).packages
):
self.game.initialize_turn(for_red=True, for_blue=False)
self.do_refresh_layout()
GameUpdateSignal.get_instance().updateGame(self.game)
@ -439,6 +447,9 @@ class QBuyGroupForGroundObjectDialog(QDialog):
)
self.ground_object.groups = [group]
# Replan redfor missions
self.game.initialize_turn(for_red=True, for_blue=False)
GameUpdateSignal.get_instance().updateGame(self.game)
def buySam(self):
@ -452,6 +463,9 @@ class QBuyGroupForGroundObjectDialog(QDialog):
self.ground_object.groups = list(sam_generator.groups)
# Replan redfor missions
self.game.initialize_turn(for_red=True, for_blue=False)
GameUpdateSignal.get_instance().updateGame(self.game)
def buy_ewr(self):
@ -465,6 +479,9 @@ class QBuyGroupForGroundObjectDialog(QDialog):
self.ground_object.groups = [ewr_generator.vg]
# Replan redfor missions
self.game.initialize_turn(for_red=True, for_blue=False)
GameUpdateSignal.get_instance().updateGame(self.game)
def error_money(self):