Basic implementation of road based transfers.

This adds the models and UIs for creating ground unit transfer orders.
Most of the feature is still missing:

* The AI doesn't do them.
* Transfers can move across the whole map in one turn.
* Transfers between disconnected bases are allowed.
* Transfers are not modeled in the simulation, so they can't be
  interdicted.

https://github.com/Khopa/dcs_liberation/issues/824
This commit is contained in:
Dan Albert
2021-02-15 12:49:36 -08:00
parent b65d178cf1
commit e9ff554f39
12 changed files with 702 additions and 30 deletions

View File

@@ -1442,11 +1442,11 @@ def unit_task(unit: UnitType) -> Optional[Task]:
return None
def find_unittype(for_task: Task, country_name: str) -> List[Type[UnitType]]:
def find_unittype(for_task: Type[MainTask], country_name: str) -> List[Type[UnitType]]:
return [x for x in UNIT_BY_TASK[for_task] if x in FACTIONS[country_name].units]
MANPADS: List[VehicleType] = [
MANPADS: List[Type[VehicleType]] = [
AirDefence.MANPADS_SA_18_Igla_Grouse,
AirDefence.MANPADS_SA_18_Igla_S_Grouse,
AirDefence.MANPADS_Stinger,

View File

@@ -34,6 +34,7 @@ from .settings import Settings
from .theater import ConflictTheater, ControlPoint, TheaterGroundObject
from game.theater.theatergroundobject import MissileSiteGroundObject
from .threatzones import ThreatZones
from .transfers import PendingTransfers
from .unitmap import UnitMap
from .weather import Conditions, TimeOfDay
@@ -121,6 +122,8 @@ class Game:
self.aircraft_inventory = GlobalAircraftInventory(self.theater.controlpoints)
self._transfers = PendingTransfers()
self.sanitize_sides()
self.on_load()
@@ -151,6 +154,14 @@ class Game:
# Regenerate any state that was not persisted.
self.on_load()
@property
def transfers(self) -> PendingTransfers:
try:
return self._transfers
except AttributeError:
self._transfers = PendingTransfers()
return self._transfers
def generate_conditions(self) -> Conditions:
return Conditions.generate(
self.theater, self.current_day, self.current_turn_time_of_day, self.settings
@@ -264,6 +275,8 @@ class Game:
for control_point in self.theater.controlpoints:
control_point.process_turn(self)
self.transfers.complete_transfers()
self.process_enemy_income()
self.process_player_income()

76
game/transfers.py Normal file
View File

@@ -0,0 +1,76 @@
import logging
from dataclasses import dataclass
from typing import Dict, List, Type
from dcs.unittype import VehicleType
from game.theater import ControlPoint
@dataclass
class TransferOrder:
"""The base type of all transfer orders.
A transfer order can transfer multiple units of multiple types.
"""
#: The location the units are transferring from.
origin: ControlPoint
#: The location the units are transferring to.
destination: ControlPoint
#: True if the transfer order belongs to the player.
player: bool
@dataclass
class RoadTransferOrder(TransferOrder):
"""A transfer order that moves units by road."""
#: The units being transferred.
units: Dict[Type[VehicleType], int]
class PendingTransfers:
def __init__(self) -> None:
self.pending_transfers: List[RoadTransferOrder] = []
@property
def pending_transfer_count(self) -> int:
return len(self.pending_transfers)
def transfer_at_index(self, index: int) -> RoadTransferOrder:
return self.pending_transfers[index]
def new_transfer(self, transfer: RoadTransferOrder) -> None:
transfer.origin.base.commit_losses(transfer.units)
self.pending_transfers.append(transfer)
def cancel_transfer(self, transfer: RoadTransferOrder) -> None:
self.pending_transfers.remove(transfer)
transfer.origin.base.commision_units(transfer.units)
def complete_transfers(self) -> None:
for transfer in self.pending_transfers:
self.complete_transfer(transfer)
self.pending_transfers.clear()
@staticmethod
def complete_transfer(transfer: RoadTransferOrder) -> None:
if transfer.player == transfer.destination.captured:
logging.info(
f"Units transferred from {transfer.origin.name} to "
f"{transfer.destination.name}"
)
transfer.destination.base.commision_units(transfer.units)
elif transfer.player == transfer.origin.captured:
logging.info(
f"{transfer.destination.name} was captured. Transferring units are "
f"returning to {transfer.origin.name}"
)
transfer.origin.base.commision_units(transfer.units)
else:
logging.info(
f"Both {transfer.origin.name} and {transfer.destination.name} were "
"captured. Units were surrounded and captured during transfer."
)