using Vanguard.Rules.Cards; namespace Vanguard.Rules.Engine.Abilities; /// Скрипты карт первого сета, подключённые к движку. public static class CardScripts { public static IReadOnlyDictionary Default { get; } = new Dictionary(StringComparer.Ordinal) { ["barcgal"] = new BarcgalScript(), ["wingal"] = new WingalScript(), ["king-of-knights-alfred"] = new AlfredScript(), ["blaster-blade"] = new BlasterBladeScript(), ["lake-maiden-lien"] = new DrawOneScript("lake-maiden-lien"), ["dragon-monk-gojo"] = new DrawOneScript("dragon-monk-gojo"), ["screamin-and-dancin-announcer-shout"] = new DrawOneScript("screamin-and-dancin-announcer-shout"), ["lizard-soldier-conroe"] = new ConroeScript(), ["battle-sister-cocoa"] = new CocoaScript(), ["tyrant-deathrex"] = new DeathrexScript(), ["demon-eater"] = new DemonEaterScript(), ["maiden-of-libra"] = new MaidenOfLibraScript(), }; } /// Tyrant, Deathrex: когда эта карта атакует, получает +5000 до конца боя. public sealed class DeathrexScript : CardScript { public override string NameId => "tyrant-deathrex"; public override IEnumerable Abilities { get { yield return new AbilityDefinition { Trigger = AbilityTrigger.OnAttackDeclared, Resolve = ctx => ctx.Engine.AddBattlePower(5000), }; } } } /// Demon Eater: в начале Основной фазы Soul Charge 1 и +2000 до конца хода. public sealed class DemonEaterScript : CardScript { public override string NameId => "demon-eater"; public override IEnumerable Abilities { get { yield return new AbilityDefinition { Trigger = AbilityTrigger.OnPhaseStart, Resolve = ctx => { ctx.Engine.SoulCharge(ctx.Owner, 1); ctx.Source.TemporaryPower += 2000; }, }; } } } /// Maiden of Libra: когда атака попадает, Counter Blast 2 и взять карту. public sealed class MaidenOfLibraScript : CardScript { public override string NameId => "maiden-of-libra"; public override IEnumerable Abilities { get { yield return new AbilityDefinition { Trigger = AbilityTrigger.OnAttackHit, Optional = true, CanPay = ctx => ctx.Engine.CanCounterBlast(ctx.Owner, 2), Pay = ctx => ctx.Engine.CounterBlast(ctx.Owner, 2), Resolve = ctx => ctx.Engine.DrawCards(ctx.Owner, 1), }; } } } /// /// Battle Sister, Cocoa: при размещении на VC/RC, если Авангард Oracle Think Tank, /// посмотреть верхнюю карту и оставить её на верху или отправить в низ. /// public sealed class CocoaScript : CardScript { public override string NameId => "battle-sister-cocoa"; public override IEnumerable Abilities { get { yield return new AbilityDefinition { Trigger = AbilityTrigger.OnPlace, Condition = ctx => ctx.Engine.VanguardClan(ctx.Owner) == Clan.OracleThinkTank, Resolve = ctx => ctx.Engine.LookTopAndReorder(ctx.Owner, "Верхняя карта колоды"), }; } } } /// /// Lizard Soldier, Conroe: [ACT](RC): Counter Blast 1 и уничтожить эту карту → /// найти в колоде Kagero 1 ранга или ниже и добавить в руку. /// public sealed class ConroeScript : CardScript { public override string NameId => "lizard-soldier-conroe"; public override IEnumerable Activated { get { yield return new ActivatedAbility { CanActivate = ctx => ctx.Engine.CanCounterBlast(ctx.Owner, 1), RetiresSelf = true, Resolve = ctx => { ctx.Engine.CounterBlast(ctx.Owner, 1); ctx.Engine.SearchDeckToHand( ctx.Owner, "Найдите Kagero 1 ранга или ниже", d => d.Clan == Clan.Kagero && d.Grade <= 1); }, }; } } } /// /// «[ACT]: повернуть эту карту и сбросить карту из руки → взять карту». /// Общий скрипт для Lake Maiden, Lien, Dragon Monk, Gojo и Shout. /// public sealed class DrawOneScript : CardScript { public DrawOneScript(string nameId) => NameId = nameId; public override string NameId { get; } public override IEnumerable Activated { get { yield return new ActivatedAbility { CanActivate = _ => true, RestsSelf = true, RequiresDiscard = true, Resolve = ctx => ctx.Engine.DrawCards(ctx.Owner, 1), }; } } } /// /// Blaster Blade: при размещении оплатить Counter Blast 2 и уничтожить Арьергард противника. /// На Авангарде — любой, на Арьергарде — только 2 ранга или выше и при Авангарде Royal Paladin. /// public sealed class BlasterBladeScript : CardScript { public override string NameId => "blaster-blade"; public override IEnumerable Abilities { get { yield return new AbilityDefinition { Trigger = AbilityTrigger.OnPlace, Optional = true, Condition = ctx => ctx.Engine.IsVanguardOf(ctx.Source, ctx.Owner), CanPay = ctx => ctx.Engine.CanCounterBlast(ctx.Owner, 2), Pay = ctx => ctx.Engine.CounterBlast(ctx.Owner, 2), Resolve = ctx => { var opponent = 1 - ctx.Owner; var slots = ctx.Engine.RearGuardSlots(opponent, _ => true); if (slots.Count == 0) return; ctx.Engine.AskUnitChoice( ctx.Owner, opponent, "Выберите Арьергард противника", slots, slot => ctx.Engine.RetireRearGuard(opponent, slot)); }, }; yield return new AbilityDefinition { Trigger = AbilityTrigger.OnPlace, Optional = true, Condition = ctx => !ctx.Engine.IsVanguardOf(ctx.Source, ctx.Owner) && ctx.Engine.VanguardClan(ctx.Owner) == Clan.RoyalPaladin, CanPay = ctx => ctx.Engine.CanCounterBlast(ctx.Owner, 2), Pay = ctx => ctx.Engine.CounterBlast(ctx.Owner, 2), Resolve = ctx => { var opponent = 1 - ctx.Owner; var slots = ctx.Engine.RearGuardSlots(opponent, d => d.Grade >= 2); if (slots.Count == 0) return; ctx.Engine.AskUnitChoice( ctx.Owner, opponent, "Выберите Арьергард противника 2 ранга или выше", slots, slot => ctx.Engine.RetireRearGuard(opponent, slot)); }, }; } } } /// /// Barcgal: когда другой Royal Paladin сменяет эту карту, вы можете призвать её в круг Арьергарда. /// public sealed class BarcgalScript : CardScript { public override string NameId => "barcgal"; public override IEnumerable Abilities { get { yield return new AbilityDefinition { Trigger = AbilityTrigger.OnRideOver, Optional = true, Condition = ctx => ctx.Other is not null && ctx.Catalog.CardOf(ctx.Other.PrintingId).Clan == Clan.RoyalPaladin, Resolve = ctx => ctx.Engine.CallFromSoul(ctx.Source, ctx.Owner), }; } } } /// /// Wingal: когда эта карта поддерживает Blaster Blade, усиленная карта получает +4000 до конца боя. /// public sealed class WingalScript : CardScript { private const string BlasterBlade = "blaster-blade"; public override string NameId => "wingal"; public override IEnumerable Abilities { get { yield return new AbilityDefinition { Trigger = AbilityTrigger.OnBoost, Condition = ctx => ctx.Other is not null && ctx.Catalog.CardOf(ctx.Other.PrintingId).NameId == BlasterBlade, Resolve = ctx => ctx.Engine.AddBattlePower(4000), }; } } } /// /// King of Knights, Alfred: в свой ход на круге Авангарда получает +2000 /// за каждый свой Арьергард Royal Paladin. /// public sealed class AlfredScript : CardScript { public override string NameId => "king-of-knights-alfred"; public override IEnumerable Continuous { get { yield return new ContinuousAbility { Applies = ctx => ctx.Engine.IsVanguardOf(ctx.Source, ctx.Owner) && ctx.State.ActivePlayer == ctx.Owner, PowerBonus = ctx => 2000 * ctx.Engine.CountRearGuards(ctx.Owner, Clan.RoyalPaladin), }; } } public override IEnumerable Activated { get { yield return new ActivatedAbility { CanActivate = ctx => ctx.Engine.CanCounterBlast(ctx.Owner, 3) && ctx.Engine.HasEmptyRearGuard(ctx.Owner), Resolve = ctx => { ctx.Engine.CounterBlast(ctx.Owner, 3); ctx.Engine.SearchDeckToCall( ctx.Owner, "Найдите Royal Paladin 2 ранга или ниже", d => d.Clan == Clan.RoyalPaladin && d.Grade <= 2); }, }; } } }