160 lines
6.3 KiB
C#
160 lines
6.3 KiB
C#
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Dynamic.ScriptHandling;
|
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
|
using PkmnLib.Static;
|
|
|
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
|
|
|
/// <summary>
|
|
/// Tests for the <see cref="Mist"/> move script and the <see cref="MistEffect"/> side script it places.
|
|
/// Gen VII Bulbapedia behavior (Generation III onwards): "Mist now creates a Mist effect on the user's side
|
|
/// of the field that lasts for five turns. All Pokémon on the user's side of the field are protected while
|
|
/// Mist is active, including Pokémon switched in after it was created." "While Mist is in effect, other
|
|
/// Pokémon (including allies) cannot lower the stats of Pokémon protected by Mist using either moves or
|
|
/// Abilities (e.g. Intimidate)", though it does not prevent self-inflicted stat reductions.
|
|
/// </summary>
|
|
public class MistTests
|
|
{
|
|
/// <summary>
|
|
/// Creates a fully mocked test setup where the user's battle side has a real <see cref="ScriptSet"/> as
|
|
/// its volatile scripts, so the Mist side effect can actually be attached and inspected.
|
|
/// </summary>
|
|
private static (Mist script, IExecutingMove move, IBattleSide side, IScriptSet sideScripts) CreateTestSetup()
|
|
{
|
|
var script = new Mist();
|
|
var move = Substitute.For<IExecutingMove>();
|
|
|
|
var side = Substitute.For<IBattleSide>();
|
|
side.GetScripts().Returns(_ => new ScriptIterator(Array.Empty<IEnumerable<ScriptContainer>>()));
|
|
IScriptSet sideScripts = new ScriptSet(side);
|
|
side.VolatileScripts.Returns(sideScripts);
|
|
|
|
var user = Substitute.For<IBattlePokemon>();
|
|
move.User.Returns(user);
|
|
user.BattleSide.Returns(side);
|
|
|
|
return (script, move, side, sideScripts);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Mist now creates a Mist effect on the user's side of the field that lasts for five
|
|
/// turns." — using the move attaches the <see cref="MistEffect"/> side script to the user's side.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_UserInBattle_AddsMistEffectToUsersSide()
|
|
{
|
|
// Arrange
|
|
var (script, move, _, sideScripts) = CreateTestSetup();
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
|
|
|
|
// Assert
|
|
await Assert.That(sideScripts.Contains(ScriptUtils.ResolveName<MistEffect>())).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "While Mist is in effect, other Pokémon (including allies) cannot lower the stats of
|
|
/// Pokémon protected by Mist using either moves or Abilities (e.g. Intimidate)." — a stat reduction
|
|
/// inflicted by another Pokémon is prevented by the <see cref="MistEffect"/> side script.
|
|
/// </summary>
|
|
[Test, Arguments(Statistic.Attack, (sbyte)-1), Arguments(Statistic.Defense, (sbyte)-2),
|
|
Arguments(Statistic.Speed, (sbyte)-6), Arguments(Statistic.Accuracy, (sbyte)-1)]
|
|
public async Task PreventStatBoostChange_StatLoweredByOpponent_Prevented(Statistic stat, sbyte amount)
|
|
{
|
|
// Arrange
|
|
var effect = new MistEffect();
|
|
var target = Substitute.For<IBattlePokemon>();
|
|
var prevent = false;
|
|
|
|
// Act
|
|
effect.PreventStatBoostChange(target, stat, amount, false, ref prevent);
|
|
|
|
// Assert
|
|
await Assert.That(prevent).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: Mist only stops other Pokémon from being able to "lower the stats of Pokémon protected by
|
|
/// Mist" — stat increases are not affected by Mist.
|
|
/// </summary>
|
|
[Test, Arguments((sbyte)1), Arguments((sbyte)2), Arguments((sbyte)6)]
|
|
public async Task PreventStatBoostChange_StatIncrease_NotPrevented(sbyte amount)
|
|
{
|
|
// Arrange
|
|
var effect = new MistEffect();
|
|
var target = Substitute.For<IBattlePokemon>();
|
|
var prevent = false;
|
|
|
|
// Act
|
|
effect.PreventStatBoostChange(target, Statistic.Attack, amount, false, ref prevent);
|
|
|
|
// Assert
|
|
await Assert.That(prevent).IsFalse();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Technical test: a stat change of zero stages is not a stat reduction, so Mist does not prevent it.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task PreventStatBoostChange_ZeroChange_NotPrevented()
|
|
{
|
|
// Arrange
|
|
var effect = new MistEffect();
|
|
var target = Substitute.For<IBattlePokemon>();
|
|
var prevent = false;
|
|
|
|
// Act
|
|
effect.PreventStatBoostChange(target, Statistic.Attack, 0, false, ref prevent);
|
|
|
|
// Assert
|
|
await Assert.That(prevent).IsFalse();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "While Mist is in effect, other Pokémon (including allies) cannot lower the stats of
|
|
/// Pokémon protected by Mist" — Mist does not prevent self-inflicted stat reductions (such as the
|
|
/// Defense/Special Defense drops from the protected Pokémon's own Superpower or Close Combat).
|
|
/// </summary>
|
|
[Test]
|
|
public async Task PreventStatBoostChange_SelfInflictedReduction_NotPrevented()
|
|
{
|
|
// Arrange
|
|
var effect = new MistEffect();
|
|
var target = Substitute.For<IBattlePokemon>();
|
|
var prevent = false;
|
|
|
|
// Act
|
|
effect.PreventStatBoostChange(target, Statistic.Defense, -1, true, ref prevent);
|
|
|
|
// Assert
|
|
await Assert.That(prevent).IsFalse();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Mist now creates a Mist effect on the user's side of the field that lasts for five
|
|
/// turns." — after five end-of-turn ticks the <see cref="MistEffect"/> removes itself from the side.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task MistEffect_AfterFiveEndOfTurns_EffectExpires()
|
|
{
|
|
// Arrange
|
|
var (script, move, side, sideScripts) = CreateTestSetup();
|
|
script.OnSecondaryEffect(move, Substitute.For<IBattlePokemon>(), 0);
|
|
var effect = sideScripts.Get<MistEffect>();
|
|
await Assert.That(effect).IsNotNull();
|
|
|
|
// Act - five turns pass
|
|
var battle = Substitute.For<IBattle>();
|
|
if (effect is IScriptOnEndTurn endTurn)
|
|
{
|
|
for (var i = 0; i < 5; i++)
|
|
endTurn.OnEndTurn(side, battle);
|
|
}
|
|
|
|
// Assert
|
|
await Assert.That(sideScripts.Contains(ScriptUtils.ResolveName<MistEffect>())).IsFalse();
|
|
}
|
|
} |