diff --git a/changelog.md b/changelog.md index 0e836160..022a919f 100644 --- a/changelog.md +++ b/changelog.md @@ -9,6 +9,7 @@ Saves from 2.5 are not compatible with 3.0. * **[Campaign]** Ground units must now be recruited at a base with a factory and transferred to their destination. When buying units in the UI, the purchase will automatically be fulfilled at the closest factory, and a transfer will be created on the next turn. * **[UI]** Campaigns generated for an older or newer version of the game will now be marked as incompatible. They can still be played, but bugs may be present. * **[Modding]** Campaigns now choose locations for factories to spawn. +* **[Modding]** Can now install custom factions to /Liberation/Factions instead of the Liberation install directory. ## Fixes diff --git a/game/factions/faction_loader.py b/game/factions/faction_loader.py index 35fb2830..d0722a00 100644 --- a/game/factions/faction_loader.py +++ b/game/factions/faction_loader.py @@ -2,8 +2,9 @@ from __future__ import annotations import json import logging from pathlib import Path -from typing import Dict, Iterator, Optional, Type +from typing import Dict, Iterator, List, Optional, Type +from game import persistency from game.factions.faction import Faction FACTION_DIRECTORY = Path("./resources/factions/") @@ -23,9 +24,16 @@ class FactionLoader: if self._factions is None: self._factions = self.load_factions() + @staticmethod + def find_faction_files_in(path: Path) -> List[Path]: + return [f for f in path.glob("*.json") if f.is_file()] + @classmethod def load_factions(cls: Type[FactionLoader]) -> Dict[str, Faction]: - files = [f for f in FACTION_DIRECTORY.glob("*.json") if f.is_file()] + user_faction_path = Path(persistency.base_path()) / "Liberation/Factions" + files = cls.find_faction_files_in( + FACTION_DIRECTORY + ) + cls.find_faction_files_in(user_faction_path) factions = {} for f in files: diff --git a/qt_ui/main.py b/qt_ui/main.py index 5acfba73..826e455b 100644 --- a/qt_ui/main.py +++ b/qt_ui/main.py @@ -213,9 +213,6 @@ def lint_weapon_data() -> None: def main(): logging_config.init_logging(VERSION) - # Load eagerly to catch errors early. - db.FACTIONS.initialize() - game: Optional[Game] = None args = parse_args()