mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
102 lines
2.7 KiB
Python
102 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
|
|
display_name: 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.display_name
|
|
|
|
@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
|