/
puma
/
ppa
Обзор
Документация
Войти
/
puma
/
ppa
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Managers/GameManager.cs
228 строк
8 KB
Margarita
vse
28 май 2026, 22:57
28 май 2026, 22:57
75da34e
Код
Авторство
О чём код?
using System; using System.Collections.Generic; using System.Linq; using Game.Models.Units.Adapters; public class GameManager { private readonly SaveManager _saveManager; private static readonly List<IUnitDeserializer> _deserializers = [ new LightInfantryDeserializer(), new HeavyInfantryDeserializer(), new ArcherDeserializer(), new WizardDeserializer(), new HealerDeserializer(), new GulyayGorodDeserializer() ]; /// <summary> /// Конструктор с dependency injection SaveManager /// </summary> public GameManager(SaveManager saveManager) { _saveManager = saveManager ?? throw new ArgumentNullException(nameof(saveManager)); } public GameManager() : this(new SaveManager()) { } /// <summary> /// Создать данные для сохранения текущего состояния игры /// </summary> public GameSaveData CreateSaveData(Player player1, Player player2, Player currentPlayer, int roundNumber, string gameMode = "BridgeFormation") { var saveData = new GameSaveData { Player1Name = player1.Name, Player2Name = player2.Name, RoundNumber = roundNumber, CurrentPlayerName = currentPlayer.Name, Player1Units = ConvertUnitsToSaveData(player1.Army?.Units ?? new()), Player2Units = ConvertUnitsToSaveData(player2.Army?.Units ?? new()), ProxyDamageLoggingEnabled = ObserverSettings.Current.EnableDamageLogging, ProxyDeathBeepEnabled = ObserverSettings.Current.EnableDeathBeep, DamageLogSessionNumber = DamageLogViewer.GetSessionNumber(), GameMode = gameMode }; return saveData; } /// <summary> /// Восстановить игру из сохраненных данных /// </summary> public (Player player1, Player player2, Player currentPlayer, int roundNumber, string gameMode)? LoadGameState(GameSaveData saveData) { try { // Восстанавливаем настройки наблюдателей из сохранённой игры ObserverSettings.Current.EnableDamageLogging = saveData.ProxyDamageLoggingEnabled; ObserverSettings.Current.EnableDeathBeep = saveData.ProxyDeathBeepEnabled; // Восстанавливаем номер сессии логирования, чтобы лог принадлежал сохраненной игре DamageLogViewer.SetSessionNumber(saveData.DamageLogSessionNumber); var player1 = new Player(saveData.Player1Name); var player2 = new Player(saveData.Player2Name); var army1 = new Army(saveData.Player1Name + " Army"); var army2 = new Army(saveData.Player2Name + " Army"); foreach (var unitData in saveData.Player1Units ?? new()) { var unit = CreateUnitFromSaveData(unitData); if (unit != null) army1.AddUnit(unit); } foreach (var unitData in saveData.Player2Units ?? new()) { var unit = CreateUnitFromSaveData(unitData); if (unit != null) army2.AddUnit(unit); } player1.Army = army1; player2.Army = army2; for (int i = 0; i < army1.Units.Count; i++) army1.Units[i].SetArmyOrder(i + 1); for (int i = 0; i < army2.Units.Count; i++) army2.Units[i].SetArmyOrder(i + 1); var currentPlayer = saveData.CurrentPlayerName == player1.Name ? player1 : player2; string gameMode = saveData.GameMode ?? "BridgeFormation"; return (player1, player2, currentPlayer, saveData.RoundNumber, gameMode); } catch (Exception ex) { throw new InvalidOperationException($"Ошибка при восстановлении игры: {ex.Message}", ex); } } /// <summary> /// Получить SaveManager для прямого доступа к сохранениям /// </summary> public SaveManager GetSaveManager() => _saveManager; private List<UnitSaveData> ConvertUnitsToSaveData(List<IUnit> units) { var result = new List<UnitSaveData>(); foreach (var unit in units) { var unitData = new UnitSaveData { Id = unit.Id, Name = unit.Name, Attack = unit is IBuffable b ? b.BaseAttack : unit.Attack, Defense = unit is IBuffable b2 ? b2.BaseDefense : unit.Defense, MaxHealth = unit.MaxHealth, CurrentHealth = unit.CurrentHealth, Cost = unit.Cost, IsAlive = unit.IsAlive, UnitType = GetUnitType(unit) }; if (unit.SpecialAbility is ArrowAbility arrowAbility) { unitData.ArrowRange = arrowAbility.Range; unitData.ArrowPower = arrowAbility.Power; } else if (unit.SpecialAbility is CloneAbility cloneAbility) { unitData.CloneRange = cloneAbility.Range; unitData.CloneProbability = cloneAbility.CloneProbability; } else if (unit.SpecialAbility is HealAbility healAbility) { unitData.HealRange = healAbility.Range; unitData.HealPower = healAbility.HealPower; } if (unit is IBuffable buffable && buffable.HasBuffs()) { unitData.ActiveBuffs = buffable.GetActiveBuffs() .OfType<BuffDecorator>() .Select(b => { var fresh = b.Fresh(); int value = fresh switch { ShieldBuff => fresh.DefenseModifier, SpearBuff => fresh.AttackModifier, HorseBuff => fresh.AttackModifier, HelmetBuff => fresh.ArrowDefenseModifier, _ => 0 }; return $"{b.Name}:{value}"; }) .ToList(); } result.Add(unitData); } return result; } /// <summary> /// Создать юнита из сохраненных данных, используя factory pattern /// </summary> private static IUnit? CreateUnitFromSaveData(UnitSaveData unitData) { var deserializer = _deserializers.FirstOrDefault(d => d.CanDeserialize(unitData)); IUnit? unit = deserializer?.Deserialize(unitData); if (unit != null) { unit.SetId(unitData.Id); unit.SetCurrentHealth(unitData.CurrentHealth); if (unit is IBuffable buffable && unitData.ActiveBuffs != null) { foreach (var entry in unitData.ActiveBuffs) { var parts = entry.Split(':'); if (parts.Length != 2 || !int.TryParse(parts[1], out int val)) continue; IBuff? buff = parts[0] switch { "Shield" => new ShieldBuff(val), "Spear" => new SpearBuff(val), "Horse" => new HorseBuff(val), "Helmet" => new HelmetBuff(val), _ => null }; if (buff != null) buffable.AddBuff(buff); } } ObserverSettings.Current.ApplyObservers(unit); } return unit; } private string GetUnitType(IUnit unit) { // Проверяем по имени юнита, так как это работает даже с Proxy-объектами if (unit.Name == "Light Infantry") return "LightInfantry"; else if (unit.Name == "Heavy Infantry") return "HeavyInfantry"; else if (unit.SpecialAbility is ArrowAbility) return "Archer"; else if (unit.SpecialAbility is CloneAbility) return "Wizard"; else if (unit.SpecialAbility is HealAbility) return "Healer"; else if (unit.Name == "Gulyay-Gorod") return "Gulyay-Gorod"; return "Unknown"; } }