108 lines
3.7 KiB
C#
108 lines
3.7 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="GyroBall"/> move script.
|
||
/// Gen VII Bulbapedia behavior: "Gyro Ball inflicts more damage the slower the user is compared to the
|
||
/// target", with base power = min(150, 25 × target Speed / user Speed + 1).
|
||
/// </summary>
|
||
public class GyroBallTests
|
||
{
|
||
private static (GyroBall script, IExecutingMove move, IPokemon target) CreateTestSetup(uint userSpeed,
|
||
uint targetSpeed)
|
||
{
|
||
var script = new GyroBall();
|
||
var move = Substitute.For<IExecutingMove>();
|
||
|
||
var user = Substitute.For<IPokemon>();
|
||
user.BoostedStats.Returns(new StatisticSet<uint>(100, 100, 100, 100, 100, userSpeed));
|
||
move.User.Returns(user);
|
||
|
||
var target = Substitute.For<IPokemon>();
|
||
target.BoostedStats.Returns(new StatisticSet<uint>(100, 100, 100, 100, 100, targetSpeed));
|
||
|
||
return (script, move, target);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Bulbapedia: "BasePower = min(150, 25 × CurrentSpeed(target) / CurrentSpeed(user) + 1)". Various
|
||
/// speed combinations, including the integer truncation of the division.
|
||
/// </summary>
|
||
[Test, Arguments(100u, 100u, (ushort)26), Arguments(100u, 50u, (ushort)13), Arguments(100u, 1u, (ushort)1),
|
||
Arguments(50u, 200u, (ushort)101)]
|
||
// 25 * 100 / 100 + 1
|
||
// 25 * 50 / 100 = 12 (truncated) + 1
|
||
// 25 * 1 / 100 = 0 (truncated) + 1
|
||
// 25 * 200 / 50 + 1
|
||
public async Task ChangeBasePower_SpeedComparison_FollowsFormula(uint userSpeed, uint targetSpeed,
|
||
ushort expectedPower)
|
||
{
|
||
// Arrange
|
||
var (script, move, target) = CreateTestSetup(userSpeed, targetSpeed);
|
||
ushort basePower = 5;
|
||
|
||
// Act
|
||
script.ChangeBasePower(move, target, 0, ref basePower);
|
||
|
||
// Assert
|
||
await Assert.That(basePower).IsEqualTo(expectedPower);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Bulbapedia: "The move reaches its maximum base power of 150" — a formula result just above the cap
|
||
/// is clamped to 150.
|
||
/// </summary>
|
||
[Test]
|
||
public async Task ChangeBasePower_FormulaExceedsCap_BasePowerCappedAt150()
|
||
{
|
||
// Arrange - 25 * 60 / 10 + 1 = 151
|
||
var (script, move, target) = CreateTestSetup(10, 60);
|
||
ushort basePower = 5;
|
||
|
||
// Act
|
||
script.ChangeBasePower(move, target, 0, ref basePower);
|
||
|
||
// Assert
|
||
await Assert.That(basePower).IsEqualTo((ushort)150);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Bulbapedia: the base power is capped at 150 for any speed ratio. The implementation truncates the
|
||
/// formula result to a byte before applying the cap, so results above 255 wrap around and produce a
|
||
/// wrong power (25 × 100 / 4 + 1 = 626 wraps to 114).
|
||
/// </summary>
|
||
[Test]
|
||
public async Task ChangeBasePower_FormulaFarExceedsByteRange_BasePowerCappedAt150()
|
||
{
|
||
// Arrange - 25 * 100 / 4 + 1 = 626
|
||
var (script, move, target) = CreateTestSetup(4, 100);
|
||
ushort basePower = 5;
|
||
|
||
// Act
|
||
script.ChangeBasePower(move, target, 0, ref basePower);
|
||
|
||
// Assert
|
||
await Assert.That(basePower).IsEqualTo((ushort)150);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Bulbapedia (Generation VI onwards): "If the user of Gyro Ball has a Speed stat that rounds down to
|
||
/// 0, the move's power is set to 1."
|
||
/// </summary>
|
||
[Test]
|
||
public async Task ChangeBasePower_UserSpeedIsZero_BasePowerIsOne()
|
||
{
|
||
// Arrange
|
||
var (script, move, target) = CreateTestSetup(0, 100);
|
||
ushort basePower = 5;
|
||
|
||
// Act
|
||
script.ChangeBasePower(move, target, 0, ref basePower);
|
||
|
||
// Assert
|
||
await Assert.That(basePower).IsEqualTo((ushort)1);
|
||
}
|
||
} |