using PkmnLib.Dynamic.Models; using PkmnLib.Plugin.Gen7.Scripts.Moves; using PkmnLib.Static; namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves; /// /// Tests for the 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). /// public class GyroBallTests { private static (GyroBall script, IExecutingMove move, IBattlePokemon target) CreateTestSetup(uint userSpeed, uint targetSpeed) { var script = new GyroBall(); var move = Substitute.For(); var user = Substitute.For(); user.BoostedStats.Returns(new StatisticSet(100, 100, 100, 100, 100, userSpeed)); move.User.Returns(user); var target = Substitute.For(); target.BoostedStats.Returns(new StatisticSet(100, 100, 100, 100, 100, targetSpeed)); return (script, move, target); } /// /// Bulbapedia: "BasePower = min(150, 25 × CurrentSpeed(target) / CurrentSpeed(user) + 1)". Various /// speed combinations, including the integer truncation of the division. /// [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); } /// /// Bulbapedia: "The move reaches its maximum base power of 150" — a formula result just above the cap /// is clamped to 150. /// [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); } /// /// 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). /// [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); } /// /// 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." /// [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); } }