Transfer pending purchases forward along capture.

Fixes https://github.com/Khopa/dcs_liberation/issues/828.

(cherry picked from commit d8c94f5ecee6b136706d40f00c13f752dccac6e1)
This commit is contained in:
Dan Albert 2021-02-12 13:43:30 -08:00
parent 3fab1d92b7
commit 0ae6575087
4 changed files with 56 additions and 27 deletions

View File

@ -6,6 +6,7 @@
* **[Culling]** Missile sites generate reasonably sized non-cull zones rather than 100km ones. * **[Culling]** Missile sites generate reasonably sized non-cull zones rather than 100km ones.
* **[UI]** Budget display is also now rounded to 2 decimal places. * **[UI]** Budget display is also now rounded to 2 decimal places.
* **[UI]** Fixed some areas where the old, non-pretty name was displayed to users. * **[UI]** Fixed some areas where the old, non-pretty name was displayed to users.
* **[Economy]** Pending ground unit purchases will also be transferred when a connected base is captured.
# 2.4.0 # 2.4.0

View File

@ -6,7 +6,7 @@ from typing import Dict, Iterator, List, TYPE_CHECKING, Tuple, Type
from dcs.mapping import Point from dcs.mapping import Point
from dcs.task import Task from dcs.task import Task
from dcs.unittype import UnitType from dcs.unittype import UnitType, VehicleType
from game import persistency from game import persistency
from game.debriefing import AirLosses, Debriefing from game.debriefing import AirLosses, Debriefing
@ -296,45 +296,69 @@ class Event:
self.game.turn) self.game.turn)
self.game.informations.append(info) self.game.informations.append(info)
def redeploy_units(self, cp): def redeploy_units(self, cp: ControlPoint) -> None:
"""" """"
Auto redeploy units to newly captured base Auto redeploy units to newly captured base
""" """
ally_connected_cps = [ocp for ocp in cp.connected_points if cp.captured == ocp.captured] ally_connected_cps = [ocp for ocp in cp.connected_points if
enemy_connected_cps = [ocp for ocp in cp.connected_points if cp.captured != ocp.captured] cp.captured == ocp.captured]
enemy_connected_cps = [ocp for ocp in cp.connected_points if
cp.captured != ocp.captured]
# If the newly captured cp does not have enemy connected cp, # If the newly captured cp does not have enemy connected cp,
# then it is not necessary to redeploy frontline units there. # then it is not necessary to redeploy frontline units there.
if len(enemy_connected_cps) == 0: if len(enemy_connected_cps) == 0:
return return
else:
# From each ally cp, send reinforcements # From each ally cp, send reinforcements
for ally_cp in ally_connected_cps: for ally_cp in ally_connected_cps:
total_units_redeployed = 0 self.redeploy_between(cp, ally_cp)
own_enemy_cp = [ocp for ocp in ally_cp.connected_points if ally_cp.captured != ocp.captured]
def redeploy_between(self, destination: ControlPoint,
source: ControlPoint) -> None:
total_units_redeployed = 0
moved_units = {} moved_units = {}
# If the connected base, does not have any more enemy cp connected. if source.has_active_frontline or not destination.captured:
# Or if it is not the opponent redeploying forces there (enemy AI will never redeploy all their forces at once) # If there are still active front lines to defend at the
if len(own_enemy_cp) > 0 or not cp.captured: # transferring CP we should not transfer all units.
for frontline_unit, count in ally_cp.base.armor.items(): #
moved_units[frontline_unit] = int(count/2) # Opfor also does not transfer all of their units.
total_units_redeployed = total_units_redeployed + int(count/2) # TODO: Balance the CPs rather than moving half from everywhere.
else: # So if the old base, does not have any more enemy cp connected, or if it is an enemy base move_factor = 0.5
for frontline_unit, count in ally_cp.base.armor.items(): else:
moved_units[frontline_unit] = count # Otherwise we can move everything.
total_units_redeployed = total_units_redeployed + count move_factor = 1
cp.base.commision_units(moved_units) for frontline_unit, count in source.base.armor.items():
ally_cp.base.commit_losses(moved_units) moved_units[frontline_unit] = int(count * move_factor)
total_units_redeployed = total_units_redeployed + int(
count * move_factor)
destination.base.commision_units(moved_units)
source.base.commit_losses(moved_units)
# Also transfer pending deliveries.
for unit_type, count in source.pending_unit_deliveries.units.items():
if not issubclass(unit_type, VehicleType):
continue
if count <= 0:
# Don't transfer *sales*...
continue
move_count = int(count * move_factor)
source.pending_unit_deliveries.sell({unit_type: move_count})
destination.pending_unit_deliveries.order({unit_type: move_count})
total_units_redeployed += move_count
if total_units_redeployed > 0: if total_units_redeployed > 0:
info = Information("Units redeployed", "", self.game.turn) text = (
info.text = str(total_units_redeployed) + " units have been redeployed from " + ally_cp.name + " to " + cp.name f"{total_units_redeployed} units have been redeployed from "
f"{source.name} to {destination.name}"
)
info = Information("Units redeployed", text, self.game.turn)
self.game.informations.append(info) self.game.informations.append(info)
logging.info(info.text) logging.info(text)
class UnitsDeliveryEvent: class UnitsDeliveryEvent:

View File

@ -606,6 +606,10 @@ class ControlPoint(MissionTarget, ABC):
def income_per_turn(self) -> int: def income_per_turn(self) -> int:
return 0 return 0
@property
def has_active_frontline(self) -> bool:
return any(
not c.is_friendly(self.captured) for c in self.connected_points)
class Airfield(ControlPoint): class Airfield(ControlPoint):