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
# From each ally cp, send reinforcements
for ally_cp in ally_connected_cps:
self.redeploy_between(cp, ally_cp)
def redeploy_between(self, destination: ControlPoint,
source: ControlPoint) -> None:
total_units_redeployed = 0
moved_units = {}
if source.has_active_frontline or not destination.captured:
# If there are still active front lines to defend at the
# transferring CP we should not transfer all units.
#
# Opfor also does not transfer all of their units.
# TODO: Balance the CPs rather than moving half from everywhere.
move_factor = 0.5
else: else:
# From each ally cp, send reinforcements # Otherwise we can move everything.
for ally_cp in ally_connected_cps: move_factor = 1
total_units_redeployed = 0
own_enemy_cp = [ocp for ocp in ally_cp.connected_points if ally_cp.captured != ocp.captured]
moved_units = {} for frontline_unit, count in source.base.armor.items():
moved_units[frontline_unit] = int(count * move_factor)
total_units_redeployed = total_units_redeployed + int(
count * move_factor)
# If the connected base, does not have any more enemy cp connected. destination.base.commision_units(moved_units)
# Or if it is not the opponent redeploying forces there (enemy AI will never redeploy all their forces at once) source.base.commit_losses(moved_units)
if len(own_enemy_cp) > 0 or not cp.captured:
for frontline_unit, count in ally_cp.base.armor.items():
moved_units[frontline_unit] = int(count/2)
total_units_redeployed = total_units_redeployed + int(count/2)
else: # So if the old base, does not have any more enemy cp connected, or if it is an enemy base
for frontline_unit, count in ally_cp.base.armor.items():
moved_units[frontline_unit] = count
total_units_redeployed = total_units_redeployed + count
cp.base.commision_units(moved_units) # Also transfer pending deliveries.
ally_cp.base.commit_losses(moved_units) 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 "
self.game.informations.append(info) f"{source.name} to {destination.name}"
logging.info(info.text) )
info = Information("Units redeployed", text, self.game.turn)
self.game.informations.append(info)
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):

View File

@ -3,7 +3,7 @@
dofile('Scripts/ScriptingSystem.lua') dofile('Scripts/ScriptingSystem.lua')
--Sanitize Mission Scripting environment --Sanitize Mission Scripting environment
--This makes unavailable some unsecure functions. --This makes unavailable some unsecure functions.
--Mission downloaded from server to client may contain potentialy harmful lua code that may use these functions. --Mission downloaded from server to client may contain potentialy harmful lua code that may use these functions.
--You can remove the code below and make availble these functions at your own risk. --You can remove the code below and make availble these functions at your own risk.