Adds effects for after you, assist, and attract
This commit is contained in:
parent
eb9a30bd41
commit
6f2bd678a5
@ -77,6 +77,9 @@ public class BattleChoiceQueue
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This moves the choice of a specific Pokémon up to the next choice to be executed.
|
/// This moves the choice of a specific Pokémon up to the next choice to be executed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// Returns true if the Pokémon was found and moved, false otherwise.
|
||||||
|
/// </returns>
|
||||||
public bool MovePokemonChoiceNext(IPokemon pokemon)
|
public bool MovePokemonChoiceNext(IPokemon pokemon)
|
||||||
{
|
{
|
||||||
var index = Array.FindIndex(_choices, _currentIndex, choice => choice?.User == pokemon);
|
var index = Array.FindIndex(_choices, _currentIndex, choice => choice?.User == pokemon);
|
||||||
|
32
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/AfterYou.cs
Normal file
32
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/AfterYou.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Moves;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The user helps the target and makes it use its move right after the user.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The target will move next on the current turn, ignoring priority. After You bypasses accuracy checks to always hit,
|
||||||
|
/// unless the target is in the semi-invulnerable turn of a move such as Dig or Fly. It fails if the target has already
|
||||||
|
/// moved on the same turn. After You ignores the effects of Quash.
|
||||||
|
/// After You fails if the order remains the same after using After You.
|
||||||
|
/// </remarks>
|
||||||
|
[Script(ScriptCategory.Move, "after_you")]
|
||||||
|
public class AfterYou : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var queue = move.User.BattleData!.Battle.ChoiceQueue;
|
||||||
|
if (queue == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If the queue doesn't change, the move fails
|
||||||
|
if (!queue.MovePokemonChoiceNext(target))
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
62
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Assist.cs
Normal file
62
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Assist.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.Models.Choices;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Utils;
|
||||||
|
using PkmnLib.Static.Moves;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Moves;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The user hurriedly and randomly uses a move among those known by ally Pokémon.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The Assist user executes a move that is randomly selected from all the eligible moves known by other Pokémon in the
|
||||||
|
/// same party. If the same move is known by multiple Pokémon, each of them counts and therefore the move is more likely
|
||||||
|
/// to be called. Assist can call a move that currently has no PP or is known by a fainted Pokémon. It is also able to
|
||||||
|
/// call moves that are currently inaccessible to their original users due to Disable, Heal Block, Taunt, or Torment.
|
||||||
|
/// If the other Pokémon in the user's party do not know any eligible moves, Assist fails.
|
||||||
|
/// </remarks>
|
||||||
|
[Script(ScriptCategory.Move, "assist")]
|
||||||
|
public class Assist : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeMove(IMoveChoice choice, ref StringKey moveName)
|
||||||
|
{
|
||||||
|
var user = choice.User;
|
||||||
|
if (user.BattleData == null)
|
||||||
|
return;
|
||||||
|
var battle = user.BattleData.Battle;
|
||||||
|
var party = battle.Parties.FirstOrDefault(p => p.Party.Contains(user));
|
||||||
|
if (party == null)
|
||||||
|
{
|
||||||
|
choice.Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var moves = GetPartyMoves(party.Party, user).ToList();
|
||||||
|
if (moves.Count == 0)
|
||||||
|
{
|
||||||
|
choice.Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var random = battle.Random.GetInt(moves.Count);
|
||||||
|
moveName = moves[random].Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<IMoveData> GetPartyMoves(IPokemonParty party, IPokemon user)
|
||||||
|
{
|
||||||
|
foreach (var pokemon in party.WhereNotNull())
|
||||||
|
{
|
||||||
|
if (pokemon == user)
|
||||||
|
continue;
|
||||||
|
var moves = pokemon.Moves.WhereNotNull().Where(m => m.MoveData.CanCopyMove());
|
||||||
|
foreach (var move in moves)
|
||||||
|
{
|
||||||
|
yield return move.MoveData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Attract.cs
Normal file
48
Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Attract.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
using PkmnLib.Static.Species;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Moves;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If it is the opposite gender of the user, the target becomes infatuated and less likely to attack.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The target becomes infatuated with the user if they have opposite genders. Attract works regardless of type immunity.
|
||||||
|
/// Unlike most status moves, Attract is able to bypass a substitute.
|
||||||
|
/// Attract has no effect if the user and target have the same gender, or if either of them is a gender-unknown Pokémon
|
||||||
|
/// (such as Magnemite). It also fails when used on a Pokémon that is already infatuated.
|
||||||
|
/// Pokémon with the Ability Oblivious or under the protection of Aroma Veil are immune to the effects of Attract. If
|
||||||
|
/// a Pokémon is infatuated by Attract while holding a Mental Herb or an Eggant Berry, the item will be consumed and the
|
||||||
|
/// infatuation will end. Even if the Pokémon has Oblivious, the item will still be consumed.
|
||||||
|
/// If the target Pokémon becomes infatuated while holding a Destiny Knot, the user will also become infatuated with the
|
||||||
|
/// target.
|
||||||
|
/// </remarks>
|
||||||
|
[Script(ScriptCategory.Move, "attract")]
|
||||||
|
public class Attract : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
if (target.Gender == move.User.Gender)
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.Gender == Gender.Genderless || move.User.Gender == Gender.Genderless)
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (target.Volatile.Contains("infatuated"))
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.Volatile.Add(new Infatuated());
|
||||||
|
}
|
||||||
|
}
|
25
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/Infatuated.cs
Normal file
25
Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/Infatuated.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If an infatuated Pokémon attempts to use a move, it will fail 50% of the time, even when targeting Pokémon other than
|
||||||
|
/// the one it is infatuated with. This failed move does not spend PP.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Infatuation is caused when Attract is used on a target of the opposite gender, G-Max Cuddle is used by Gigantamax Eevee
|
||||||
|
/// on all opponents of the opposite gender, may be caused when a Pokémon makes contact with a Pokémon of the opposite
|
||||||
|
/// gender that has Cute Charm as its Ability, and is caused to a Pokémon that infatuates a Pokémon holding a Destiny Knot.
|
||||||
|
/// </remarks>
|
||||||
|
[Script(ScriptCategory.Pokemon, "infatuated")]
|
||||||
|
public class Infatuated : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PreventMove(IExecutingMove move, ref bool prevent)
|
||||||
|
{
|
||||||
|
if (move.User.BattleData?.Battle?.Random.GetBool() == true)
|
||||||
|
prevent = true;
|
||||||
|
}
|
||||||
|
}
|
70
Plugins/PkmnLib.Plugin.Gen7/Scripts/Utils/CopyableMoves.cs
Normal file
70
Plugins/PkmnLib.Plugin.Gen7/Scripts/Utils/CopyableMoves.cs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using PkmnLib.Static.Moves;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Utils;
|
||||||
|
|
||||||
|
public static class CopyableMoves
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Validates if a move can be copied by scripts, such as Assist.
|
||||||
|
/// </summary>
|
||||||
|
public static bool CanCopyMove(this IMoveData move) => !NonCopyable.Contains(move.Name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The names of moves that cannot be copied by scripts.
|
||||||
|
/// </summary>
|
||||||
|
private static readonly HashSet<StringKey> NonCopyable =
|
||||||
|
[
|
||||||
|
"assist",
|
||||||
|
"baneful_bunker",
|
||||||
|
"beak_blast",
|
||||||
|
"belch",
|
||||||
|
"bestow",
|
||||||
|
"bounce",
|
||||||
|
"celebrate",
|
||||||
|
"chatter",
|
||||||
|
"circle_throw",
|
||||||
|
"copycat",
|
||||||
|
"counter",
|
||||||
|
"covet",
|
||||||
|
"destiny_bond",
|
||||||
|
"detect",
|
||||||
|
"dig",
|
||||||
|
"dive",
|
||||||
|
"dragon_tail",
|
||||||
|
"endure",
|
||||||
|
"feint",
|
||||||
|
"fly",
|
||||||
|
"focus_punch",
|
||||||
|
"follow_me",
|
||||||
|
"helping_hand",
|
||||||
|
"hold_hands",
|
||||||
|
"kings_shield",
|
||||||
|
"mat_block",
|
||||||
|
"me_first",
|
||||||
|
"metronome",
|
||||||
|
"mimic",
|
||||||
|
"mirror_coat",
|
||||||
|
"mirror_move",
|
||||||
|
"nature_power",
|
||||||
|
"phantom_force",
|
||||||
|
"protect",
|
||||||
|
"rage_powder",
|
||||||
|
"roar",
|
||||||
|
"shadow_force",
|
||||||
|
"shell_trap",
|
||||||
|
"sketch",
|
||||||
|
"sky_drop",
|
||||||
|
"sleep_talk",
|
||||||
|
"snatch",
|
||||||
|
"spiky_shield",
|
||||||
|
"spotlight",
|
||||||
|
"struggle",
|
||||||
|
"switcheroo",
|
||||||
|
"thief",
|
||||||
|
"transform",
|
||||||
|
"trick",
|
||||||
|
"whirlwind"
|
||||||
|
];
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user