Refactor Templates to Layouts, Review and Cleanup

- Fix tgogenerator
- Fix UI for ForceGroup and Layouts
- Fix ammo depot handling
- Split bigger files in smaller meaningful files (TGO, layouts, forces)
- Renamed Template to Layout
- Renamed GroundGroup to TheaterGroup and GroundUnit to TheaterUnit
- Reorganize Layouts and UnitGroups to a ArmedForces class and ForceGroup similar to the AirWing and Squadron
- Reworded the UnitClass, GroupRole, GroupTask (adopted to PEP8) and reworked the connection from Role and Task
- added comments
- added missing unit classes
- added temp workaround for missing classes
- add repariable property to TheaterUnit
- Review and Cleanup

Added serialization for loaded templates

Loading the templates from the .miz files takes a lot of computation time and in the future there will be more templates added to the system. Therefore a local pickle serialization for the loaded templates was re-added:
- The pickle will be created the first time the TemplateLoader will be accessed
- Pickle is stored in Liberation SaveDir
- Added UI option to (re-)import templates
This commit is contained in:
RndName
2022-02-10 12:23:16 +01:00
parent 1ae6503ceb
commit 2c17a9a52e
138 changed files with 1985 additions and 3096 deletions

View File

@@ -1,5 +1,7 @@
from dcs.vehicles import AirDefence
from game.theater.theatergroup import TheaterUnit
class AlicCodes:
CODES = {
@@ -37,5 +39,5 @@ class AlicCodes:
}
@classmethod
def code_for(cls, unit_type: str) -> int:
return cls.CODES[unit_type]
def code_for(cls, unit: TheaterUnit) -> int:
return cls.CODES[unit.type.id]

View File

