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(),
["knight-of-rose-morgana"] = new MorganaScript(),
};
}
///
/// Knight of Rose, Morgana: при атаке можно сбросить карту из руки и получить +4000 до конца хода.
///
public sealed class MorganaScript : CardScript
{
public override string NameId => "knight-of-rose-morgana";
public override IEnumerable Abilities
{
get
{
yield return new AbilityDefinition
{
Trigger = AbilityTrigger.OnAttackDeclared,
Optional = true,
CanPay = ctx => ctx.State.Players[ctx.Owner].Hand.Count > 0,
Resolve = ctx => ctx.Engine.AskHandCardChoice(
ctx.Owner,
"Сбросьте карту из руки",
null,
card =>
{
var p = ctx.State.Players[ctx.Owner];
p.Hand.Remove(card);
p.Drop.Add(card);
ctx.Source.TemporaryPower += 4000;
}),
};
}
}
}
/// 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);
},
};
}
}
}