121 lines
4.4 KiB
C#
121 lines
4.4 KiB
C#
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Dynamic.ScriptHandling;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Status;
|
|
using PkmnLib.Static.Species;
|
|
using PkmnLib.Static.Utils;
|
|
|
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
|
|
|
/// <summary>
|
|
/// Tests for the <see cref="Hex"/> move script.
|
|
/// Gen VII Bulbapedia behavior: Hex's base power "is 50 and will double to 100 when the target is affected by a
|
|
/// non-volatile status condition"; Generation VI onwards: "Hex's base power was increased to 65 and will double
|
|
/// to 130." Additionally, from the Comatose ability page: "The Pokémon with this Ability takes double damage from
|
|
/// Hex".
|
|
/// </summary>
|
|
public class HexTests
|
|
{
|
|
/// <summary>
|
|
/// Creates a fully mocked test setup where the target has the given (or no) non-volatile status in its
|
|
/// <see cref="IBattlePokemon.StatusScript"/>.
|
|
/// </summary>
|
|
private static (Hex hex, IExecutingMove move, IBattlePokemon target) CreateTestSetup(Script? status)
|
|
{
|
|
var hex = new Hex();
|
|
var move = Substitute.For<IExecutingMove>();
|
|
var target = Substitute.For<IBattlePokemon>();
|
|
target.StatusScript.Returns(status == null ? new ScriptContainer() : new ScriptContainer(status));
|
|
move.User.Returns(Substitute.For<IBattlePokemon>());
|
|
return (hex, move, target);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Every non-volatile status condition implemented in Gen 7.
|
|
/// </summary>
|
|
public static IEnumerable<Func<Script>> NonVolatileStatusScripts()
|
|
{
|
|
yield return () => new Burned();
|
|
yield return () => new Poisoned();
|
|
yield return () => new BadlyPoisoned();
|
|
yield return () => new Paralyzed();
|
|
yield return () => new Frozen();
|
|
yield return () => new Sleep();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: Hex "will double to 130 when the target is affected by a non-volatile status condition."
|
|
/// Every non-volatile status (burn, poison, bad poison, paralysis, freeze, sleep) doubles the base power.
|
|
/// </summary>
|
|
[Test, MethodDataSource(nameof(NonVolatileStatusScripts))]
|
|
public async Task ChangeBasePower_TargetHasNonVolatileStatus_BasePowerDoubles(Script status)
|
|
{
|
|
// Arrange
|
|
var (hex, move, target) = CreateTestSetup(status);
|
|
ushort basePower = 65;
|
|
|
|
// Act
|
|
hex.ChangeBasePower(move, target, 0, ref basePower);
|
|
|
|
// Assert
|
|
await Assert.That(basePower).IsEqualTo((ushort)130);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: the base power only doubles "when the target is affected by a non-volatile status condition" —
|
|
/// against a target with no status the base power is unchanged.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task ChangeBasePower_TargetHasNoStatus_BasePowerUnchanged()
|
|
{
|
|
// Arrange
|
|
var (hex, move, target) = CreateTestSetup(null);
|
|
ushort basePower = 65;
|
|
|
|
// Act
|
|
hex.ChangeBasePower(move, target, 0, ref basePower);
|
|
|
|
// Assert
|
|
await Assert.That(basePower).IsEqualTo((ushort)65);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia (Comatose ability page, Gen VII): "The Pokémon with this Ability takes double damage from Hex" —
|
|
/// a target with <see cref="IBattlePokemon.ActiveAbility"/> Comatose gets the doubled base power even without a
|
|
/// status condition.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task ChangeBasePower_TargetHasComatose_BasePowerDoubles()
|
|
{
|
|
// Arrange
|
|
var (hex, move, target) = CreateTestSetup(null);
|
|
var comatose = Substitute.For<IAbility>();
|
|
comatose.Name.Returns(new StringKey("comatose"));
|
|
target.ActiveAbility.Returns(comatose);
|
|
ushort basePower = 65;
|
|
|
|
// Act
|
|
hex.ChangeBasePower(move, target, 0, ref basePower);
|
|
|
|
// Assert
|
|
await Assert.That(basePower).IsEqualTo((ushort)130);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Technical test: doubling a very large base power clamps at <see cref="ushort.MaxValue"/> instead of
|
|
/// overflowing.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task ChangeBasePower_StatusedTargetWithLargeBasePower_ClampsAtMaxValue()
|
|
{
|
|
// Arrange
|
|
var (hex, move, target) = CreateTestSetup(new Burned());
|
|
ushort basePower = ushort.MaxValue - 100;
|
|
|
|
// Act
|
|
hex.ChangeBasePower(move, target, 0, ref basePower);
|
|
|
|
// Assert
|
|
await Assert.That(basePower).IsEqualTo(ushort.MaxValue);
|
|
}
|
|
} |