156 lines
5.9 KiB
C#
156 lines
5.9 KiB
C#
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Dynamic.ScriptHandling;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Battle;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|
using PkmnLib.Static;
|
|
|
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
|
|
|
/// <summary>
|
|
/// Tests for the <see cref="MagicRoom"/> move script and the <see cref="MagicRoomEffect"/> battle volatile it
|
|
/// applies. Gen VII Bulbapedia behavior: "Magic Room suppresses the effect of all items held by the Pokémon on
|
|
/// the field. This effect lasts for five turns." Using the move again while active removes the effect
|
|
/// immediately.
|
|
/// </summary>
|
|
public class MagicRoomTests
|
|
{
|
|
/// <summary>
|
|
/// Creates a fully mocked test setup for Magic Room tests. The battle gets a real
|
|
/// <see cref="ScriptSet"/> as its volatile set, so the applied effect can be inspected.
|
|
/// </summary>
|
|
private static (MagicRoom script, IExecutingMove move, IBattlePokemon target, IBattle battle, IScriptSet
|
|
battleVolatile) CreateTestSetup()
|
|
{
|
|
var script = new MagicRoom();
|
|
var move = Substitute.For<IExecutingMove>();
|
|
var target = Substitute.For<IBattlePokemon>();
|
|
|
|
var battle = Substitute.For<IBattle>();
|
|
battle.GetScripts().Returns(_ => new ScriptIterator(new List<IEnumerable<ScriptContainer>>()));
|
|
var battleVolatile = new ScriptSet(battle);
|
|
battle.Volatile.Returns(battleVolatile);
|
|
|
|
var user = Substitute.For<IBattlePokemon>();
|
|
move.User.Returns(user);
|
|
user.Battle.Returns(battle);
|
|
|
|
return (script, move, target, battle, battleVolatile);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Magic Room suppresses the effect of all items held by the Pokémon on the field."
|
|
/// The move script applies the <see cref="MagicRoomEffect"/> volatile, which implements the item
|
|
/// suppression, to the battle.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_MoveUsed_AddsMagicRoomEffectToBattleVolatile()
|
|
{
|
|
// Arrange
|
|
var (script, move, target, _, battleVolatile) = CreateTestSetup();
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
await Assert.That(battleVolatile.Get<MagicRoomEffect>()).IsNotNull();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "If Magic Room is used while it is already in effect, it will end immediately."
|
|
/// Using the move a second time must remove the active effect from the battle instead of leaving it in
|
|
/// place.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_UsedWhileActive_RemovesEffectImmediately()
|
|
{
|
|
// Arrange
|
|
var (script, move, target, _, battleVolatile) = CreateTestSetup();
|
|
|
|
// Act - second use while the effect is active
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
await Assert.That(battleVolatile.Contains("magic_room")).IsFalse();
|
|
}
|
|
|
|
// ----- MagicRoomEffect behavior (the volatile the move applies) -----
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Magic Room suppresses the effect of all items held by the Pokémon on the field."
|
|
/// While the effect is active no Pokémon can consume its held item.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task PreventHeldItemConsume_MagicRoomActive_ItemConsumptionPrevented()
|
|
{
|
|
// Arrange
|
|
var effect = new MagicRoomEffect();
|
|
var pokemon = Substitute.For<IBattlePokemon>();
|
|
var item = Substitute.For<IItem>();
|
|
var prevented = false;
|
|
|
|
// Act
|
|
effect.PreventHeldItemConsume(pokemon, item, ref prevented);
|
|
|
|
// Assert
|
|
await Assert.That(prevented).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Magic Room suppresses the effect of all items held by the Pokémon on the field."
|
|
/// The effect suppresses all item battle trigger scripts while active.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnBeforeAnyHookInvoked_NullCategoryList_SuppressesItemBattleTriggers()
|
|
{
|
|
// Arrange
|
|
var effect = new MagicRoomEffect();
|
|
List<ScriptCategory>? suppressedCategories = null;
|
|
|
|
// Act
|
|
effect.OnBeforeAnyHookInvoked(ref suppressedCategories);
|
|
|
|
// Assert
|
|
await Assert.That(suppressedCategories).IsNotNull();
|
|
await Assert.That(suppressedCategories!.Contains(ScriptCategory.ItemBattleTrigger)).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "Magic Room suppresses the effect of all items held by the Pokémon on the field."
|
|
/// When other suppressions are already present, the item suppression is added to the existing list.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnBeforeAnyHookInvoked_ExistingCategoryList_AddsItemBattleTriggerSuppression()
|
|
{
|
|
// Arrange
|
|
var effect = new MagicRoomEffect();
|
|
List<ScriptCategory>? suppressedCategories = [ScriptCategory.Weather];
|
|
|
|
// Act
|
|
effect.OnBeforeAnyHookInvoked(ref suppressedCategories);
|
|
|
|
// Assert
|
|
await Assert.That(suppressedCategories!.Contains(ScriptCategory.ItemBattleTrigger)).IsTrue();
|
|
await Assert.That(suppressedCategories!.Contains(ScriptCategory.Weather)).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "This effect lasts for five turns." The turn Magic Room is used counts as the first turn,
|
|
/// so after five end-of-turn ticks the effect must have removed itself from the battle.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnEndTurn_AfterFiveEndOfTurns_EffectHasEnded()
|
|
{
|
|
// Arrange
|
|
var (script, move, target, battle, battleVolatile) = CreateTestSetup();
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
var effect = battleVolatile.Get<MagicRoomEffect>()!;
|
|
|
|
// Act - five end-of-turn ticks, the duration of the effect
|
|
for (var i = 0; i < 5; i++)
|
|
effect.OnEndTurn(battle, battle);
|
|
|
|
// Assert
|
|
await Assert.That(battleVolatile.Contains("magic_room")).IsFalse();
|
|
}
|
|
} |