using UnityEngine; // ТОЧКА СБОРКИ МОДУЛЕЙ (слой приложения). Документ: Docs/Modules/README.md // // Здесь и только здесь модули соединяются с остальной игрой: // 1. регистрируются реализации контрактов, которые не регистрируются сами; // 2. события модулей подключаются к системам, которые ещё не разнесены по модулям (GameProgress, Казармы). // Модули друг о друге ничего не знают -- всю "проводку" видно в одном файле. public static class GameModules { // После SubsystemRegistration (там ядро очищается) и раньше любых Awake [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)] static void Register() { // Боевая система -- чистый C#, сама зарегистрироваться не может GameServices.Register(new BattleSystem()); // Армия -- чистый C#, единственное место хранения войск (секция "army") var army = new ArmyService(); GameServices.Register(army); SaveRegistry.Register(army); EventBus.Subscribe(_ => { if (GameProgress.HasInstance) GameProgress.Instance.MarkChanged(); }); EventBus.Subscribe(_ => MigrateLegacyArmy(army)); // Круг -- чистый C#, сам сохраняет, в каком Круге игрок (секция "circle") var circle = new CircleService(); GameServices.Register(circle); SaveRegistry.Register(circle); // Чат -- чистый C#; история живёт, пока открыта игра (между сценами тоже) GameServices.Register(new ChatService(System.DateTimeOffset.UtcNow.ToUnixTimeMilliseconds())); // Казармы появляются в списке стройки кодом -- до восстановления зданий из сохранения EventBus.Subscribe(_ => BarracksBootstrap.Ensure()); // Статистика для заданий (GameProgress) -- по событиям Мира EventBus.Subscribe(OnMarchStarted); EventBus.Subscribe(OnMarchReturned); // Окно "ВОЙСКО ВЕРНУЛОСЬ" в городе MarchReturnPopup.Reset(); EventBus.Subscribe(MarchReturnPopup.OnMarchReturned); } // Сцена загружена, Awake всех объектов прошли, Start -- ещё нет (сохранение грузится в Start) [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] static void MigrateLegacyMarches() { // Раньше походы хранились в progress.json (GameProgress.Data.sashaMarches). // Теперь их сохраняет модуль Мира в save.json, секция "world". Переносим один раз. var data = GameProgress.Instance.Data; if (data.sashaMarches == null || data.sashaMarches.Count == 0 || MarchManager.Instance == null) return; // Если в save.json уже есть секция "world", загрузка сохранения заменит эти походы на сохранённые MarchManager.Instance.LoadMarches(new System.Collections.Generic.List(data.sashaMarches)); // Из progress.json убираем, только когда походы уже записаны в save.json -- иначе вылет игры их потеряет EventBus.Subscribe(ClearLegacyMarches); } static void ClearLegacyMarches(GameSavedEvent e) { EventBus.Unsubscribe(ClearLegacyMarches); GameProgress.Instance.Data.sashaMarches.Clear(); GameProgress.Instance.MarkChanged(); Debug.Log("[МОДУЛИ] Походы перенесены из progress.json в модуль Мира."); } // Раньше войска хранились в progress.json (GameProgress.Data.troops и sashaMarchUnits моста ArmyBridge). // Теперь -- в модуле Армии, save.json, секция "army". Переносим один раз, после загрузки сохранения. static void MigrateLegacyArmy(ArmyService army) { var data = GameProgress.Instance.Data; if (data.armyInModule) return; if (!army.RestoredFromSave) { var legacyMarches = new System.Collections.Generic.List>(); foreach (var m in data.sashaMarchUnits) legacyMarches.Add(new System.Collections.Generic.KeyValuePair(m.marchId, m.units)); army.ImportLegacy(data.troops, legacyMarches); Debug.Log($"[МОДУЛИ] Войска перенесены из progress.json в модуль Армии: в городе {army.SoldiersAtHome}, в походах {army.TroopsInMarches}."); } // Из progress.json убираем, только когда войска уже записаны в save.json -- иначе вылет игры их потеряет if (army.RestoredFromSave) ClearLegacyArmy(default); else EventBus.Subscribe(ClearLegacyArmy); } static void ClearLegacyArmy(GameSavedEvent e) { EventBus.Unsubscribe(ClearLegacyArmy); var data = GameProgress.Instance.Data; data.armyInModule = true; System.Array.Clear(data.troops, 0, data.troops.Length); data.sashaMarchUnits.Clear(); GameProgress.Instance.MarkChanged(); } static void OnMarchStarted(MarchStartedEvent e) { var data = GameProgress.Instance.Data; data.marchesSent++; data.dailyMarches++; GameProgress.Instance.MarkChanged(); } static void OnMarchReturned(MarchReturnedEvent e) { if (!e.Victory) return; GameProgress.Instance.Data.worldWins++; GameProgress.Instance.MarkChanged(); } }