using System; using System.Collections.Generic; // Контракты модулей: всё, что один модуль может попросить у другого. // Реализация живёт в своём модуле, здесь -- только "что умеет". // Добавляя метод сюда, обнови документ модуля в Docs/Modules. // ---------------- Экономика: ресурсы и производство ---------------- public interface IEconomy { float Get(ResourceType type); bool Has(ResourceType type, float amount); void Add(ResourceType type, float amount); bool TrySpend(ResourceType type, float amount); bool CanAfford(IReadOnlyList cost); // Списывает всё или ничего bool TrySpend(IReadOnlyList cost); } // ---------------- Поселение: здания и развитие города ---------------- public interface ISettlement { int TownHallLevel { get; } int BuildingCount { get; } bool IsCityLoaded { get; } // открыта ли сейчас сцена города } // Здание с уровнем (добывающие постройки и т.п.) -- Поселение сохраняет уровень, не зная, чьё это здание public interface ILeveledBuilding { int Level { get; set; } } // ---------------- Армия: войска ---------------- public interface IArmy { int SoldiersAtHome { get; } // Забрать воинов из города в поход (запоминает состав похода) bool TakeForMarch(int marchId, int count); // Вернуть выживших из похода по тем же типам войск void ReturnFromMarch(int marchId, int survivors); } // ---------------- Глобальный мир: карта и перемещения ---------------- public interface IWorld { int ActiveMarches { get; } bool TryStartMarch(string targetId, int soldiers, out string error); } // ---------------- Боевая система: урон, потери, исход ---------------- public struct BattleRequest { public int Attackers; public int Defenders; } public struct BattleOutcome { public bool Victory; // победил атакующий public int AttackerLosses; public int DefenderLosses; public int Survivors; // сколько атакующих осталось } public interface IBattleSystem { BattleOutcome Resolve(BattleRequest request); } // ---------------- Чат: общий мир и Круг ---------------- public enum ChatChannel { World, // общий чат всего мира Circle // чат своего Круга } [Serializable] public class ChatMessage { public ChatChannel channel; public string senderId; public string senderName; public string text; public long timeMs; // Unix-время в миллисекундах } public interface IChat { int MaxMessageLength { get; } IReadOnlyList GetMessages(ChatChannel channel); bool CanWrite(ChatChannel channel); // в канал "Круг" -- только состоя в Круге // Отправить от имени локального игрока. false -- пустое сообщение или канал "Круг" без Круга bool Send(ChatChannel channel, string text); } // ---------------- Круг: объединение игроков ---------------- public enum CircleRole { Leader, // глава Member // участник } [Serializable] public class CircleMember { public string playerId; public string name; public CircleRole role; } [Serializable] public class CircleInfo { public string id; public string name; public List members = new List(); public string LeaderName { get { foreach (var m in members) if (m.role == CircleRole.Leader) return m.name; return ""; } } } public interface ICircle { int MaxMembers { get; } CircleInfo Current { get; } // Круг игрока; null -- игрок не в Круге bool IsInCircle { get; } bool IsLeader { get; } IReadOnlyList GetCircles(); // все Круги, в которые можно вступить bool TryCreate(string name, out string error); // создатель становится главой bool TryJoin(string circleId, out string error); void Leave(); // глава один в Круге -- Круг распускается } // ---------------- Сохранения: игровое состояние ---------------- public interface ISaveSystem { bool HasSave { get; } void SaveNow(); void DeleteSave(); // Новая игра: все модули возвращаются к стартовому состоянию, файл перезаписывается void ResetAll(); } // Участник сохранения: каждый модуль сам решает, что и как хранит, в своей секции файла. public interface ISaveParticipant { string SaveKey { get; } // имя секции в файле: "economy", "settlement", "world"... string Capture(); // JSON секции; null -- оставить то, что уже было в файле void Restore(string json); void ResetState(); // вернуться к состоянию новой игры (сброс сохранений) } // Список участников. Модули регистрируются сами, модуль Сохранений обходит их при записи и загрузке. public static class SaveRegistry { private static readonly List participants = new List(); public static IReadOnlyList All => participants; public static void Register(ISaveParticipant participant) { participants.RemoveAll(p => p.SaveKey == participant.SaveKey); participants.Add(participant); } public static void Unregister(ISaveParticipant participant) { participants.Remove(participant); } public static void Clear() { participants.Clear(); } }