mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
replan opfor mission on sell or buy of tgos
This commit is contained in:
parent
8b70d2674f
commit
7229b886e0
@ -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
|
* **[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.
|
* **[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]** 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]** 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.
|
* **[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.
|
* **[UI]** Statistics window tick marks are now always integers.
|
||||||
|
|||||||
70
game/game.py
70
game/game.py
@ -386,26 +386,49 @@ class Game:
|
|||||||
self.blue_bullseye = Bullseye(enemy_cp.position)
|
self.blue_bullseye = Bullseye(enemy_cp.position)
|
||||||
self.red_bullseye = Bullseye(player_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.events = []
|
||||||
self._generate_events()
|
self._generate_events()
|
||||||
|
|
||||||
self.set_bullseye()
|
self.set_bullseye()
|
||||||
|
|
||||||
# Update statistics
|
# Update statistics
|
||||||
self.game_stats.update(self)
|
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
|
# Check for win or loss condition
|
||||||
turn_state = self.check_win_loss()
|
turn_state = self.check_win_loss()
|
||||||
if turn_state in (TurnState.LOSS, TurnState.WIN):
|
if turn_state in (TurnState.LOSS, TurnState.WIN):
|
||||||
return self.process_win_loss(turn_state)
|
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
|
# Plan flights & combat for next turn
|
||||||
with logged_duration("Computing conflict positions"):
|
with logged_duration("Computing conflict positions"):
|
||||||
self.compute_conflicts_position()
|
self.compute_conflicts_position()
|
||||||
@ -415,38 +438,31 @@ class Game:
|
|||||||
self.compute_transit_networks()
|
self.compute_transit_networks()
|
||||||
self.ground_planners = {}
|
self.ground_planners = {}
|
||||||
|
|
||||||
self.blue_procurement_requests.clear()
|
self.procurement_requests_for(player).clear()
|
||||||
self.red_procurement_requests.clear()
|
|
||||||
|
|
||||||
with logged_duration("Procurement of airlift assets"):
|
with logged_duration("Procurement of airlift assets"):
|
||||||
self.transfers.order_airlift_assets()
|
self.transfers.order_airlift_assets()
|
||||||
with logged_duration("Transport planning"):
|
with logged_duration("Transport planning"):
|
||||||
self.transfers.plan_transports()
|
self.transfers.plan_transports()
|
||||||
|
|
||||||
with logged_duration("Blue mission planning"):
|
if not player or (
|
||||||
if self.settings.auto_ato_behavior is not AutoAtoBehavior.Disabled:
|
player and self.settings.auto_ato_behavior is not AutoAtoBehavior.Disabled
|
||||||
blue_planner = CoalitionMissionPlanner(self, is_player=True)
|
):
|
||||||
blue_planner.plan_missions()
|
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"):
|
self.plan_procurement_for(player)
|
||||||
red_planner = CoalitionMissionPlanner(self, is_player=False)
|
|
||||||
red_planner.plan_missions()
|
|
||||||
|
|
||||||
for cp in self.theater.controlpoints:
|
def plan_procurement_for(self, for_player: bool) -> None:
|
||||||
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:
|
|
||||||
# The first turn needs to buy a *lot* of aircraft to fill CAPs, so it
|
# 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
|
# gets much more of the budget that turn. Otherwise budget (after
|
||||||
# repairs) is split evenly between air and ground. For the default
|
# repairs) is split evenly between air and ground. For the default
|
||||||
# starting budget of 2000 this gives 600 to ground forces and 1400 to
|
# 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
|
# aircraft. After that the budget will be spend proportionally based on how much is already invested
|
||||||
|
|
||||||
|
if for_player:
|
||||||
self.budget = ProcurementAi(
|
self.budget = ProcurementAi(
|
||||||
self,
|
self,
|
||||||
for_player=True,
|
for_player=True,
|
||||||
@ -455,7 +471,7 @@ class Game:
|
|||||||
manage_front_line=self.settings.automate_front_line_reinforcements,
|
manage_front_line=self.settings.automate_front_line_reinforcements,
|
||||||
manage_aircraft=self.settings.automate_aircraft_reinforcements,
|
manage_aircraft=self.settings.automate_aircraft_reinforcements,
|
||||||
).spend_budget(self.budget)
|
).spend_budget(self.budget)
|
||||||
|
else:
|
||||||
self.enemy_budget = ProcurementAi(
|
self.enemy_budget = ProcurementAi(
|
||||||
self,
|
self,
|
||||||
for_player=False,
|
for_player=False,
|
||||||
|
|||||||
@ -124,7 +124,6 @@ class QBaseMenu2(QDialog):
|
|||||||
self.cp.capture(self.game_model.game, for_player=not self.cp.captured)
|
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
|
# Reinitialized ground planners and the like. The ATO needs to be reset because
|
||||||
# missions planned against the flipped base are no longer valid.
|
# missions planned against the flipped base are no longer valid.
|
||||||
self.game_model.game.reset_ato()
|
|
||||||
self.game_model.game.initialize_turn()
|
self.game_model.game.initialize_turn()
|
||||||
GameUpdateSignal.get_instance().updateGame(self.game_model.game)
|
GameUpdateSignal.get_instance().updateGame(self.game_model.game)
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,5 @@ class QGroundForcesStrategy(QGroupBox):
|
|||||||
self.cp.base.affect_strength(amount)
|
self.cp.base.affect_strength(amount)
|
||||||
enemy_point.base.affect_strength(-amount)
|
enemy_point.base.affect_strength(-amount)
|
||||||
# Clear the ATO to replan missions affected by the front line.
|
# Clear the ATO to replan missions affected by the front line.
|
||||||
self.game.reset_ato()
|
|
||||||
self.game.initialize_turn()
|
self.game.initialize_turn()
|
||||||
GameUpdateSignal.get_instance().updateGame(self.game)
|
GameUpdateSignal.get_instance().updateGame(self.game)
|
||||||
|
|||||||
@ -259,6 +259,14 @@ class QGroundObjectMenu(QDialog):
|
|||||||
self.update_total_value()
|
self.update_total_value()
|
||||||
self.game.budget = self.game.budget + self.total_value
|
self.game.budget = self.game.budget + self.total_value
|
||||||
self.ground_object.groups = []
|
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()
|
self.do_refresh_layout()
|
||||||
GameUpdateSignal.get_instance().updateGame(self.game)
|
GameUpdateSignal.get_instance().updateGame(self.game)
|
||||||
|
|
||||||
@ -439,6 +447,9 @@ class QBuyGroupForGroundObjectDialog(QDialog):
|
|||||||
)
|
)
|
||||||
self.ground_object.groups = [group]
|
self.ground_object.groups = [group]
|
||||||
|
|
||||||
|
# Replan redfor missions
|
||||||
|
self.game.initialize_turn(for_red=True, for_blue=False)
|
||||||
|
|
||||||
GameUpdateSignal.get_instance().updateGame(self.game)
|
GameUpdateSignal.get_instance().updateGame(self.game)
|
||||||
|
|
||||||
def buySam(self):
|
def buySam(self):
|
||||||
@ -452,6 +463,9 @@ class QBuyGroupForGroundObjectDialog(QDialog):
|
|||||||
|
|
||||||
self.ground_object.groups = list(sam_generator.groups)
|
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)
|
GameUpdateSignal.get_instance().updateGame(self.game)
|
||||||
|
|
||||||
def buy_ewr(self):
|
def buy_ewr(self):
|
||||||
@ -465,6 +479,9 @@ class QBuyGroupForGroundObjectDialog(QDialog):
|
|||||||
|
|
||||||
self.ground_object.groups = [ewr_generator.vg]
|
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)
|
GameUpdateSignal.get_instance().updateGame(self.game)
|
||||||
|
|
||||||
def error_money(self):
|
def error_money(self):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user