/
Alexwww228
/
BridgeBattleSimulator
Обзор
Документация
Войти
/
Alexwww228
/
BridgeBattleSimulator
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
BattleSimulator.UI/ViewModels/UnitViewModel.cs
127 строк
5 KB
Alexwww228
fix: save and logic
24 апр 2026, 21:29
24 апр 2026, 21:29
89aa884
Код
Авторство
О чём код?
using ReactiveUI; using BattleSimulator.Domain.Decorators; using BattleSimulator.Domain.Interfaces; using BattleSimulator.Domain.Units; namespace BattleSimulator.UI.ViewModels; /// <summary> /// ViewModel-обёртка над IUnit для реактивного отображения в UI. /// /// Паттерн MVVM: ViewModel транслирует состояние домена в наблюдаемые свойства. /// Refresh() вызывается после каждого хода для обновления HP-бара и статуса. /// </summary> public sealed class UnitViewModel : ReactiveObject { private readonly IUnit _unit; /// <summary>Создать VM для юнита. isFront = стоит ли у моста.</summary> public UnitViewModel(IUnit unit, bool isFront = false) { _unit = unit; IsFront = isFront; Refresh(); } // ── Неизменяемые свойства (из домена) ────────────────────────────── public string Name => _unit.Name; public string UnitType => _unit.UnitType; public int MaxHp => _unit.MaxHp; public int Attack => _unit.Attack; public int Defense => _unit.Defense; public int Cost => _unit.Cost; // ── Реактивные свойства (обновляются через Refresh) ───────────────── /// <summary>Текущее HP.</summary> public int Hp { get; private set; } /// <summary>Жив ли юнит.</summary> public bool IsAlive { get; private set; } /// <summary>Является ли юнит передовым (у моста).</summary> private bool _isFront; public bool IsFront { get => _isFront; set { if (_isFront == value) return; _isFront = value; this.RaisePropertyChanged(nameof(IsFront)); } } /// <summary>Текстовый статус для отображения.</summary> public string StatusText { get; private set; } = ""; public string BuffText { get; private set; } = ""; public bool HasBuffs => !string.IsNullOrWhiteSpace(BuffText); public string TraitsText { get; private set; } = ""; public bool HasTraits => !string.IsNullOrWhiteSpace(TraitsText); /// <summary>Процент оставшегося HP (0.0–1.0) для прогресс-бара.</summary> public double HpPercent => MaxHp == 0 ? 0 : (double)Hp / MaxHp; /// <summary>Цвет HP-бара: зелёный → оранжевый → красный.</summary> public string HpBarColor => HpPercent switch { >= 0.6 => "#4CAF50", >= 0.3 => "#FF9800", _ => "#F44336" }; /// <summary> /// Обновить реактивные свойства из состояния домена. /// Вызывается Battlefield/BattleViewModel после каждой атаки. /// </summary> public void Refresh() { Hp = _unit.Hp; IsAlive = _unit.IsAlive; StatusText = _unit.IsAlive ? $"ХП: {_unit.Hp}/{_unit.MaxHp}" : "☠ Погиб"; BuffText = string.Join(", ", UnitBuffDecorator.GetBuffTypes(_unit)); TraitsText = BuildTraitsText(_unit); // Уведомляем об изменении свойств и вычисляемых значений this.RaisePropertyChanged(nameof(Hp)); this.RaisePropertyChanged(nameof(MaxHp)); this.RaisePropertyChanged(nameof(IsAlive)); this.RaisePropertyChanged(nameof(StatusText)); this.RaisePropertyChanged(nameof(BuffText)); this.RaisePropertyChanged(nameof(HasBuffs)); this.RaisePropertyChanged(nameof(TraitsText)); this.RaisePropertyChanged(nameof(HasTraits)); this.RaisePropertyChanged(nameof(HpPercent)); this.RaisePropertyChanged(nameof(HpBarColor)); } private static string BuildTraitsText(IUnit unit) { var traits = new List<string>(); if (unit.IsArmyClone) traits.Add("Клон"); var core = unit; while (core is UnitBuffDecorator decorator) core = decorator.InnerUnit; if (core is Archer archer) traits.Add($"Дальн:{archer.Range}"); if (core is Unit domainUnit && domainUnit.Power > 0) traits.Add(core.UnitType switch { "Wizard" => $"Шанс:{domainUnit.Power}%", "Healer" => $"Леч:{domainUnit.Power}", _ => $"Power:{domainUnit.Power}" }); return string.Join(" • ", traits); } }