Perform aircraft transfers at the end of the turn.

This commit is contained in:
Dan Albert 2020-11-22 18:42:33 -08:00
parent 7438c30885
commit 493e53c28f
2 changed files with 61 additions and 6 deletions

View File

@ -61,6 +61,13 @@ class AirLosses:
losses_by_type[loss.flight.unit_type] += loss.flight.count losses_by_type[loss.flight.unit_type] += loss.flight.count
return losses_by_type return losses_by_type
def surviving_flight_members(self, flight: Flight) -> int:
losses = 0
for loss in self.losses:
if loss.flight == flight:
losses += 1
return flight.count - losses
@dataclass(frozen=True) @dataclass(frozen=True)
class StateData: class StateData:

View File

@ -9,9 +9,10 @@ from dcs.task import Task
from dcs.unittype import UnitType from dcs.unittype import UnitType
from game import db, persistency from game import db, persistency
from game.debriefing import Debriefing from game.debriefing import AirLosses, Debriefing
from game.infos.information import Information from game.infos.information import Information
from game.theater import ControlPoint from game.theater import ControlPoint
from gen import AirTaskingOrder
from gen.ground_forces.combat_stance import CombatStance from gen.ground_forces.combat_stance import CombatStance
from ..unitmap import UnitMap from ..unitmap import UnitMap
@ -99,6 +100,52 @@ class Event:
persistency.mission_path_for("liberation_nextturn.miz")) persistency.mission_path_for("liberation_nextturn.miz"))
return unit_map return unit_map
@staticmethod
def _transfer_aircraft(ato: AirTaskingOrder, losses: AirLosses,
for_player: bool) -> None:
for package in ato.packages:
for flight in package.flights:
# No need to transfer to the same location.
if flight.departure == flight.arrival:
continue
# Don't transfer to bases that were captured. Note that if the
# airfield was back-filling transfers it may overflow. We could
# attempt to be smarter in the future by performing transfers in
# order up a graph to prevent transfers to full airports and
# send overflow off-map, but overflow is fine for now.
if flight.arrival.captured != for_player:
logging.info(
f"Not transferring {flight} because {flight.arrival} "
"was captured")
continue
transfer_count = losses.surviving_flight_members(flight)
if transfer_count < 0:
logging.error(f"{flight} had {flight.count} aircraft but "
f"{transfer_count} losses were recorded.")
continue
aircraft = flight.unit_type
available = flight.departure.base.total_units_of_type(aircraft)
if available < transfer_count:
logging.error(
f"Found killed {aircraft} from {flight.departure} but "
f"that airbase has only {available} available.")
continue
flight.departure.base.aircraft[aircraft] -= transfer_count
if aircraft not in flight.arrival.base.aircraft:
# TODO: Should use defaultdict.
flight.arrival.base.aircraft[aircraft] = 0
flight.arrival.base.aircraft[aircraft] += transfer_count
def complete_aircraft_transfers(self, debriefing: Debriefing) -> None:
self._transfer_aircraft(self.game.blue_ato, debriefing.air_losses,
for_player=True)
self._transfer_aircraft(self.game.red_ato, debriefing.air_losses,
for_player=False)
def commit(self, debriefing: Debriefing): def commit(self, debriefing: Debriefing):
logging.info("Commiting mission results") logging.info("Commiting mission results")
@ -132,8 +179,9 @@ class Event:
if unit_type in cp.base.armor.keys(): if unit_type in cp.base.armor.keys():
logging.info(f"Ground unit destroyed: {unit_type}") logging.info(f"Ground unit destroyed: {unit_type}")
cp.base.armor[unit_type] = max(0, cp.base.armor[unit_type] - 1) cp.base.armor[unit_type] = max(0, cp.base.armor[unit_type] - 1)
except Exception as e: except Exception:
print(e) logging.exception(
f"Could not commit lost ground unit {killed_ground_unit}")
# ------------------------------ # ------------------------------
# Static ground objects # Static ground objects
@ -217,10 +265,10 @@ class Event:
for cp in captured_cps: for cp in captured_cps:
logging.info("Will run redeploy for " + cp.name) logging.info("Will run redeploy for " + cp.name)
self.redeploy_units(cp) self.redeploy_units(cp)
except Exception:
logging.exception(f"Could not process base capture {captured}")
self.complete_aircraft_transfers(debriefing)
except Exception as e:
print(e)
# Destroyed units carcass # Destroyed units carcass
# ------------------------- # -------------------------