Move all battle state from IPokemon to an ephemeral IBattlePokemon wrapper

This commit is contained in:
2026-08-28 15:20:26 +02:00
parent 942be8eaeb
commit 8a2733a0a9
859 changed files with 4408 additions and 5331 deletions

View File

@@ -22,13 +22,13 @@ public class KingsShieldTests
/// Pokémon using King's Shield itself, as the move is self-targeted, so the returned <c>user</c> is
/// passed as both the move's user and the secondary effect's target.
/// </summary>
private static (KingsShield script, IExecutingMove move, IPokemon user, IHitData hitData, IScriptSet volatileSet,
IForm defaultForm) CreateProtectSetup(bool userMovesLast = false, float randomRoll = 0.0f,
private static (KingsShield script, IExecutingMove move, IBattlePokemon user, IHitData hitData, IScriptSet
volatileSet, IForm defaultForm) CreateProtectSetup(bool userMovesLast = false, float randomRoll = 0.0f,
string speciesName = "mimikyu", string formName = "default")
{
var script = new KingsShield();
var move = Substitute.For<IExecutingMove>();
var user = Substitute.For<IPokemon>();
var user = Substitute.For<IBattlePokemon>();
var hitData = Substitute.For<IHitData>();
// Mirror the real HitData behavior: once Fail() is called, HasFailed reports true.
hitData.When(h => h.Fail()).Do(_ => hitData.HasFailed.Returns(true));
@@ -56,9 +56,7 @@ public class KingsShieldTests
battle.ChoiceQueue.Returns(queue);
battle.Random.Returns(random);
var battleData = Substitute.For<IPokemonBattleData>();
battleData.Battle.Returns(battle);
user.BattleData.Returns(battleData);
user.Battle.Returns(battle);
// Give the mock a real script iterator (used by the volatile add hook) and a real volatile script set.
user.GetScripts().Returns(_ => new ScriptIterator([]));
@@ -72,12 +70,12 @@ public class KingsShieldTests
/// Creates a fully mocked setup for driving <see cref="KingsShieldEffect.BlockIncomingHit"/>, the
/// volatile script that King's Shield attaches to its user.
/// </summary>
private static (KingsShieldEffect effect, IExecutingMove move, IPokemon target, IPokemon attacker) CreateBlockSetup(
bool isContact, bool hasProtectFlag, MoveCategory category = MoveCategory.Physical)
private static (KingsShieldEffect effect, IExecutingMove move, IBattlePokemon target, IBattlePokemon attacker)
CreateBlockSetup(bool isContact, bool hasProtectFlag, MoveCategory category = MoveCategory.Physical)
{
var effect = new KingsShieldEffect();
var move = Substitute.For<IExecutingMove>();
var target = Substitute.For<IPokemon>();
var target = Substitute.For<IBattlePokemon>();
var hitData = Substitute.For<IHitData>();
hitData.IsContact.Returns(isContact);
move.GetHitData(target, 0).Returns(hitData);
@@ -87,29 +85,27 @@ public class KingsShieldTests
useMove.Category.Returns(category);
move.UseMove.Returns(useMove);
var attacker = Substitute.For<IPokemon>();
var attacker = Substitute.For<IBattlePokemon>();
attacker.GetScripts().Returns(_ => new ScriptIterator(Array.Empty<IEnumerable<ScriptContainer>>()));
move.User.Returns(attacker);
target.BattleData.Returns(Substitute.For<IPokemonBattleData>());
return (effect, move, target, attacker);
}
/// <summary>
/// Helper to extract the statistic and stage change from a Pokémon's received
/// <see cref="IPokemon.ChangeStatBoost"/> calls.
/// <see cref="IBattlePokemon.ChangeStatBoost"/> calls.
/// </summary>
private static (Statistic stat, sbyte change)? GetStatBoostCall(IPokemon pokemon)
private static (Statistic stat, sbyte change)? GetStatBoostCall(IBattlePokemon pokemon)
{
var call = pokemon.ReceivedCalls().FirstOrDefault(c => c.GetMethodInfo().Name == "ChangeStatBoost");
return call != null ? ((Statistic)call.GetArguments()[0]!, (sbyte)call.GetArguments()[1]!) : null;
}
/// <summary>
/// Helper that checks whether a Pokémon received a <see cref="IPokemon.ChangeForm"/> call.
/// Helper that checks whether a Pokémon received a <see cref="IBattlePokemon.ChangeForm"/> call.
/// </summary>
private static bool ReceivedChangeForm(IPokemon pokemon) =>
private static bool ReceivedChangeForm(IBattlePokemon pokemon) =>
pokemon.ReceivedCalls().Any(c => c.GetMethodInfo().Name == "ChangeForm");
/// <summary>