123 lines
4.9 KiB
C#
123 lines
4.9 KiB
C#
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|
using PkmnLib.Static;
|
|
|
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
|
|
|
/// <summary>
|
|
/// Tests for the <see cref="GuardSplit"/> move script.
|
|
/// Gen VII Bulbapedia behavior: "Guard Split averages the user's Defense and Special Defense stats with
|
|
/// those of the target Pokémon." and "Both the user's and the target's stat changes are ignored when
|
|
/// calculating the average." (the calculation therefore uses the flat, unboosted stats).
|
|
/// </summary>
|
|
public class GuardSplitTests
|
|
{
|
|
private static (GuardSplit script, IExecutingMove move, IBattlePokemon user, IBattlePokemon target) CreateTestSetup(
|
|
uint userDefense, uint userSpecialDefense, uint targetDefense, uint targetSpecialDefense)
|
|
{
|
|
var script = new GuardSplit();
|
|
var move = Substitute.For<IExecutingMove>();
|
|
|
|
var user = Substitute.For<IBattlePokemon>();
|
|
user.FlatStats.Returns(new StatisticSet<uint>(100, 100, userDefense, 100, userSpecialDefense, 100));
|
|
move.User.Returns(user);
|
|
|
|
var target = Substitute.For<IBattlePokemon>();
|
|
target.FlatStats.Returns(new StatisticSet<uint>(100, 100, targetDefense, 100, targetSpecialDefense, 100));
|
|
|
|
return (script, move, user, target);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Guard Split averages the user's Defense and Special Defense stats with those of the
|
|
/// target Pokémon." — both Pokémon end up with the averaged Defense value.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_DifferentDefenseStats_BothGetAveragedDefense()
|
|
{
|
|
// Arrange
|
|
var (script, move, user, target) = CreateTestSetup(40, 100, 60, 100);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
await Assert.That(user.FlatStats.GetStatistic(Statistic.Defense)).IsEqualTo(50u);
|
|
await Assert.That(target.FlatStats.GetStatistic(Statistic.Defense)).IsEqualTo(50u);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: the averaging also covers "Special Defense" — both Pokémon end up with the averaged
|
|
/// Special Defense value.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_DifferentSpecialDefenseStats_BothGetAveragedSpecialDefense()
|
|
{
|
|
// Arrange
|
|
var (script, move, user, target) = CreateTestSetup(100, 80, 100, 120);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
await Assert.That(user.FlatStats.GetStatistic(Statistic.SpecialDefense)).IsEqualTo(100u);
|
|
await Assert.That(target.FlatStats.GetStatistic(Statistic.SpecialDefense)).IsEqualTo(100u);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The average of an odd sum is truncated by integer division, matching the games' integer stat
|
|
/// arithmetic.
|
|
/// </summary>
|
|
[Test, Arguments(35u, 40u, 37u), Arguments(1u, 2u, 1u), Arguments(99u, 100u, 99u)]
|
|
public async Task OnSecondaryEffect_OddDefenseSum_AverageIsTruncated(uint userDefense, uint targetDefense,
|
|
uint expectedAverage)
|
|
{
|
|
// Arrange
|
|
var (script, move, user, target) = CreateTestSetup(userDefense, 100, targetDefense, 100);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
await Assert.That(user.FlatStats.GetStatistic(Statistic.Defense)).IsEqualTo(expectedAverage);
|
|
await Assert.That(target.FlatStats.GetStatistic(Statistic.Defense)).IsEqualTo(expectedAverage);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: only Defense and Special Defense are averaged — the other stats are left untouched.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_Always_OtherStatsUnchanged()
|
|
{
|
|
// Arrange
|
|
var (script, move, user, target) = CreateTestSetup(40, 80, 60, 120);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
await Assert.That(user.FlatStats.GetStatistic(Statistic.Attack)).IsEqualTo(100u);
|
|
await Assert.That(user.FlatStats.GetStatistic(Statistic.SpecialAttack)).IsEqualTo(100u);
|
|
await Assert.That(user.FlatStats.GetStatistic(Statistic.Speed)).IsEqualTo(100u);
|
|
await Assert.That(user.FlatStats.GetStatistic(Statistic.Hp)).IsEqualTo(100u);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The changed flat stats must be propagated to the effective in-battle stats — both Pokémon get
|
|
/// their boosted stats recalculated.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_Always_RecalculatesBoostedStatsOnBothPokemon()
|
|
{
|
|
// Arrange
|
|
var (script, move, user, target) = CreateTestSetup(40, 80, 60, 120);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
user.Received(1).RecalculateBoostedStats();
|
|
target.Received(1).RecalculateBoostedStats();
|
|
await Assert.That(user.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "RecalculateBoostedStats")).IsTrue();
|
|
}
|
|
} |