@@ -1,6 +1,12 @@
import inspect
import dcs
REQUIRED_BUILDINGS = [
"ammo",
"factory",
"fob",
]
DEFAULT_AVAILABLE_BUILDINGS = [
"fuel",
"comms",

View File

@@ -104,13 +104,13 @@ MODERN_DOCTRINE = Doctrine(
sweep_distance=nautical_miles(60),
ground_unit_procurement_ratios=GroundUnitProcurementRatios(
{
UnitClass.Tank: 3,
UnitClass.Atgm: 2,
UnitClass.Apc: 2,
UnitClass.Ifv: 3,
UnitClass.Artillery: 1,
UnitClass.TANK: 3,
UnitClass.ATGM: 2,
UnitClass.APC: 2,
UnitClass.IFV: 3,
UnitClass.ARTILLERY: 1,
UnitClass.SHORAD: 2,
UnitClass.Recon: 1,
UnitClass.RECON: 1,
}
),
)
@@ -141,13 +141,13 @@ COLDWAR_DOCTRINE = Doctrine(
sweep_distance=nautical_miles(40),
ground_unit_procurement_ratios=GroundUnitProcurementRatios(
{
UnitClass.Tank: 4,
UnitClass.Atgm: 2,
UnitClass.Apc: 3,
UnitClass.Ifv: 2,
UnitClass.Artillery: 1,
UnitClass.TANK: 4,
UnitClass.ATGM: 2,
UnitClass.APC: 3,
UnitClass.IFV: 2,
UnitClass.ARTILLERY: 1,
UnitClass.SHORAD: 2,
UnitClass.Recon: 1,
UnitClass.RECON: 1,
}
),
)
@@ -178,12 +178,12 @@ WWII_DOCTRINE = Doctrine(
sweep_distance=nautical_miles(10),
ground_unit_procurement_ratios=GroundUnitProcurementRatios(
{
UnitClass.Tank: 3,
UnitClass.Atgm: 3,
UnitClass.Apc: 3,
UnitClass.Artillery: 1,
UnitClass.TANK: 3,
UnitClass.ATGM: 3,
UnitClass.APC: 3,
UnitClass.ARTILLERY: 1,
UnitClass.SHORAD: 3,
UnitClass.Recon: 1,
UnitClass.RECON: 1,
}
),
)

View File

@@ -1,63 +1,69 @@
from __future__ import annotations
from enum import Enum
class GroupRole(Enum):
Unknow = "Unknown"
AntiAir = "AntiAir"
Building = "Building"
Naval = "Naval"
GroundForce = "GroundForce"
Defenses = "Defenses"
Air = "Air"
"""Role of a ForceGroup within the ArmedForces"""
AIR_DEFENSE = "AntiAir"
BUILDING = "Building"
DEFENSES = "Defenses"
GROUND_FORCE = "GroundForce"
NAVAL = "Naval"
@property
def tasks(self) -> list[GroupTask]:
return [task for task in GroupTask if task.role == self]
class GroupTask(Enum):
EWR = "EarlyWarningRadar"
AAA = "AAA"
SHORAD = "SHORAD"
MERAD = "MERAD"
LORAD = "LORAD"
AircraftCarrier = "AircraftCarrier"
HelicopterCarrier = "HelicopterCarrier"
Navy = "Navy"
BaseDefense = "BaseDefense" # Ground
FrontLine = "FrontLine"
Air = "Air"
Missile = "Missile"
Coastal = "Coastal"
Factory = "Factory"
Ammo = "Ammo"
Oil = "Oil"
FOB = "FOB"
StrikeTarget = "StrikeTarget"
Comms = "Comms"
Power = "Power"
"""Specific Tasking of a ForceGroup"""
def __init__(self, description: str, role: GroupRole):
self.description = description
self.role = role
ROLE_TASKINGS: dict[GroupRole, list[GroupTask]] = {
GroupRole.Unknow: [], # No Tasking
GroupRole.AntiAir: [
GroupTask.EWR,
GroupTask.AAA,
GroupTask.SHORAD,
GroupTask.MERAD,
GroupTask.LORAD,
],
GroupRole.GroundForce: [GroupTask.BaseDefense, GroupTask.FrontLine],
GroupRole.Naval: [
GroupTask.AircraftCarrier,
GroupTask.HelicopterCarrier,
GroupTask.Navy,
],
GroupRole.Building: [
GroupTask.Factory,
GroupTask.Ammo,
GroupTask.Oil,
GroupTask.FOB,
GroupTask.StrikeTarget,
GroupTask.Comms,
GroupTask.Power,
],
GroupRole.Defenses: [GroupTask.Missile, GroupTask.Coastal],
GroupRole.Air: [GroupTask.Air],
}
@classmethod
def by_description(cls, description: str) -> GroupTask:
for task in GroupTask:
if task.description == description:
return task
raise RuntimeError(f"GroupTask with description {description} does not exist")
# ANTI AIR
AAA = ("AAA", GroupRole.AIR_DEFENSE)
EARLY_WARNING_RADAR = ("EarlyWarningRadar", GroupRole.AIR_DEFENSE)
LORAD = ("LORAD", GroupRole.AIR_DEFENSE)
MERAD = ("MERAD", GroupRole.AIR_DEFENSE)
SHORAD = ("SHORAD", GroupRole.AIR_DEFENSE)
# NAVAL
AIRCRAFT_CARRIER = ("AircraftCarrier", GroupRole.NAVAL)
HELICOPTER_CARRIER = ("HelicopterCarrier", GroupRole.NAVAL)
NAVY = ("Navy", GroupRole.NAVAL)
# GROUND FORCES
BASE_DEFENSE = ("BaseDefense", GroupRole.GROUND_FORCE)
FRONT_LINE = ("FrontLine", GroupRole.GROUND_FORCE)
# DEFENSES
COASTAL = ("Coastal", GroupRole.DEFENSES)
MISSILE = ("Missile", GroupRole.DEFENSES)
# BUILDINGS
ALLY_CAMP = ("AllyCamp", GroupRole.BUILDING)
AMMO = ("Ammo", GroupRole.BUILDING)
COMMS = ("Comms", GroupRole.BUILDING)
DERRICK = ("Derrick", GroupRole.BUILDING)
FACTORY = ("Factory", GroupRole.BUILDING)
FARP = ("Farp", GroupRole.BUILDING)
FOB = ("FOB", GroupRole.BUILDING)
FUEL = ("Fuel", GroupRole.BUILDING)
OFFSHORE_STRIKE_TARGET = ("OffShoreStrikeTarget", GroupRole.BUILDING)
OIL = ("Oil", GroupRole.BUILDING)
POWER = ("Power", GroupRole.BUILDING)
STRIKE_TARGET = ("StrikeTarget", GroupRole.BUILDING)
VILLAGE = ("Village", GroupRole.BUILDING)
WARE = ("Ware", GroupRole.BUILDING)
WW2_BUNKER = ("WW2Bunker", GroupRole.BUILDING)

View File

@@ -2,39 +2,40 @@ from __future__ import annotations
from enum import unique, Enum
from game.data.groups import GroupRole, GroupTask
@unique
class UnitClass(Enum):
Unknown = "Unknown"
Tank = "Tank"
Atgm = "ATGM"
Ifv = "IFV"
Apc = "APC"
Artillery = "Artillery"
Logistics = "Logistics"
Recon = "Recon"
Infantry = "Infantry"
UNKNOWN = "Unknown"
AAA = "AAA"
AIRCRAFT_CARRIER = "AircraftCarrier"
APC = "APC"
ARTILLERY = "Artillery"
ATGM = "ATGM"
BOAT = "Boat"
COMMAND_POST = "CommandPost"
CRUISER = "Cruiser"
DESTROYER = "Destroyer"
EARLY_WARNING_RADAR = "EarlyWarningRadar"
FORTIFICATION = "Fortification"
FRIGATE = "Frigate"
HELICOPTER_CARRIER = "HelicopterCarrier"
IFV = "IFV"
INFANTRY = "Infantry"
LANDING_SHIP = "LandingShip"
LAUNCHER = "Launcher"
LOGISTICS = "Logistics"
MANPAD = "Manpad"
MISSILE = "Missile"
OPTICAL_TRACKER = "OpticalTracker"
PLANE = "Plane"
POWER = "Power"
RECON = "Recon"
SEARCH_LIGHT = "SearchLight"
SEARCH_RADAR = "SearchRadar"
SEARCH_TRACK_RADAR = "SearchTrackRadar"
SHORAD = "SHORAD"
Manpad = "Manpad"
SR = "SearchRadar"
STR = "SearchTrackRadar"
LowAltSR = "LowAltSearchRadar"
TR = "TrackRadar"
LN = "Launcher"
EWR = "EarlyWarningRadar"
SPECIALIZED_RADAR = "SpecializedRadar"
SUBMARINE = "Submarine"
TANK = "Tank"
TELAR = "TELAR"
Missile = "Missile"
AircraftCarrier = "AircraftCarrier"
HelicopterCarrier = "HelicopterCarrier"
Destroyer = "Destroyer"
Cruiser = "Cruiser"
Submarine = "Submarine"
LandingShip = "LandingShip"
Boat = "Boat"
Plane = "Plane"
def to_dict(self) -> str:
return self.value
TRACK_RADAR = "TrackRadar"