142 lines
5.3 KiB
C#
142 lines
5.3 KiB
C#
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Dynamic.Models.Choices;
|
|
using PkmnLib.Dynamic.ScriptHandling;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Moves;
|
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
|
using PkmnLib.Static.Moves;
|
|
using PkmnLib.Static.Utils;
|
|
|
|
namespace PkmnLib.Plugin.Gen7.Tests.Scripts.Moves;
|
|
|
|
/// <summary>
|
|
/// Tests for the <see cref="Imprison"/> move script and its <see cref="ImprisonEffect"/> volatile.
|
|
/// Gen VII Bulbapedia behavior: "As long as the user remains in battle, opponents cannot use any move which
|
|
/// is also known by the user. This includes opponents switched in after the move was used". Generation V
|
|
/// onwards: "Imprison still works even if no opponent has a move the user knows."
|
|
/// </summary>
|
|
public class ImprisonTests
|
|
{
|
|
/// <summary>
|
|
/// Creates a substitute learned move whose <see cref="IMoveData.Name"/> is the given name.
|
|
/// </summary>
|
|
private static ILearnedMove CreateLearnedMove(string name)
|
|
{
|
|
var moveData = Substitute.For<IMoveData>();
|
|
moveData.Name.Returns(new StringKey(name));
|
|
var learnedMove = Substitute.For<ILearnedMove>();
|
|
learnedMove.MoveData.Returns(moveData);
|
|
return learnedMove;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates the Pokémon that used Imprison, knowing the given moves (with an empty move slot, as real
|
|
/// movesets can have them), and the <see cref="ImprisonEffect"/> bound to it.
|
|
/// </summary>
|
|
private static (ImprisonEffect effect, IBattlePokemon user) CreateImprisonUser(params string[] knownMoves)
|
|
{
|
|
var user = Substitute.For<IBattlePokemon>();
|
|
var moves = knownMoves.Select(ILearnedMove? (m) => CreateLearnedMove(m)).Append(null).ToArray();
|
|
user.Moves.Returns(moves);
|
|
return (new ImprisonEffect(user), user);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a move choice by the given Pokémon for a move with the given name.
|
|
/// </summary>
|
|
private static IMoveChoice CreateMoveChoice(IBattlePokemon chooser, string moveName)
|
|
{
|
|
var choice = Substitute.For<IMoveChoice>();
|
|
choice.User.Returns(chooser);
|
|
var learnedMove = CreateLearnedMove(moveName);
|
|
choice.ChosenMove.Returns(learnedMove);
|
|
return choice;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "As long as the user remains in battle, opponents cannot use any move which is also known
|
|
/// by the user." This includes opponents switched in after the move was used, so using the move puts the
|
|
/// <see cref="ImprisonEffect"/> on the battle's volatile scripts, where every move choice sees it.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task OnSecondaryEffect_Used_AddsImprisonEffectToBattleVolatile()
|
|
{
|
|
// Arrange
|
|
var script = new Imprison();
|
|
var move = Substitute.For<IExecutingMove>();
|
|
var user = Substitute.For<IBattlePokemon>();
|
|
move.User.Returns(user);
|
|
var target = Substitute.For<IBattlePokemon>();
|
|
|
|
var battle = Substitute.For<IBattle>();
|
|
battle.GetScripts().Returns(_ => new ScriptIterator(Array.Empty<IEnumerable<ScriptContainer>>()));
|
|
var battleVolatile = new ScriptSet(battle);
|
|
battle.Volatile.Returns(battleVolatile);
|
|
|
|
target.Battle.Returns(battle);
|
|
|
|
// Act
|
|
script.OnSecondaryEffect(move, target, 0);
|
|
|
|
// Assert
|
|
await Assert.That(battleVolatile.Get<ImprisonEffect>()).IsNotNull();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "opponents cannot use any move which is also known by the user." An opponent choosing a
|
|
/// move the Imprison user knows has its selection prevented.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task PreventMoveSelection_OpponentChoosesMoveKnownByUser_SelectionPrevented()
|
|
{
|
|
// Arrange
|
|
var (effect, _) = CreateImprisonUser("tackle", "imprison");
|
|
var opponent = Substitute.For<IBattlePokemon>();
|
|
var choice = CreateMoveChoice(opponent, "tackle");
|
|
var prevent = false;
|
|
|
|
// Act
|
|
effect.PreventMoveSelection(choice, ref prevent);
|
|
|
|
// Assert
|
|
await Assert.That(prevent).IsTrue();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: only moves "also known by the user" are sealed. An opponent choosing a move the Imprison
|
|
/// user does not know is free to use it.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task PreventMoveSelection_OpponentChoosesMoveNotKnownByUser_SelectionAllowed()
|
|
{
|
|
// Arrange
|
|
var (effect, _) = CreateImprisonUser("tackle", "imprison");
|
|
var opponent = Substitute.For<IBattlePokemon>();
|
|
var choice = CreateMoveChoice(opponent, "ember");
|
|
var prevent = false;
|
|
|
|
// Act
|
|
effect.PreventMoveSelection(choice, ref prevent);
|
|
|
|
// Assert
|
|
await Assert.That(prevent).IsFalse();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bulbapedia: "opponents cannot use any move which is also known by the user" — the user itself is not
|
|
/// restricted and can keep using its own moves.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task PreventMoveSelection_UsersOwnChoice_SelectionAllowed()
|
|
{
|
|
// Arrange
|
|
var (effect, user) = CreateImprisonUser("tackle", "imprison");
|
|
var choice = CreateMoveChoice(user, "tackle");
|
|
var prevent = false;
|
|
|
|
// Act
|
|
effect.PreventMoveSelection(choice, ref prevent);
|
|
|
|
// Assert
|
|
await Assert.That(prevent).IsFalse();
|
|
}
|
|
} |