Intercept also works when the vanguard is attacked
Removed the rear-guard-only restriction. Interceptor resolution now runs before the vanguard damage branch, so a successful intercept retires the interceptor and the vanguard takes no damage. The attacked rear-guard still cannot intercept itself. Two tests.
This commit is contained in:
parent
fdc21c8a26
commit
4dd96e6f02
|
|
@ -12,8 +12,9 @@ namespace Vanguard.Rules.Engine;
|
|||
/// * поддержка работает как отдельная способность: карты 0 и 1 ранга могут передать
|
||||
/// свою силу атакующему Арьергарду из той же колонны, сила действует только в этом бою;
|
||||
/// * перехват — отдельная способность карт 2 ранга: карта из переднего ряда выходит
|
||||
/// в круг защиты, и сила атаки сравнивается с ней; из заднего ряда —
|
||||
/// только если эффект разрешил (InterceptFromBackRow);
|
||||
/// в круг защиты и при атаке по Авангарду, и при атаке по Арьергарду;
|
||||
/// атакованный Арьергард не может перехватить атаку на самого себя;
|
||||
/// из заднего ряда — только если эффект разрешил (InterceptFromBackRow);
|
||||
/// * триггер требует выбора целей через ResolveTriggerCommand:
|
||||
/// +5000 любой карте в кругах Авангарда или Арьергарда, затем второй эффект;
|
||||
/// правило одинаково для drive check и damage check;
|
||||
|
|
@ -373,9 +374,6 @@ public sealed class GameEngine
|
|||
if (State.ActivePlayer != defenderIndex)
|
||||
return CommandResult.Reject("Перехватывает только обороняющийся.");
|
||||
|
||||
if (battle.TargetSlot < 0)
|
||||
return CommandResult.Reject("Перехват возможен только при атаке по Арьергарду.");
|
||||
|
||||
if (battle.Interceptor is not null)
|
||||
return CommandResult.Reject("Перехват уже объявлен.");
|
||||
|
||||
|
|
@ -647,16 +645,17 @@ public sealed class GameEngine
|
|||
|
||||
if (hit)
|
||||
{
|
||||
if (battle.TargetSlot < 0)
|
||||
if (battle.Interceptor is not null)
|
||||
{
|
||||
// перехватчик уже вышел из круга и уйдёт в сброс при закрытии боя,
|
||||
// первоначальная цель (Авангард или Арьергард) не страдает
|
||||
_events.Add(new InterceptorRetiredEvent(defenderIndex, battle.Interceptor.PrintingId));
|
||||
}
|
||||
else if (battle.TargetSlot < 0)
|
||||
{
|
||||
var damage = attackerDef.Critical + attacker.TemporaryCritical;
|
||||
DealDamage(defenderIndex, damage);
|
||||
}
|
||||
else if (battle.Interceptor is not null)
|
||||
{
|
||||
// перехватчик уже вышел из круга и уйдёт в сброс при закрытии боя
|
||||
_events.Add(new InterceptorRetiredEvent(defenderIndex, battle.Interceptor.PrintingId));
|
||||
}
|
||||
else
|
||||
{
|
||||
State.Players[defenderIndex].RearGuards[battle.TargetSlot] = null;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public class GameEngineTests
|
|||
private const string Govannon = "BT01/045EN"; // Draw
|
||||
private const string Iseult = "BT01/011EN"; // Sentinel, Royal Paladin
|
||||
private const string Nehalem = "BT01/022EN"; // Kagero
|
||||
private const string Overlord = "BT01/004EN"; // Kagero, 11000
|
||||
|
||||
[Fact]
|
||||
public void Start_Places_Starting_Vanguard_And_Draws_Five()
|
||||
|
|
@ -382,6 +383,37 @@ public class GameEngineTests
|
|||
Assert.True(engine.Execute(new InterceptCommand(1)).Accepted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Intercept_Works_Against_Vanguard_Attack()
|
||||
{
|
||||
var engine = StartedEngine();
|
||||
engine.Execute(new SkipRideCommand());
|
||||
SetVanguard(engine, 0, Overlord);
|
||||
StackDeck(engine.State.Players[0], Gallatin, Gallatin);
|
||||
engine.Execute(new EnterBattleCommand());
|
||||
|
||||
var defender = engine.State.Players[1];
|
||||
defender.RearGuards[3] = TakeFromDeck(defender, Gallatin);
|
||||
|
||||
Assert.True(engine.Execute(new AttackCommand(-1, -1)).Accepted);
|
||||
Assert.True(engine.Execute(new InterceptCommand(3)).Accepted);
|
||||
Assert.True(engine.Execute(new PassGuardCommand()).Accepted);
|
||||
|
||||
Assert.Empty(defender.Damage);
|
||||
Assert.NotNull(defender.Vanguard);
|
||||
Assert.Contains(defender.Drop, c => c.PrintingId == Gallatin);
|
||||
Assert.Contains(engine.Events, e => e is InterceptorRetiredEvent);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Attacked_RearGuard_Cannot_Intercept_Itself()
|
||||
{
|
||||
var engine = ReadyToAttackRearGuard();
|
||||
|
||||
Assert.True(engine.Execute(new AttackCommand(3, 0)).Accepted);
|
||||
Assert.False(engine.Execute(new InterceptCommand(0)).Accepted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ResolveTrigger_Rejects_When_Nothing_Is_Pending()
|
||||
{
|
||||
|
|
@ -493,7 +525,7 @@ public class GameEngineTests
|
|||
|
||||
private List<string> BuildDeck()
|
||||
{
|
||||
var mustInclude = new[] { Barcgal, Marron, Gallatin, Alfred, Nike, Flogal, Govannon, Iseult, Nehalem };
|
||||
var mustInclude = new[] { Barcgal, Marron, Gallatin, Alfred, Nike, Flogal, Govannon, Iseult, Nehalem, Overlord };
|
||||
var names = mustInclude
|
||||
.Select(_catalog.CardOf)
|
||||
.Select(c => c.NameId)
|
||||
|
|
|
|||
Loading…
Reference in New Issue