mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
This was always the intent, but apparently it wasn't implemented correctly. All properties of the unit type can now be overridden per variant.
101 lines
2.7 KiB
Python
101 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
from abc import ABC
|
|
from dataclasses import dataclass
|
|
from functools import cached_property
|
|
from pathlib import Path
|
|
from typing import ClassVar, Generic, Iterator, Type, TypeVar, Any
|
|
|
|
import yaml
|
|
from dcs.unittype import UnitType as DcsUnitType
|
|
from typing_extensions import Self
|
|
|
|
from game.data.units import UnitClass
|
|
|
|
DcsUnitTypeT = TypeVar("DcsUnitTypeT", bound=Type[DcsUnitType])
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class UnitType(ABC, Generic[DcsUnitTypeT]):
|
|
dcs_unit_type: DcsUnitTypeT
|
|
variant_id: str
|
|
description: str
|
|
year_introduced: str
|
|
country_of_origin: str
|
|
manufacturer: str
|
|
role: str
|
|
price: int
|
|
unit_class: UnitClass
|
|
|
|
_loaded: ClassVar[bool] = False
|
|
|
|
def __str__(self) -> str:
|
|
return self.variant_id
|
|
|
|
@property
|
|
def dcs_id(self) -> str:
|
|
return self.dcs_unit_type.id
|
|
|
|
@classmethod
|
|
def register(cls, unit_type: Self) -> None:
|
|
raise NotImplementedError
|
|
|
|
@classmethod
|
|
def named(cls, name: str) -> Self:
|
|
raise NotImplementedError
|
|
|
|
@classmethod
|
|
def for_dcs_type(cls, dcs_unit_type: DcsUnitTypeT) -> Iterator[Self]:
|
|
raise NotImplementedError
|
|
|
|
@staticmethod
|
|
def each_dcs_type() -> Iterator[DcsUnitTypeT]:
|
|
raise NotImplementedError
|
|
|
|
@classmethod
|
|
def _data_directory(cls) -> Path:
|
|
raise NotImplementedError
|
|
|
|
@classmethod
|
|
def _each_variant_of(cls, unit: DcsUnitTypeT) -> Iterator[Self]:
|
|
data_path = cls._data_directory() / f"{unit.id}.yaml"
|
|
if not data_path.exists():
|
|
logging.warning(f"No data for {unit.id}; it will not be available")
|
|
return
|
|
|
|
with data_path.open(encoding="utf-8") as data_file:
|
|
data = yaml.safe_load(data_file)
|
|
|
|
for variant_id, variant_data in data.get("variants", {unit.id: {}}).items():
|
|
if variant_data is None:
|
|
variant_data = {}
|
|
yield cls._variant_from_dict(unit, variant_id, data | variant_data)
|
|
|
|
@classmethod
|
|
def _variant_from_dict(
|
|
cls, dcs_unit_type: DcsUnitTypeT, variant_id: str, data: dict[str, Any]
|
|
) -> Self:
|
|
raise NotImplementedError
|
|
|
|
@classmethod
|
|
def _load_all(cls) -> None:
|
|
for unit_type in cls.each_dcs_type():
|
|
for data in cls._each_variant_of(unit_type):
|
|
cls.register(data)
|
|
cls._loaded = True
|
|
|
|
@cached_property
|
|
def eplrs_capable(self) -> bool:
|
|
return getattr(self.dcs_unit_type, "eplrs", False)
|
|
|
|
@classmethod
|
|
def exists(cls, name: str) -> bool:
|
|
if not cls._loaded:
|
|
cls._load_all()
|
|
try:
|
|
cls.named(name)
|
|
return True
|
|
except (KeyError, AssertionError):
|
|
return False
|