VanguardReMaster/server/src/Vanguard.Rules/Engine/GameModels.cs

144 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Vanguard.Rules.Cards;
namespace Vanguard.Rules.Engine;
public enum Phase
{
Mulligan,
Stand,
Draw,
Ride,
Main,
Battle,
End,
}
public enum Step
{
None,
Guard,
Drive,
Trigger,
Ability,
Choice,
}
/// <summary>Вариант выбора, который предлагается игроку.</summary>
public sealed record ChoiceOption(int Slot, string Label);
/// <summary>Карта на поле: игрок и круг (-1 — Авангард).</summary>
public sealed record UnitTarget(int Player, int Slot);
/// <summary>
/// Ожидание выбора игрока. Resolve получает индекс выбранного варианта.
/// Пока выбор не сделан, движок не продолжает разрешение способности.
/// </summary>
public sealed class PendingChoice
{
public required int Player { get; init; }
public required string Prompt { get; init; }
public required IReadOnlyList<ChoiceOption> Options { get; init; }
public required Action<int> Resolve { get; init; }
}
public enum TriggerContext
{
DriveCheck,
DamageCheck,
}
/// <summary>Когда карта, находившаяся на поле, возвращается в колоду.</summary>
public enum ReturnToDeckTiming
{
AfterBattle,
EndOfTurn,
}
/// <summary>Триггер, который ждёт выбора целей от владельца.</summary>
public sealed class PendingTrigger
{
public required int Player { get; init; }
public required string PrintingId { get; init; }
public required CardInstance Card { get; init; }
public required TriggerType Trigger { get; init; }
public required TriggerContext Context { get; init; }
/// <summary>На drive check триггер сначала даёт +5000 силы, на damage check — нет.</summary>
public required bool GrantsPower { get; init; }
/// <summary>Сколько урона осталось раздать после этого триггера (контекст damage check).</summary>
public int RemainingDamage { get; init; }
}
/// <summary>Экземпляр карты в партии. Один принт может встречаться много раз.</summary>
public sealed class CardInstance
{
public required int Id { get; init; }
public required string PrintingId { get; init; }
/// <summary>Повёрнута ли карта (Rest). Актуально только для юнитов на поле.</summary>
public bool Rested { get; set; }
/// <summary>Открыта ли карта. Для урона — лицом вверх после Counter Blast.</summary>
public bool FaceUp { get; set; }
/// <summary>Модификаторы силы и крита с указанием источника и срока жизни.</summary>
public List<StatModifier> Modifiers { get; } = new();
/// <summary>Способности, выданные эффектами, а не напечатанные на карте.</summary>
public List<GrantedAbility> GrantedAbilities { get; } = new();
/// <summary>Запреты, выданные эффектами.</summary>
public List<CardRestriction> Restrictions { get; } = new();
/// <summary>Вернуть карту в колоду после боя или в конце хода (Juggernaut, Lozenge).</summary>
public ReturnToDeckTiming? ReturnToDeck { get; set; }
/// <summary>
/// Переопределение Сдерживания, выданное эффектом.
/// null — как напечатано на карте.
/// </summary>
public bool? RestraintOverride { get; set; }
/// <summary>
/// Переопределение способности поддержки, выданное эффектом.
/// null — как напечатано на карте.
/// </summary>
public bool? BoostOverride { get; set; }
/// <summary>Переопределение перехвата, выданное эффектом.</summary>
public bool? InterceptOverride { get; set; }
/// <summary>Эффект разрешил перехватывать из заднего ряда.</summary>
public bool InterceptFromBackRow { get; set; }
/// <summary>
/// Переопределение числа проверок, выданное эффектом.
/// null — по умолчанию: 1 для 0–2 ранга, 2 для 3+, у Арьергарда 0.
/// </summary>
public int? DriveChecksOverride { get; set; }
}
public sealed class PlayerState
{
public PlayerState(string name) => Name = name;
public string Name { get; }
public List<CardInstance> Deck { get; } = new();
public List<CardInstance> Hand { get; } = new();
public CardInstance? Vanguard { get; set; }
/// <summary>Пять кругов Арьергарда: 0–2 задний ряд, 3–4 передний (3 — левый, 4 — правый).</summary>
public CardInstance?[] RearGuards { get; } = new CardInstance?[RearGuardSlots];
public const int RearGuardSlots = 5;
public List<CardInstance> Guardian { get; } = new();
public List<CardInstance> Soul { get; } = new();
public List<CardInstance> Damage { get; } = new();
public List<CardInstance> Drop { get; } = new();
public List<CardInstance> Trigger { get; } = new();
public bool IsDefeated { get; set; }
}