diff --git a/changelog.md b/changelog.md index 55e745ba..b1570640 100644 --- a/changelog.md +++ b/changelog.md @@ -12,6 +12,7 @@ Saves from 6.x are not compatible with 7.0. * **[Mission Generation]** The A-10C II now uses separate radios for inter- and intra-flight comms (similar to other modern aircraft). * **[Modding]** Updated Community A-4E-C mod version support to 2.1.0 release. * **[Modding]** Add support for VSN F-4B and F-4C mod. +* **[Modding]** Custom factions can now be defined in YAML as well as JSON. JSON support may be removed in the future if having both formats causes confusion. ## Fixes diff --git a/game/factions/faction.py b/game/factions/faction.py index 26eb3529..8bab8211 100644 --- a/game/factions/faction.py +++ b/game/factions/faction.py @@ -4,33 +4,32 @@ import itertools import logging from dataclasses import dataclass, field from functools import cached_property -from typing import Optional, Dict, Type, List, Any, Iterator, TYPE_CHECKING +from typing import Any, Dict, Iterator, List, Optional, TYPE_CHECKING, Type import dcs from dcs.countries import country_dict -from dcs.unittype import ShipType, StaticType -from dcs.unittype import UnitType as DcsUnitType +from dcs.unittype import ShipType, StaticType, UnitType as DcsUnitType +from game.armedforces.forcegroup import ForceGroup from game.data.building_data import ( - WW2_ALLIES_BUILDINGS, DEFAULT_AVAILABLE_BUILDINGS, - WW2_GERMANY_BUILDINGS, - WW2_FREE, - REQUIRED_BUILDINGS, IADS_BUILDINGS, + REQUIRED_BUILDINGS, + WW2_ALLIES_BUILDINGS, + WW2_FREE, + WW2_GERMANY_BUILDINGS, ) from game.data.doctrine import ( + COLDWAR_DOCTRINE, Doctrine, MODERN_DOCTRINE, - COLDWAR_DOCTRINE, WWII_DOCTRINE, ) -from game.data.units import UnitClass from game.data.groups import GroupRole +from game.data.units import UnitClass from game.dcs.aircrafttype import AircraftType from game.dcs.groundunittype import GroundUnitType from game.dcs.shipunittype import ShipUnitType -from game.armedforces.forcegroup import ForceGroup from game.dcs.unittype import UnitType if TYPE_CHECKING: @@ -168,7 +167,7 @@ class Faction: return sorted(air_defenses) @classmethod - def from_json(cls: Type[Faction], json: Dict[str, Any]) -> Faction: + def from_dict(cls: Type[Faction], json: Dict[str, Any]) -> Faction: faction = Faction(locales=json.get("locales")) faction.country = json.get("country", "/") diff --git a/game/factions/factions.py b/game/factions/factions.py index c22a2cae..99ae5449 100644 --- a/game/factions/factions.py +++ b/game/factions/factions.py @@ -5,6 +5,8 @@ import logging from collections.abc import Iterator from pathlib import Path +import yaml + from game import persistence from .faction import Faction @@ -22,6 +24,7 @@ class Factions: @staticmethod def iter_faction_files_in(path: Path) -> Iterator[Path]: yield from path.glob("*.json") + yield from path.glob("*.yaml") @classmethod def iter_faction_files(cls) -> Iterator[Path]: @@ -36,8 +39,11 @@ class Factions: for path in cls.iter_faction_files(): try: with path.open("r", encoding="utf-8") as fdata: - data = json.load(fdata) - faction = Faction.from_json(data) + if path.suffix == ".yaml": + data = yaml.safe_load(fdata) + else: + data = json.load(fdata) + faction = Faction.from_dict(data) factions[faction.name] = faction logging.info("Loaded faction from %s", path) except Exception: diff --git a/tests/test_factions.py b/tests/test_factions.py index bec4c278..58e20667 100644 --- a/tests/test_factions.py +++ b/tests/test_factions.py @@ -1,40 +1,33 @@ import json -from pathlib import Path import unittest -import pytest +from pathlib import Path -from dcs.helicopters import UH_1H, AH_64A +import pytest +from dcs.helicopters import AH_64A, UH_1H from dcs.planes import ( - F_15C, - F_15E, - F_14B, - FA_18C_hornet, - F_16C_50, - A_10A, AV8BNA, - B_52H, - B_1B, - F_117A, - MQ_9_Reaper, - E_3A, - E_2C, - KC130, - KC_135, + A_10A, A_10C, A_10C_2, + B_1B, + B_52H, + E_2C, + E_3A, + FA_18C_hornet, + F_117A, + F_14B, + F_15C, + F_15E, + F_16C_50, + KC130, + KC_135, + MQ_9_Reaper, ) -from dcs.ships import ( - Stennis, - LHA_Tarawa, - PERRY, - USS_Arleigh_Burke_IIa, - TICONDEROG, -) -from dcs.vehicles import Armor, Unarmed, Infantry, Artillery +from dcs.ships import LHA_Tarawa, Stennis +from dcs.vehicles import Armor, Artillery, Infantry, Unarmed from game.factions.faction import Faction - THIS_DIR = Path(__file__).parent RESOURCES_DIR = THIS_DIR / "resources" @@ -46,7 +39,7 @@ class TestFactionLoader(unittest.TestCase): @pytest.mark.skip(reason="Faction unit names in the json files are outdated") def test_load_valid_faction(self) -> None: with (RESOURCES_DIR / "valid_faction.json").open("r") as data: - faction = Faction.from_json(json.load(data)) + faction = Faction.from_dict(json.load(data)) self.assertEqual(faction.country, "USA") self.assertEqual(faction.name, "USA 2005") @@ -109,7 +102,7 @@ class TestFactionLoader(unittest.TestCase): with (RESOURCES_DIR / "invalid_faction_country.json").open("r") as data: try: - Faction.from_json(json.load(data)) + Faction.from_dict(json.load(data)) self.fail("Should have thrown assertion error") except AssertionError as e: pass