181 lines
6.8 KiB
C#
181 lines
6.8 KiB
C#
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Dynamic.Models.Choices;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|
using PkmnLib.Static.Species;
|
|
using PkmnLib.Static.Utils;
|
|
|
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
|
|
|
/// <summary>
|
|
/// Tests for the <see cref="CoreEnforcer"/> move script.
|
|
/// Gen VII Bulbapedia behavior: "Core Enforcer deals damage. If the target has already used a move or had
|
|
/// a Bag item used on it by its Trainer in the same turn, Core Enforcer also suppresses the target's
|
|
/// Ability while it remains in battle."
|
|
/// </summary>
|
|
public class CoreEnforcerTests
|
|
{
|
|
private static (CoreEnforcer script, IExecutingMove move, IMoveChoice currentChoice, IPokemon target, IHitData
|
|
hitData, IBattle battle) CreateTestSetup()
|
|
{
|
|
var script = new CoreEnforcer();
|
|
var battle = Substitute.For<IBattle>();
|
|
var battleData = Substitute.For<IPokemonBattleData>();
|
|
battleData.Battle.Returns(battle);
|
|
var target = Substitute.For<IPokemon>();
|
|
target.BattleData.Returns(battleData);
|
|
|
|
var currentChoice = Substitute.For<IMoveChoice>();
|
|
var move = Substitute.For<IExecutingMove>();
|
|
move.MoveChoice.Returns(currentChoice);
|
|
var hitData = Substitute.For<IHitData>();
|
|
move.GetHitData(target, 0).Returns(hitData);
|
|
|
|
return (script, move, currentChoice, target, hitData, battle);
|
|
}
|
|
|
|
private static void SetTurnChoices(IBattle battle, params ITurnChoice[] choices)
|
|
{
|
|
battle.PreviousTurnChoices.Returns(new List<IReadOnlyList<ITurnChoice>> { choices });
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "If the target has already used a move [...] in the same turn, Core Enforcer also
|
|
/// suppresses the target's Ability while it remains in battle."
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_TargetMovedEarlierInTurn_SuppressesTargetAbility()
|
|
{
|
|
// Arrange
|
|
var (script, move, currentChoice, target, hitData, battle) = CreateTestSetup();
|
|
var targetChoice = Substitute.For<IMoveChoice>();
|
|
targetChoice.User.Returns(target);
|
|
SetTurnChoices(battle, targetChoice, currentChoice);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
target.Received(1).SuppressAbility();
|
|
hitData.DidNotReceive().Fail();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: the suppression also happens if the target "had a Bag item used on it by its Trainer in
|
|
/// the same turn".
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_ItemUsedEarlierInTurn_SuppressesTargetAbility()
|
|
{
|
|
// Arrange
|
|
var (script, move, currentChoice, target, hitData, battle) = CreateTestSetup();
|
|
var itemChoice = Substitute.For<IItemChoice>();
|
|
itemChoice.User.Returns(target);
|
|
SetTurnChoices(battle, itemChoice, currentChoice);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
target.Received(1).SuppressAbility();
|
|
hitData.DidNotReceive().Fail();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: the Ability is only suppressed "If the target has already used a move [...] in the same
|
|
/// turn" — when Core Enforcer strikes before the target has acted, no suppression happens.
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_TargetActsLaterInTurn_DoesNotSuppressAbility()
|
|
{
|
|
// Arrange
|
|
var (script, move, currentChoice, target, hitData, battle) = CreateTestSetup();
|
|
var targetChoice = Substitute.For<IMoveChoice>();
|
|
targetChoice.User.Returns(target);
|
|
SetTurnChoices(battle, currentChoice, targetChoice);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
target.DidNotReceive().SuppressAbility();
|
|
hitData.Received(1).Fail();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: suppression requires the target to have already acted — as the very first action of the
|
|
/// turn, Core Enforcer never suppresses.
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_CoreEnforcerIsFirstActionOfTurn_DoesNotSuppressAbility()
|
|
{
|
|
// Arrange
|
|
var (script, move, currentChoice, target, hitData, battle) = CreateTestSetup();
|
|
SetTurnChoices(battle, currentChoice);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
target.DidNotReceive().SuppressAbility();
|
|
hitData.Received(1).Fail();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Technical test: a target without battle data (not in battle) is left untouched.
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_TargetHasNoBattleData_DoesNothing()
|
|
{
|
|
// Arrange
|
|
var (script, move, _, target, hitData, _) = CreateTestSetup();
|
|
target.BattleData.Returns((IPokemonBattleData?)null);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
target.DidNotReceive().SuppressAbility();
|
|
hitData.DidNotReceive().Fail();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: the condition is that "the target has already used a move" — an action by a different
|
|
/// Pokémon (e.g. the user's ally in a Double Battle) does not count as the target having acted.
|
|
/// </summary>
|
|
[Test]
|
|
public void OnSecondaryEffect_OnlyOtherPokemonActedEarlier_DoesNotSuppressAbility()
|
|
{
|
|
// Arrange
|
|
var (script, move, currentChoice, target, hitData, battle) = CreateTestSetup();
|
|
var allyChoice = Substitute.For<IMoveChoice>();
|
|
allyChoice.User.Returns(Substitute.For<IPokemon>());
|
|
SetTurnChoices(battle, allyChoice, currentChoice);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
target.DidNotReceive().SuppressAbility();
|
|
hitData.Received(1).Fail();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "The move cannot suppress certain signature abilities including Multitype, Stance
|
|
/// Change, Schooling, Comatose, Shields Down, Disguise, RKS System, Battle Bond, Power Construct".
|
|
/// The script requests the suppression unconditionally; <see cref="IPokemon.SuppressAbility"/> refuses
|
|
/// it when <see cref="IAbility.CanBeChanged"/> is false, so these abilities must carry that flag in the
|
|
/// Gen7 data.
|
|
/// </summary>
|
|
[Test, Arguments("multitype"), Arguments("stance_change"), Arguments("schooling"), Arguments("comatose"),
|
|
Arguments("shields_down"), Arguments("disguise"), Arguments("rks_system"), Arguments("battle_bond"),
|
|
Arguments("power_construct")]
|
|
public async Task OnSecondaryEffect_UnsuppressableAbility_IsProtectedByAbilityData(string abilityName)
|
|
{
|
|
// Arrange
|
|
var library = LibraryHelpers.LoadLibrary();
|
|
|
|
// Assert
|
|
await Assert.That(library.StaticLibrary.Abilities.TryGet(new StringKey(abilityName), out var ability)).IsTrue();
|
|
await Assert.That(ability!.CanBeChanged).IsFalse();
|
|
}
|
|
} |