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

@@ -8,13 +8,13 @@ namespace PkmnLib.Plugin.Gen7.AI;
public static class AIHelperFunctions
{
public static int GetScoreForTargetStatRaise(int score, AIMoveState move, IPokemon target,
public static int GetScoreForTargetStatRaise(int score, AIMoveState move, IBattlePokemon target,
StatisticSet<sbyte> statChanges, bool fixedChange = false, bool ignoreContrary = false)
{
var wholeEffect = move.Move.Category != MoveCategory.Status;
var desireMult = 1;
if (move.User.BattleData?.SideIndex != target.BattleData?.SideIndex)
if (move.User.SideIndex != target.SideIndex)
desireMult = -1;
if (!ignoreContrary && !fixedChange && target.ActiveAbility?.Name == AbilityNames.Contrary)
@@ -41,8 +41,7 @@ public static class AIHelperFunctions
if (!move.User.HasMoveWithEffect(MoveEffectNames.PowerTrip))
{
var foeIsAware =
target.BattleData?.BattleSide.Pokemon.Any(x => x?.ActiveAbility?.Name == AbilityNames.Unaware) != true;
var foeIsAware = target.BattleSide.Pokemon.Any(x => x?.ActiveAbility?.Name == AbilityNames.Unaware) != true;
if (!foeIsAware)
{
return wholeEffect ? ExplicitAI.MoveUselessScore : score;
@@ -80,13 +79,13 @@ public static class AIHelperFunctions
return score;
}
public static int GetScoreForTargetStatDrop(int score, AIMoveState move, IPokemon target,
public static int GetScoreForTargetStatDrop(int score, AIMoveState move, IBattlePokemon target,
StatisticSet<sbyte> statChanges, bool fixedChange = false, bool ignoreContrary = false)
{
var wholeEffect = move.Move.Category != MoveCategory.Status;
var desireMult = -1;
if (move.User.BattleData?.SideIndex == target.BattleData?.SideIndex)
if (move.User.SideIndex == target.SideIndex)
desireMult = 1;
if (!ignoreContrary && !fixedChange && target.ActiveAbility?.Name == AbilityNames.Contrary)
{
@@ -109,7 +108,7 @@ public static class AIHelperFunctions
return wholeEffect ? ExplicitAI.MoveUselessScore : score;
var foeIsAware = false;
if (target.BattleData?.BattleSide.Pokemon.All(x => x?.ActiveAbility?.Name != AbilityNames.Unaware) == true)
if (target.BattleSide.Pokemon.All(x => x?.ActiveAbility?.Name != AbilityNames.Unaware) == true)
{
foeIsAware = true;
}
@@ -148,7 +147,8 @@ public static class AIHelperFunctions
/// <summary>
/// Checks if a stat raise is worthwhile for the given Pokémon and stat.
/// </summary>
private static bool IsStatRaiseWorthwhile(IPokemon pokemon, Statistic stat, sbyte amount, bool fixedChange = false)
private static bool IsStatRaiseWorthwhile(IBattlePokemon pokemon, Statistic stat, sbyte amount,
bool fixedChange = false)
{
if (!fixedChange && pokemon.StatBoost.GetStatistic(stat) == StatBoostStatisticSet.MaxStatBoost)
return false;
@@ -169,7 +169,7 @@ public static class AIHelperFunctions
}
case Statistic.Defense:
{
var opponentSide = pokemon.BattleData!.Battle.Sides.First(x => x != pokemon.BattleData.BattleSide);
var opponentSide = pokemon.Battle.Sides.First(x => x != pokemon.BattleSide);
return opponentSide.Pokemon.WhereNotNull().Any(x => x.Moves.WhereNotNull().Any(y =>
y.MoveData.Category == MoveCategory.Physical ||
y.MoveData.SecondaryEffect?.Name == MoveEffectNames.Psyshock));
@@ -184,7 +184,7 @@ public static class AIHelperFunctions
}
case Statistic.SpecialDefense:
{
var opponentSide = pokemon.BattleData!.Battle.Sides.First(x => x != pokemon.BattleData.BattleSide);
var opponentSide = pokemon.Battle.Sides.First(x => x != pokemon.BattleSide);
return opponentSide.Pokemon.WhereNotNull().Any(x => x.Moves.WhereNotNull().Any(y =>
y.MoveData.Category == MoveCategory.Special &&
y.MoveData.SecondaryEffect?.Name != MoveEffectNames.Psyshock));
@@ -194,7 +194,7 @@ public static class AIHelperFunctions
if (!pokemon.HasMoveWithEffect(MoveEffectNames.ElectroBall, MoveEffectNames.PowerTrip))
{
var targetSpeed = pokemon.BoostedStats.Speed;
var opponentSide = pokemon.BattleData!.Battle.Sides.First(x => x != pokemon.BattleData.BattleSide);
var opponentSide = pokemon.Battle.Sides.First(x => x != pokemon.BattleSide);
var meaningful = opponentSide.Pokemon.WhereNotNull().Select(opponent => opponent.BoostedStats.Speed)
.Any(foeSpeed => targetSpeed < foeSpeed && targetSpeed * 2.5 > foeSpeed);
if (!meaningful)
@@ -208,7 +208,7 @@ public static class AIHelperFunctions
if (minAccuracy >= 90 && pokemon.StatBoost.Accuracy >= 0)
{
var meaningful = false;
var opponentSide = pokemon.BattleData!.Battle.Sides.First(x => x != pokemon.BattleData.BattleSide);
var opponentSide = pokemon.Battle.Sides.First(x => x != pokemon.BattleSide);
if (opponentSide.Pokemon.WhereNotNull().Any(x => x.StatBoost.Evasion > 0))
{
meaningful = true;
@@ -222,7 +222,7 @@ public static class AIHelperFunctions
return true;
}
private static bool IsStatDropWorthwhile(IPokemon pokemon, Statistic stat, sbyte amount)
private static bool IsStatDropWorthwhile(IBattlePokemon pokemon, Statistic stat, sbyte amount)
{
if (amount == 0)
return false;
@@ -236,7 +236,7 @@ public static class AIHelperFunctions
}
case Statistic.Defense:
{
var opponentSide = pokemon.BattleData!.Battle.Sides.First(x => x != pokemon.BattleData.BattleSide);
var opponentSide = pokemon.Battle.Sides.First(x => x != pokemon.BattleSide);
return opponentSide.Pokemon.WhereNotNull().Any(x => x.Moves.WhereNotNull().Any(y =>
y.MoveData.Category == MoveCategory.Physical ||
y.MoveData.SecondaryEffect?.Name == MoveEffectNames.Psyshock));
@@ -247,7 +247,7 @@ public static class AIHelperFunctions
}
case Statistic.SpecialDefense:
{
var opponentSide = pokemon.BattleData!.Battle.Sides.First(x => x != pokemon.BattleData.BattleSide);
var opponentSide = pokemon.Battle.Sides.First(x => x != pokemon.BattleSide);
return opponentSide.Pokemon.WhereNotNull().Any(x => x.Moves.WhereNotNull().Any(y =>
y.MoveData.Category == MoveCategory.Special &&
y.MoveData.SecondaryEffect?.Name != MoveEffectNames.Psyshock));
@@ -257,7 +257,7 @@ public static class AIHelperFunctions
if (!pokemon.HasMoveWithEffect(MoveEffectNames.ElectroBall))
{
var targetSpeed = pokemon.BoostedStats.Speed;
var opponentSide = pokemon.BattleData!.Battle.Sides.First(x => x != pokemon.BattleData.BattleSide);
var opponentSide = pokemon.Battle.Sides.First(x => x != pokemon.BattleSide);
return opponentSide.Pokemon.WhereNotNull().Select(opponent => opponent.BoostedStats.Speed)
.Any(foeSpeed => targetSpeed > foeSpeed && targetSpeed < foeSpeed * 2.5);
}
@@ -272,8 +272,8 @@ public static class AIHelperFunctions
return true;
}
private static void GetTargetStatRaiseScoreOne(ref int score, IPokemon target, Statistic stat, sbyte increment,
AIMoveState move, float desireMult = 1)
private static void GetTargetStatRaiseScoreOne(ref int score, IBattlePokemon target, Statistic stat,
sbyte increment, AIMoveState move, float desireMult = 1)
{
var oldStage = target.StatBoost.GetStatistic(stat);
var newStage = (sbyte)(oldStage + increment);
@@ -282,7 +282,7 @@ public static class AIHelperFunctions
var actualIncrement = incMult;
incMult -= 1;
incMult *= desireMult;
var opponentSide = target.BattleData!.Battle.Sides.First(x => x != target.BattleData.BattleSide);
var opponentSide = target.Battle.Sides.First(x => x != target.BattleSide);
switch (stat)
{
@@ -407,7 +407,7 @@ public static class AIHelperFunctions
}
}
private static void GetTargetStatDropScoreOne(ref int score, IPokemon target, Statistic stat, sbyte decrement,
private static void GetTargetStatDropScoreOne(ref int score, IBattlePokemon target, Statistic stat, sbyte decrement,
AIMoveState move, float desireMult = 1)
{
var oldStage = target.StatBoost.GetStatistic(stat);
@@ -416,7 +416,7 @@ public static class AIHelperFunctions
Gen7BattleStatCalculator.GetStatBoostModifier(Math.Max(newStage, (sbyte)-6));
decMult -= 1;
decMult *= desireMult;
var opponentSide = target.BattleData!.Battle.Sides.First(x => x != target.BattleData.BattleSide);
var opponentSide = target.Battle.Sides.First(x => x != target.BattleSide);
switch (stat)
{
@@ -519,11 +519,11 @@ public static class AIHelperFunctions
/// <summary>
/// Calculates the score for the generic concept of raising a target's stats.
/// </summary>
private static int GetTargetStatRaiseScoreGeneric(int score, IPokemon target, StatisticSet<sbyte> statChanges,
private static int GetTargetStatRaiseScoreGeneric(int score, IBattlePokemon target, StatisticSet<sbyte> statChanges,
AIMoveState move, float desireMult = 1)
{
var totalIncrement = statChanges.Sum(x => x.value);
var turns = target.BattleData!.Battle.CurrentTurnNumber - target.BattleData!.SwitchInTurn;
var turns = target.Battle.CurrentTurnNumber - target.SwitchInTurn;
if (turns < 2 && move.Move.Category == MoveCategory.Status)
score += (int)(totalIncrement * desireMult * 5);
@@ -532,11 +532,11 @@ public static class AIHelperFunctions
return score;
}
private static int GetTargetStatDropScoreGeneric(int score, IPokemon target, StatisticSet<sbyte> statChanges,
private static int GetTargetStatDropScoreGeneric(int score, IBattlePokemon target, StatisticSet<sbyte> statChanges,
AIMoveState move, float desireMult = 1)
{
var totalDecrement = statChanges.Sum(x => x.value);
var turns = target.BattleData!.Battle.CurrentTurnNumber - target.BattleData!.SwitchInTurn;
var turns = target.Battle.CurrentTurnNumber - target.SwitchInTurn;
if (turns < 2 && move.Move.Category == MoveCategory.Status)
score += (int)(totalDecrement * desireMult * 5);
@@ -545,34 +545,34 @@ public static class AIHelperFunctions
return score;
}
private static int GetScoreChangeForAdditionalEffect(this AIMoveState move, IPokemon? target)
private static int GetScoreChangeForAdditionalEffect(this AIMoveState move, IBattlePokemon? target)
{
if (move.Move.SecondaryEffect is null)
return 0;
if (move.User.ActiveAbility?.Name == AbilityNames.SheerForce)
return -999;
if (target is not null && target.BattleData?.Position != move.User.BattleData?.Position &&
if (target is not null && target.Position != move.User.Position &&
target.ActiveAbility?.Name == AbilityNames.ShieldDust)
return -999;
if ((move.Move.SecondaryEffect.Chance < 100 && move.User.ActiveAbility?.Name == AbilityNames.SereneGrace) ||
move.User.BattleData?.BattleSide.VolatileScripts.Contains<RainbowEffect>() == true)
move.User.BattleSide.VolatileScripts.Contains<RainbowEffect>() == true)
{
return 5;
}
return 0;
}
private static bool HasMoveWithEffect(this IPokemon pokemon, params StringKey[] effect)
private static bool HasMoveWithEffect(this IBattlePokemon pokemon, params StringKey[] effect)
{
return pokemon.Moves.WhereNotNull().Any(move => move.MoveData.SecondaryEffect?.Name is not null &&
effect.Contains(move.MoveData.SecondaryEffect.Name));
}
private static bool Opposes(this IPokemon pokemon, IPokemon target) =>
pokemon.BattleData?.BattleSide != target.BattleData?.BattleSide;
private static bool Opposes(this IBattlePokemon pokemon, IBattlePokemon target) =>
pokemon.BattleSide != target.BattleSide;
public static bool WantsStatusProblem(IPokemon pokemon, StringKey? status)
public static bool WantsStatusProblem(IBattlePokemon pokemon, StringKey? status)
{
if (status is null)
return true;

View File

@@ -19,7 +19,8 @@ public static class AISwitchFunctions
/// <summary>
/// Switch out if the Perish Song effect is about to cause the Pokémon to faint.
/// </summary>
private static bool PerishSong(IExplicitAI ai, IPokemon pokemon, IBattle battle, IReadOnlyList<IPokemon> reserves)
private static bool PerishSong(IExplicitAI ai, IBattlePokemon pokemon, IBattle battle,
IReadOnlyList<IBattlePokemon> reserves)
{
if (!pokemon.Volatile.TryGet<PerishSongEffect>(out var effect))
return false;
@@ -29,8 +30,8 @@ public static class AISwitchFunctions
/// <summary>
/// Switch out if the Pokémon is expected to take significant end-of-turn damage.
/// </summary>
private static bool SignificantEndOfTurnDamage(IExplicitAI ai, IPokemon pokemon, IBattle battle,
IReadOnlyList<IPokemon> reserves)
private static bool SignificantEndOfTurnDamage(IExplicitAI ai, IBattlePokemon pokemon, IBattle battle,
IReadOnlyList<IBattlePokemon> reserves)
{
var eorDamage = 0;
pokemon.RunScriptHook<IAIInfoScriptExpectedEndOfTurnDamage>(x =>
@@ -61,21 +62,20 @@ public static class AISwitchFunctions
return false;
}
private static bool HighDamageFromFoe(IExplicitAI ai, IPokemon pokemon, IBattle battle,
IReadOnlyList<IPokemon> reserves)
private static bool HighDamageFromFoe(IExplicitAI ai, IBattlePokemon pokemon, IBattle battle,
IReadOnlyList<IBattlePokemon> reserves)
{
if (!ai.TrainerHighSkill)
return false;
if (pokemon.CurrentHealth >= pokemon.MaxHealth / 2)
return false;
var bigThreat = false;
var opponents = battle.Sides.Where(x => x != pokemon.BattleData?.BattleSide)
.SelectMany(x => x.Pokemon.WhereNotNull());
var opponents = battle.Sides.Where(x => x != pokemon.BattleSide).SelectMany(x => x.Pokemon.WhereNotNull());
foreach (var opponent in opponents)
{
if (Math.Abs(opponent.Level - pokemon.Level) > 5)
continue;
var lastMoveUsed = opponent.BattleData?.LastMoveChoice;
var lastMoveUsed = opponent.LastMoveChoice;
if (lastMoveUsed is null)
continue;
var moveData = lastMoveUsed.ChosenMove.MoveData;
@@ -107,15 +107,15 @@ public static class AISwitchFunctions
/// <summary>
/// Switch out to cure a status problem or heal HP with abilities like Natural Cure or Regenerator.
/// </summary>
private static bool CureStatusProblemBySwitchingOut(IExplicitAI ai, IPokemon pokemon, IBattle battle,
IReadOnlyList<IPokemon> reserves)
private static bool CureStatusProblemBySwitchingOut(IExplicitAI ai, IBattlePokemon pokemon, IBattle battle,
IReadOnlyList<IBattlePokemon> reserves)
{
if (pokemon.ActiveAbility == null)
return false;
// Don't try to cure a status problem/heal a bit of HP if entry hazards will
// KO the battler if it switches back in
var entryHazardDamage = ExplicitAI.CalculateEntryHazardDamage(pokemon, pokemon.BattleData!.BattleSide);
var entryHazardDamage = ExplicitAI.CalculateEntryHazardDamage(pokemon, pokemon.BattleSide);
if (entryHazardDamage >= pokemon.CurrentHealth)
return false;
if (pokemon.StatusScript.Script is null)
@@ -151,7 +151,7 @@ public static class AISwitchFunctions
if (pokemon.StatusScript.Script is Poisoned or BadlyPoisoned &&
!reserves.Any(p => p.Types.Any(t => t.Name == TypeNames.Poison)))
{
if (pokemon.BattleData!.BattleSide.VolatileScripts.TryGet<ToxicSpikesEffect>(out _))
if (pokemon.BattleSide.VolatileScripts.TryGet<ToxicSpikesEffect>(out _))
{
return false;
}
@@ -179,7 +179,7 @@ public static class AISwitchFunctions
var hasDamagingMove = pokemon.Moves.Any(m => m?.MoveData.Category != MoveCategory.Status);
if (hasDamagingMove)
{
var opponents = battle.Sides.Where(x => x != pokemon.BattleData?.BattleSide)
var opponents = battle.Sides.Where(x => x != pokemon.BattleSide)
.SelectMany(x => x.Pokemon.WhereNotNull());
var weakFoe = opponents.Any(opponent => opponent.CurrentHealth < opponent.MaxHealth / 3);
if (weakFoe)

View File

@@ -26,7 +26,7 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
}
/// <inheritdoc />
public void CalculateBoostedStats(IPokemon pokemon, StatisticSet<uint> stats)
public void CalculateBoostedStats(IBattlePokemon pokemon, StatisticSet<uint> stats)
{
stats.SetStatistic(Statistic.Hp, CalculateBoostedStat(pokemon, Statistic.Hp));
stats.SetStatistic(Statistic.Attack, CalculateBoostedStat(pokemon, Statistic.Attack));
@@ -37,7 +37,7 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
}
/// <inheritdoc />
public uint CalculateBoostedStat(IPokemon pokemon, Statistic stat)
public uint CalculateBoostedStat(IBattlePokemon pokemon, Statistic stat)
{
var flatStat = CalculateFlatStat(pokemon, stat);
var boostModifier = GetStatBoostModifier(pokemon.StatBoost.GetStatistic(stat));
@@ -48,7 +48,7 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
}
/// <inheritdoc />
public byte CalculateModifiedAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex,
public byte CalculateModifiedAccuracy(IExecutingMove executingMove, IBattlePokemon target, byte hitIndex,
byte moveAccuracy)
{
var accuracyModifier = 1.0f;

View File

@@ -15,7 +15,7 @@ public class Gen7CaptureLibrary : ICaptureLibrary
public bool HasPokemonBeenCaughtBefore(ISpecies species) => _configuration.TimesSpeciesCaught(species) > 0;
/// <inheritdoc />
public CaptureResult TryCapture(IPokemon target, IItem captureItem, IBattleRandom random)
public CaptureResult TryCapture(IBattlePokemon target, IItem captureItem, IBattleRandom random)
{
var maxHealth = target.BoostedStats.Hp;
var currentHealth = target.CurrentHealth;

View File

@@ -6,8 +6,8 @@ namespace PkmnLib.Plugin.Gen7.Libraries.Battling;
public class Gen7DamageCalculator(Gen7PluginConfiguration configuration) : IDamageCalculator
{
/// <inheritdoc />
public uint GetDamage(IExecutingMove? executingMove, MoveCategory category, IPokemon user, IPokemon target,
int targetCount, byte hitNumber, IHitData hitData)
public uint GetDamage(IExecutingMove? executingMove, MoveCategory category, IBattlePokemon user,
IBattlePokemon target, int targetCount, byte hitNumber, IHitData hitData)
{
if (category == MoveCategory.Status)
return 0;
@@ -36,7 +36,7 @@ public class Gen7DamageCalculator(Gen7PluginConfiguration configuration) : IDama
if (configuration.DamageCalculatorHasRandomness)
{
var battle = target.BattleData?.Battle;
var battle = target.Battle;
if (battle == null)
throw new InvalidOperationException("Randomness is enabled, but no battle is set.");
var random = battle.Random;
@@ -75,7 +75,7 @@ public class Gen7DamageCalculator(Gen7PluginConfiguration configuration) : IDama
}
/// <inheritdoc />
public ushort GetBasePower(IExecutingMove executingMove, IPokemon target, byte hitNumber, IHitData hitData)
public ushort GetBasePower(IExecutingMove executingMove, IBattlePokemon target, byte hitNumber, IHitData hitData)
{
if (executingMove.UseMove.Category == MoveCategory.Status)
return 0;
@@ -86,7 +86,7 @@ public class Gen7DamageCalculator(Gen7PluginConfiguration configuration) : IDama
}
/// <inheritdoc />
public bool IsCritical(IBattle battle, IExecutingMove executingMove, IPokemon target, byte hitNumber)
public bool IsCritical(IBattle battle, IExecutingMove executingMove, IBattlePokemon target, byte hitNumber)
{
if (executingMove.UseMove.Category == MoveCategory.Status)
return false;
@@ -104,8 +104,8 @@ public class Gen7DamageCalculator(Gen7PluginConfiguration configuration) : IDama
};
}
private static float GetStatModifier(IExecutingMove? executingMove, MoveCategory category, IPokemon user,
IPokemon target, byte hitNumber, IHitData hitData)
private static float GetStatModifier(IExecutingMove? executingMove, MoveCategory category, IBattlePokemon user,
IBattlePokemon target, byte hitNumber, IHitData hitData)
{
if (category == MoveCategory.Status)
return 1;
@@ -168,7 +168,7 @@ public class Gen7DamageCalculator(Gen7PluginConfiguration configuration) : IDama
/// Gets the damage modifier. This is a value that defaults to 1.0, but can be modified by scripts
/// to apply a raw modifier to the damage.
/// </summary>
private static float GetDamageModifier(IExecutingMove executingMove, IPokemon target, byte hitNumber)
private static float GetDamageModifier(IExecutingMove executingMove, IBattlePokemon target, byte hitNumber)
{
var modifier = 1.0f;

View File

@@ -11,7 +11,7 @@ public class Gen7MiscLibrary : IMiscLibrary
new SecondaryEffectImpl(-1, "struggle", new Dictionary<StringKey, object?>()), ["not_sketchable"]);
/// <inheritdoc />
public ITurnChoice ReplacementChoice(IPokemon user, byte targetSide, byte targetPosition) =>
public ITurnChoice ReplacementChoice(IBattlePokemon user, byte targetSide, byte targetPosition) =>
new MoveChoice(user, new LearnedMoveImpl(_struggleData, MoveLearnMethod.Unknown), targetSide, targetPosition);
/// <inheritdoc />
@@ -37,7 +37,7 @@ public class Gen7MiscLibrary : IMiscLibrary
public bool CanFlee(IBattle battle, IFleeChoice fleeChoice)
{
var user = fleeChoice.User;
var battleData = user.BattleData;
var battleData = user;
if (battleData == null)
return false;
var opponentSide = battle.Sides[battleData.SideIndex == 0 ? 1 : 0];

View File

@@ -12,13 +12,13 @@ public class Aftermath : Script, IScriptOnIncomingHit, IScriptOnFaint
private IExecutingMove? _lastAttack;
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
_lastAttack = move.GetHitData(target, hit).IsContact ? move : null;
}
/// <inheritdoc />
public void OnFaint(IPokemon pokemon, DamageSource source)
public void OnFaint(IBattlePokemon pokemon, DamageSource source)
{
if (source != DamageSource.MoveDamage)
return;
@@ -27,11 +27,9 @@ public class Aftermath : Script, IScriptOnIncomingHit, IScriptOnFaint
var user = _lastAttack.User;
if (!user.IsUsable)
return;
if (user.BattleData is null)
return;
// Aftermath does not trigger if a Pokémon with Damp is on the field
var battle = user.BattleData.Battle;
var battle = user.Battle;
var hasDamp = battle.Sides.SelectMany(side => side.Pokemon).WhereNotNull()
.Any(p => p.ActiveAbility?.Name == AbilityNames.Damp);
if (hasDamp)

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Analytic : Script, IScriptChangeDamageModifier
{
/// <inheritdoc />
public void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
public void ChangeDamageModifier(IExecutingMove move, IBattlePokemon target, byte hit, ref float modifier)
{
if (move.Battle.ChoiceQueue?.HasNext() == false)
{

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class AngerPoint : Script, IScriptOnIncomingHit
{
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
if (move.GetHitData(target, hit).IsCritical)
{

View File

@@ -9,18 +9,18 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "anticipation")]
public class Anticipation : Script, IScriptOnOpponentSwitchIn
{
private IPokemon? _owner;
private IBattlePokemon? _owner;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new ArgumentException("Anticipation script can only be added to a Pokemon.", nameof(source));
_owner = pokemon;
}
/// <inheritdoc />
public void OnOpponentSwitchIn(IPokemon pokemon, byte position)
public void OnOpponentSwitchIn(IBattlePokemon pokemon, byte position)
{
if (_owner is null)
return;
@@ -37,7 +37,7 @@ public class Anticipation : Script, IScriptOnOpponentSwitchIn
if (relevantMoves)
{
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owner));
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owner));
}
}
}

View File

@@ -9,12 +9,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "arena_trap")]
public class ArenaTrap : Script, IScriptPreventOpponentRunAway, IScriptPreventOpponentSwitch
{
private IPokemon? _owner;
private IBattlePokemon? _owner;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("ArenaTrap can only be added to a Pokemon.");
_owner = pokemon;
}
@@ -25,7 +25,7 @@ public class ArenaTrap : Script, IScriptPreventOpponentRunAway, IScriptPreventOp
if (choice.User.IsFloating)
return;
if (_owner is not null)
choice.User.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owner));
choice.User.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owner));
prevent = true;
}
@@ -35,7 +35,7 @@ public class ArenaTrap : Script, IScriptPreventOpponentRunAway, IScriptPreventOp
if (choice.User.IsFloating)
return;
if (_owner is not null)
choice.User.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owner));
choice.User.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owner));
prevent = true;
}
}

View File

@@ -10,17 +10,17 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class AromaVeil : Script, IScriptOnSwitchIn, IScriptOnSwitchOut
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var side = pokemon.BattleData?.BattleSide;
var side = pokemon.BattleSide;
var effect = side?.VolatileScripts.Add(new Side.AromaVeilEffect())?.Script as Side.AromaVeilEffect;
effect?.PlacerActivated(pokemon);
}
/// <inheritdoc />
public void OnSwitchOut(IPokemon oldPokemon, byte position)
public void OnSwitchOut(IBattlePokemon oldPokemon, byte position)
{
var side = oldPokemon.BattleData?.BattleSide;
var side = oldPokemon.BattleSide;
var effect = side?.VolatileScripts.Get<Side.AromaVeilEffect>();
effect?.PlacerDeactivated(oldPokemon);
}

View File

@@ -9,12 +9,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "bad_dreams")]
public class BadDreams : Script, IScriptOnEndTurn
{
private IPokemon? _owner;
private IBattlePokemon? _owner;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Bad Dreams ability can only be added to a Pokemon.");
_owner = pokemon;
}
@@ -24,8 +24,7 @@ public class BadDreams : Script, IScriptOnEndTurn
{
if (_owner is null)
return;
var opponents = battle.Sides.Where(x => x != _owner?.BattleData?.BattleSide).SelectMany(x => x.Pokemon)
.WhereNotNull();
var opponents = battle.Sides.Where(x => x != _owner?.BattleSide).SelectMany(x => x.Pokemon).WhereNotNull();
foreach (var opponent in opponents)
{

View File

@@ -10,17 +10,17 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Battery : Script, IScriptOnSwitchIn, IScriptOnSwitchOut
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var side = pokemon.BattleData?.BattleSide;
var side = pokemon.BattleSide;
var effect = side?.VolatileScripts.Add(new Side.BatteryAbilityEffect())?.Script as Side.BatteryAbilityEffect;
effect?.PlacerActivated(pokemon);
}
/// <inheritdoc />
public void OnSwitchOut(IPokemon oldPokemon, byte position)
public void OnSwitchOut(IBattlePokemon oldPokemon, byte position)
{
var side = oldPokemon.BattleData?.BattleSide;
var side = oldPokemon.BattleSide;
var effect = side?.VolatileScripts.Get<Side.BatteryAbilityEffect>();
effect?.PlacerDeactivated(oldPokemon);
}

View File

@@ -10,18 +10,18 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class BattleBond : Script, IScriptChangeNumberOfHits, IScriptOnOpponentFaints, IScriptChangeBasePower
{
/// <inheritdoc />
public void OnOpponentFaints(IExecutingMove move, IPokemon target, byte hit)
public void OnOpponentFaints(IExecutingMove move, IBattlePokemon target, byte hit)
{
if (move.User.Species.Name == SpeciesNames.Greninja && move.User.Form.Name != FormNames.Ash &&
move.User.Species.TryGetForm(FormNames.Ash, out var ashForm))
{
move.User.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(move.User));
move.User.Battle.EventHook.Invoke(new AbilityTriggerEvent(move.User));
move.User.ChangeForm(ashForm);
}
}
/// <inheritdoc />
public void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
public void ChangeBasePower(IExecutingMove move, IBattlePokemon target, byte hit, ref ushort basePower)
{
if (move.UseMove.Name == MoveNames.WaterShuriken && move.User.Form.Name == FormNames.Ash)
basePower = 20;

View File

@@ -10,11 +10,11 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class BeastBoost : Script, IScriptOnOpponentFaints
{
/// <inheritdoc />
public void OnOpponentFaints(IExecutingMove move, IPokemon target, byte hit)
public void OnOpponentFaints(IExecutingMove move, IBattlePokemon target, byte hit)
{
var highestStat = move.User.BoostedStats.OrderByDescending(x => x.value).First().statistic;
EventBatchId batchId = new();
move.User.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(move.User)
move.User.Battle.EventHook.Invoke(new AbilityTriggerEvent(move.User)
{
BatchId = batchId,
});

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Berserk : Script, IScriptOnDamage
{
/// <inheritdoc />
public void OnDamage(IPokemon pokemon, DamageSource source, uint oldHealth, uint newHealth)
public void OnDamage(IBattlePokemon pokemon, DamageSource source, uint oldHealth, uint newHealth)
{
if (source is not DamageSource.MoveDamage)
return;
@@ -18,7 +18,7 @@ public class Berserk : Script, IScriptOnDamage
return;
EventBatchId batchId = new();
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
BatchId = batchId,
});

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Bulletproof : Script, IScriptFailIncomingMove
{
/// <inheritdoc />
public void FailIncomingMove(IExecutingMove move, IPokemon target, ref bool fail)
public void FailIncomingMove(IExecutingMove move, IBattlePokemon target, ref bool fail)
{
if (move.UseMove.HasFlag(MoveFlags.Ballistics))
fail = true;

View File

@@ -29,7 +29,7 @@ public class ChangeMoveTypeAbility : Script, IScriptOnInitialize, IScriptChangeM
}
/// <inheritdoc />
public void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, ref TypeIdentifier? typeIdentifier)
public void ChangeMoveType(IExecutingMove move, IBattlePokemon target, byte hit, ref TypeIdentifier? typeIdentifier)
{
var typeLibrary = target.Library.StaticLibrary.Types;
// Both types must be valid and the current type must match the from type
@@ -44,7 +44,7 @@ public class ChangeMoveTypeAbility : Script, IScriptOnInitialize, IScriptChangeM
}
/// <inheritdoc />
public void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
public void ChangeBasePower(IExecutingMove move, IBattlePokemon target, byte hit, ref ushort basePower)
{
if (move.GetHitData(target, hit).HasFlag("change_move_type_ability"))
basePower = basePower.MultiplyOrMax(1.3f);

View File

@@ -10,11 +10,11 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class CheekPouch : Script, IScriptOnAfterItemConsume
{
/// <inheritdoc />
public void OnAfterItemConsume(IPokemon pokemon, IItem item)
public void OnAfterItemConsume(IBattlePokemon pokemon, IItem item)
{
if (item.Category == ItemCategory.Berry)
{
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
pokemon.Heal(pokemon.MaxHealth / 3);
}
}

View File

@@ -10,12 +10,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class ColorChange : Script, IScriptOnIncomingHit
{
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
var hitData = move.GetHitData(target, hit);
if (hitData.Type != null && (hitData.Type != target.Types.FirstOrDefault() || target.Types.Count > 1))
{
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.SetTypes([hitData.Type.Value]);
}
}

View File

@@ -11,7 +11,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Comatose : Script, IScriptPreventStatusChange, IScriptCustomTrigger
{
/// <inheritdoc />
public void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, ref bool preventStatus)
public void PreventStatusChange(IBattlePokemon pokemon, StringKey status, bool selfInflicted,
ref bool preventStatus)
{
if (status == ScriptUtils.ResolveName<Status.Sleep>())
{

View File

@@ -11,14 +11,14 @@ public class Competitive : Script, IScriptOnAfterStatBoostChange
{
/// <inheritdoc />
/// <inheritdoc />
public void OnAfterStatBoostChange(IPokemon pokemon, Statistic stat, bool selfInflicted, sbyte change)
public void OnAfterStatBoostChange(IBattlePokemon pokemon, Statistic stat, bool selfInflicted, sbyte change)
{
if (change >= 0)
return;
if (selfInflicted)
return;
EventBatchId batchId = new();
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
BatchId = batchId,
});

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class CompoundEyes : Script, IScriptChangeAccuracy
{
/// <inheritdoc />
public void ChangeAccuracy(IExecutingMove move, IPokemon target, byte hit, ref int modifiedAccuracy)
public void ChangeAccuracy(IExecutingMove move, IBattlePokemon target, byte hit, ref int modifiedAccuracy)
{
move.Battle.EventHook.Invoke(new AbilityTriggerEvent(move.User));
modifiedAccuracy = (int)(modifiedAccuracy * 1.3f);

View File

@@ -11,10 +11,10 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Contrary : Script, IScriptChangeStatBoostChange
{
/// <inheritdoc />
public void ChangeStatBoostChange(IPokemon target, Statistic stat, bool selfInflicted, ref sbyte amount)
public void ChangeStatBoostChange(IBattlePokemon target, Statistic stat, bool selfInflicted, ref sbyte amount)
{
// Invert the stat change
amount = (sbyte)-amount;
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
}
}

View File

@@ -13,13 +13,13 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class CursedBody : Script, IScriptOnIncomingHit
{
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
// 30% chance to disable the move
if (move.Battle.Random.GetFloat() > 0.3f)
return;
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.Volatile.Add(new DisableEffect(move.ChosenMove.MoveData.Name));
}
}

View File

@@ -14,7 +14,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class CuteCharm : Script, IScriptOnIncomingHit
{
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
// Only trigger on contact moves
if (!move.GetHitData(target, hit).IsContact)
@@ -28,7 +28,7 @@ public class CuteCharm : Script, IScriptOnIncomingHit
move.User.Gender == Gender.Genderless)
return;
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
move.User.Volatile.Add(new Infatuated());
}
}

View File

@@ -11,7 +11,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Damp : Script, IScriptFailIncomingMove
{
/// <inheritdoc />
public void FailIncomingMove(IExecutingMove move, IPokemon target, ref bool fail)
public void FailIncomingMove(IExecutingMove move, IBattlePokemon target, ref bool fail)
{
if (move.UseMove.Name == MoveNames.SelfDestruct || move.UseMove.Name == MoveNames.Explosion)
{

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class DarkAura : Script, IScriptChangeDamageModifier
{
/// <inheritdoc />
public void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
public void ChangeDamageModifier(IExecutingMove move, IBattlePokemon target, byte hit, ref float modifier)
{
if (move.GetHitData(target, hit).Type?.Name == TypeNames.Dark)
{

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Dazzling : Script, IScriptFailIncomingMove
{
/// <inheritdoc />
public void FailIncomingMove(IExecutingMove move, IPokemon target, ref bool fail)
public void FailIncomingMove(IExecutingMove move, IBattlePokemon target, ref bool fail)
{
if (move.UseMove.Priority > 0)
{

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Defeatist : Script, IScriptChangeDamageModifier
{
/// <inheritdoc />
public void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
public void ChangeDamageModifier(IExecutingMove move, IBattlePokemon target, byte hit, ref float modifier)
{
if (move.User.CurrentHealth < move.User.MaxHealth / 2)
{

View File

@@ -11,14 +11,14 @@ public class Defiant : Script, IScriptOnAfterStatBoostChange
{
/// <inheritdoc />
/// <inheritdoc />
public void OnAfterStatBoostChange(IPokemon pokemon, Statistic stat, bool selfInflicted, sbyte change)
public void OnAfterStatBoostChange(IBattlePokemon pokemon, Statistic stat, bool selfInflicted, sbyte change)
{
if (change >= 0)
return;
if (selfInflicted)
return;
EventBatchId batchId = new();
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
BatchId = batchId,
});

View File

@@ -11,9 +11,9 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class DeltaStreamAbility : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battle = pokemon.BattleData?.Battle;
var battle = pokemon.Battle;
if (battle == null)
return;

View File

@@ -11,9 +11,9 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class DesolateLandAbility : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battle = pokemon.BattleData?.Battle;
var battle = pokemon.Battle;
if (battle == null)
return;

View File

@@ -13,10 +13,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Disguise : Script, IScriptChangeIncomingDamage
{
/// <inheritdoc />
public void ChangeIncomingDamage(IPokemon pokemon, DamageSource source, ref uint damage)
public void ChangeIncomingDamage(IBattlePokemon pokemon, DamageSource source, ref uint damage)
{
if (pokemon.BattleData == null)
return;
if (source is not DamageSource.MoveDamage and not DamageSource.Confusion)
return;
if (pokemon.Form.Name == FormNames.Busted || pokemon.Form.Name == FormNames.TotemBusted)
@@ -39,7 +37,7 @@ public class Disguise : Script, IScriptChangeIncomingDamage
EventBatchId batchId = new();
pokemon.BattleData.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
BatchId = batchId,
});

View File

@@ -11,9 +11,9 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Download : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battleData = pokemon.BattleData;
var battleData = pokemon;
if (battleData == null)
return;

View File

@@ -11,9 +11,9 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Drizzle : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battleData = pokemon.BattleData;
var battleData = pokemon;
if (battleData == null)
return;

View File

@@ -11,9 +11,9 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Drought : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battleData = pokemon.BattleData;
var battleData = pokemon;
if (battleData == null)
return;

View File

@@ -10,12 +10,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "dry_skin")]
public class DrySkin : Script, IScriptChangeDamageModifier, IScriptOnEndTurn, IAIInfoScriptExpectedEndOfTurnDamage
{
private IPokemon? _owningPokemon;
private IBattlePokemon? _owningPokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
{
throw new ArgumentException("DrySkin script must be added to a Pokemon.", nameof(source));
}
@@ -23,7 +23,7 @@ public class DrySkin : Script, IScriptChangeDamageModifier, IScriptOnEndTurn, IA
}
/// <inheritdoc />
public void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
public void ChangeDamageModifier(IExecutingMove move, IBattlePokemon target, byte hit, ref float modifier)
{
var hitType = move.GetHitData(target, hit).Type;
if (hitType?.Name == TypeNames.Fire)
@@ -33,7 +33,7 @@ public class DrySkin : Script, IScriptChangeDamageModifier, IScriptOnEndTurn, IA
else if (hitType?.Name == TypeNames.Water)
{
modifier = 0;
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.Heal(target.MaxHealth / 4);
}
}
@@ -46,20 +46,20 @@ public class DrySkin : Script, IScriptChangeDamageModifier, IScriptOnEndTurn, IA
var weather = battle.WeatherName;
if (weather == ScriptUtils.ResolveName<Weather.Rain>())
{
_owningPokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owningPokemon));
_owningPokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owningPokemon));
_owningPokemon.Heal(_owningPokemon.MaxHealth / 8);
}
else if (weather == ScriptUtils.ResolveName<Weather.HarshSunlight>())
{
_owningPokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owningPokemon));
_owningPokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owningPokemon));
_owningPokemon.Damage(_owningPokemon.MaxHealth / 8, DamageSource.Weather);
}
}
/// <inheritdoc />
public void ExpectedEndOfTurnDamage(IPokemon pokemon, ref int damage)
public void ExpectedEndOfTurnDamage(IBattlePokemon pokemon, ref int damage)
{
if (pokemon.BattleData?.Battle.WeatherName == ScriptUtils.ResolveName<Weather.HarshSunlight>())
if (pokemon.Battle.WeatherName == ScriptUtils.ResolveName<Weather.HarshSunlight>())
{
damage += (int)(pokemon.MaxHealth / 8f);
}

View File

@@ -11,7 +11,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class EffectSpore : Script, IScriptOnIncomingHit
{
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
if (move.User.Types.Any(x => x.Name == TypeNames.Grass))
return;

View File

@@ -11,9 +11,9 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class ElectricSurge : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battleData = pokemon.BattleData;
var battleData = pokemon;
if (battleData == null)
return;

View File

@@ -10,10 +10,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class EmergencyExit : Script, IScriptOnDamage
{
/// <inheritdoc />
public void OnDamage(IPokemon pokemon, DamageSource source, uint oldHealth, uint newHealth)
public void OnDamage(IBattlePokemon pokemon, DamageSource source, uint oldHealth, uint newHealth)
{
if (pokemon.BattleData is null)
return;
if (source is DamageSource.Confusion)
return;
@@ -22,11 +20,11 @@ public class EmergencyExit : Script, IScriptOnDamage
if (!(oldHealthFraction >= 0.5f) || !(newHealthFraction < 0.5f))
return;
if (pokemon.BattleData.Battle.IsWildBattle)
if (pokemon.Battle.IsWildBattle)
{
pokemon.BattleData.Battle.ForceEndBattle();
pokemon.Battle.ForceEndBattle();
return;
}
pokemon.BattleData.BattleSide.SwapPokemon(pokemon.BattleData.Position, null);
pokemon.BattleSide.SwapPokemon(pokemon.Position, null);
}
}

View File

@@ -11,7 +11,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class FairyAura : Script, IScriptChangeDamageModifier
{
/// <inheritdoc />
public void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
public void ChangeDamageModifier(IExecutingMove move, IBattlePokemon target, byte hit, ref float modifier)
{
if (move.GetHitData(target, hit).Type?.Name == TypeNames.Fairy)
{

View File

@@ -10,7 +10,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Filter : Script, IScriptChangeIncomingMoveDamageModifier
{
/// <inheritdoc />
public void ChangeIncomingMoveDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
public void ChangeIncomingMoveDamageModifier(IExecutingMove move, IBattlePokemon target, byte hit,
ref float modifier)
{
if (move.GetHitData(target, hit).Effectiveness >= 2.0f)
{

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class FlameBody : Script, IScriptOnIncomingHit
{
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
if (!move.GetHitData(target, hit).IsContact)
return;

View File

@@ -12,7 +12,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class FlareBoost : Script, IScriptChangeDamageModifier
{
/// <inheritdoc />
public void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
public void ChangeDamageModifier(IExecutingMove move, IBattlePokemon target, byte hit, ref float modifier)
{
if (!move.User.HasStatus(ScriptUtils.ResolveName<Status.Burned>()))
return;

View File

@@ -13,7 +13,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class FlashFire : Script, IScriptChangeIncomingEffectiveness
{
/// <inheritdoc />
public void ChangeIncomingEffectiveness(IExecutingMove executingMove, IPokemon target, byte hitIndex,
public void ChangeIncomingEffectiveness(IExecutingMove executingMove, IBattlePokemon target, byte hitIndex,
ref float effectiveness)
{
if (executingMove.GetHitData(target, hitIndex).Type?.Name != TypeNames.Fire)

View File

@@ -9,15 +9,15 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "flower_gift")]
public class FlowerGift : Script, IScriptOnWeatherChange
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Flower Gift can only be added to a Pokemon script source.");
_pokemon = pokemon;
var effect = _pokemon.BattleData?.BattleSide.VolatileScripts.Add(new Side.FlowerGiftEffect());
var effect = _pokemon.BattleSide.VolatileScripts.Add(new Side.FlowerGiftEffect());
(effect?.Script as Side.FlowerGiftEffect)?.OnAdded(_pokemon);
}
@@ -42,7 +42,7 @@ public class FlowerGift : Script, IScriptOnWeatherChange
{
if (_pokemon is null)
return;
if (_pokemon.BattleData?.BattleSide.VolatileScripts.TryGet<Side.FlowerGiftEffect>(out var script) == true)
if (_pokemon.BattleSide.VolatileScripts.TryGet<Side.FlowerGiftEffect>(out var script) == true)
{
script.OnRemoved(_pokemon);
}

View File

@@ -9,15 +9,15 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "flower_veil")]
public class FlowerVeil : Script
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Flower Veil can only be added to a Pokemon script source.");
_pokemon = pokemon;
var effect = _pokemon.BattleData?.BattleSide.VolatileScripts.Add(new Side.FlowerVeilEffect());
var effect = _pokemon.BattleSide.VolatileScripts.Add(new Side.FlowerVeilEffect());
(effect?.Script as Side.FlowerVeilEffect)?.OnAdded(_pokemon);
}
@@ -26,7 +26,7 @@ public class FlowerVeil : Script
{
if (_pokemon is null)
return;
if (_pokemon.BattleData?.BattleSide.VolatileScripts.TryGet<Side.FlowerVeilEffect>(out var script) == true)
if (_pokemon.BattleSide.VolatileScripts.TryGet<Side.FlowerVeilEffect>(out var script) == true)
{
script.OnRemoved(_pokemon);
}

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Fluffy : Script, IScriptChangeDamageModifier
{
/// <inheritdoc />
public void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
public void ChangeDamageModifier(IExecutingMove move, IBattlePokemon target, byte hit, ref float modifier)
{
if (move.GetHitData(target, hit).Type?.Name == TypeNames.Fire)
{

View File

@@ -9,20 +9,20 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "forecast")]
public class Forecast : Script, IScriptOnSwitchIn, IScriptOnWeatherChange
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Forecast can only be added to a Pokemon script source.");
_pokemon = pokemon;
}
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
ChangeForm(pokemon, pokemon.BattleData?.Battle.WeatherName);
ChangeForm(pokemon, pokemon.Battle.WeatherName);
}
/// <inheritdoc />
@@ -43,7 +43,7 @@ public class Forecast : Script, IScriptOnSwitchIn, IScriptOnWeatherChange
ChangeForm(_pokemon, null);
}
private static void ChangeForm(IPokemon pokemon, StringKey? weather)
private static void ChangeForm(IBattlePokemon pokemon, StringKey? weather)
{
if (pokemon.Species.Name != SpeciesNames.Castform)
return;

View File

@@ -12,9 +12,9 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Forewarn : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battleData = pokemon.BattleData;
var battleData = pokemon;
if (battleData == null)
return;

View File

@@ -9,15 +9,15 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "friend_guard")]
public class FriendGuard : Script
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Friend Guard can only be added to a Pokemon script source.");
_pokemon = pokemon;
var effect = _pokemon.BattleData?.BattleSide.VolatileScripts.Add(new Side.FriendGuardEffect());
var effect = _pokemon.BattleSide.VolatileScripts.Add(new Side.FriendGuardEffect());
(effect?.Script as Side.FriendGuardEffect)?.OnAdded(_pokemon);
}
@@ -26,7 +26,7 @@ public class FriendGuard : Script
{
if (_pokemon is null)
return;
if (_pokemon.BattleData?.BattleSide.VolatileScripts.TryGet<Side.FriendGuardEffect>(out var script) == true)
if (_pokemon.BattleSide.VolatileScripts.TryGet<Side.FriendGuardEffect>(out var script) == true)
{
script.OnRemoved(_pokemon);
}

View File

@@ -10,14 +10,13 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Frisk : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
if (pokemon.BattleData?.BattleSide is null)
if (pokemon.BattleSide is null)
return;
// Check if the Pokémon has an opposing side
var opposingSide =
pokemon.BattleData.Battle.Sides.FirstOrDefault(side => side != pokemon.BattleData.BattleSide);
var opposingSide = pokemon.Battle.Sides.FirstOrDefault(side => side != pokemon.BattleSide);
if (opposingSide is null)
return;
@@ -28,7 +27,7 @@ public class Frisk : Script, IScriptOnSwitchIn
// If the opponent has a held item, reveal it
if (opponent.HeldItem != null)
{
pokemon.BattleData.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
Metadata = new Dictionary<StringKey, object?>
{

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class FullMetalBody : Script, IScriptPreventStatBoostChange
{
/// <inheritdoc />
public void PreventStatBoostChange(IPokemon target, Statistic stat, sbyte amount, bool selfInflicted,
public void PreventStatBoostChange(IBattlePokemon target, Statistic stat, sbyte amount, bool selfInflicted,
ref bool prevent)
{
if (selfInflicted)

View File

@@ -12,7 +12,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class FurCoat : Script, IScriptChangeIncomingMoveDamage
{
/// <inheritdoc />
public void ChangeIncomingMoveDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage)
public void ChangeIncomingMoveDamage(IExecutingMove move, IBattlePokemon target, byte hit, ref uint damage)
{
if (move.UseMove.Category == MoveCategory.Physical)
{

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Galvanize : Script, IScriptChangeMoveType, IScriptChangeDamageModifier
{
/// <inheritdoc />
public void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, ref TypeIdentifier? typeIdentifier)
public void ChangeMoveType(IExecutingMove move, IBattlePokemon target, byte hit, ref TypeIdentifier? typeIdentifier)
{
if (typeIdentifier?.Name == TypeNames.Normal &&
move.Battle.Library.StaticLibrary.Types.TryGetTypeIdentifier(TypeNames.Electric, out var electricType))
@@ -20,7 +20,7 @@ public class Galvanize : Script, IScriptChangeMoveType, IScriptChangeDamageModif
}
/// <inheritdoc />
public void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
public void ChangeDamageModifier(IExecutingMove move, IBattlePokemon target, byte hit, ref float modifier)
{
if (move.GetHitData(target, hit).Type?.Name == TypeNames.Electric)
modifier *= 1.2f;

View File

@@ -9,10 +9,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Gluttony : Script, IScriptOnDamage
{
/// <inheritdoc />
public void OnDamage(IPokemon pokemon, DamageSource source, uint oldHealth, uint newHealth)
public void OnDamage(IBattlePokemon pokemon, DamageSource source, uint oldHealth, uint newHealth)
{
if (pokemon.BattleData is null)
return;
var oldHealthFraction = (float)oldHealth / pokemon.MaxHealth;
var newHealthFraction = (float)newHealth / pokemon.MaxHealth;
if (!(oldHealthFraction >= 0.5f) || !(newHealthFraction < 0.5f))

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Gooey : Script, IScriptOnIncomingHit
{
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
if (!move.GetHitData(target, hit).IsContact)
return;

View File

@@ -10,8 +10,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class GrassPelt : Script, IScriptChangeIncomingMoveDefensiveStatValue
{
/// <inheritdoc />
public void ChangeIncomingMoveDefensiveStatValue(IExecutingMove move, IPokemon target, byte hit, uint offensiveStat,
StatisticSet<uint> statisticSet, Statistic stat, ref uint value)
public void ChangeIncomingMoveDefensiveStatValue(IExecutingMove move, IBattlePokemon target, byte hit,
uint offensiveStat, StatisticSet<uint> statisticSet, Statistic stat, ref uint value)
{
if (move.Battle.TerrainName == ScriptUtils.ResolveName<Terrain.GrassyTerrain>() && stat == Statistic.Defense)
value = value.MultiplyOrMax(1.5f);

View File

@@ -9,9 +9,9 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class GrassySurge : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battleData = pokemon.BattleData;
var battleData = pokemon;
if (battleData == null)
return;

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Guts : Script, IScriptChangeOffensiveStatValue
{
/// <inheritdoc />
public void ChangeOffensiveStatValue(IExecutingMove move, IPokemon target, byte hit, uint defensiveStat,
public void ChangeOffensiveStatValue(IExecutingMove move, IBattlePokemon target, byte hit, uint defensiveStat,
ImmutableStatisticSet<uint> targetStats, Statistic stat, ref uint value)
{
if (target.StatusScript.IsEmpty)

View File

@@ -8,12 +8,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "harvest")]
public class Harvest : Script, IScriptOnEndTurn
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Harvest can only be added to a Pokemon script source.");
_pokemon = pokemon;
}
@@ -21,12 +21,12 @@ public class Harvest : Script, IScriptOnEndTurn
/// <inheritdoc />
public void OnEndTurn(IScriptSource owner, IBattle battle)
{
if (_pokemon?.BattleData is null)
if (_pokemon is null)
return;
if (_pokemon.HeldItem is not null)
return;
var consumedBerry = _pokemon.BattleData.ConsumedItems.FirstOrDefault(x => x.Category == ItemCategory.Berry);
var consumedBerry = _pokemon.ConsumedItems.FirstOrDefault(x => x.Category == ItemCategory.Berry);
if (consumedBerry != null)
{
var rng = battle.Random;

View File

@@ -8,12 +8,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "healer")]
public class Healer : Script, IScriptOnEndTurn
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Harvest can only be added to a Pokemon script source.");
_pokemon = pokemon;
}
@@ -21,22 +21,22 @@ public class Healer : Script, IScriptOnEndTurn
/// <inheritdoc />
public void OnEndTurn(IScriptSource owner, IBattle battle)
{
if (_pokemon?.BattleData is null)
if (_pokemon is null)
return;
if (_pokemon.BattleData.Position > 0)
if (_pokemon.Position > 0)
{
var leftAlly = _pokemon.BattleData.BattleSide.Pokemon[_pokemon.BattleData.Position - 1];
var leftAlly = _pokemon.BattleSide.Pokemon[_pokemon.Position - 1];
TryClearStatus(battle, leftAlly);
}
if (_pokemon.BattleData.Position < _pokemon.BattleData.BattleSide.Pokemon.Count - 1)
if (_pokemon.Position < _pokemon.BattleSide.Pokemon.Count - 1)
{
var rightAlly = _pokemon.BattleData.BattleSide.Pokemon[_pokemon.BattleData.Position + 1];
var rightAlly = _pokemon.BattleSide.Pokemon[_pokemon.Position + 1];
TryClearStatus(battle, rightAlly);
}
}
private static void TryClearStatus(IBattle battle, IPokemon? leftAlly)
private static void TryClearStatus(IBattle battle, IBattlePokemon? leftAlly)
{
if (leftAlly is null)
return;

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Heatproof : Script, IScriptChangeBasePower
{
/// <inheritdoc />
public void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
public void ChangeBasePower(IExecutingMove move, IBattlePokemon target, byte hit, ref ushort basePower)
{
if (move.GetHitData(target, hit).Type?.Name == TypeNames.Fire)
{

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class HugePower : Script, IScriptChangeOffensiveStatValue
{
/// <inheritdoc />
public void ChangeOffensiveStatValue(IExecutingMove move, IPokemon target, byte hit, uint defensiveStat,
public void ChangeOffensiveStatValue(IExecutingMove move, IBattlePokemon target, byte hit, uint defensiveStat,
ImmutableStatisticSet<uint> targetStats, Statistic stat, ref uint value)
{
if (stat == Statistic.Attack)

View File

@@ -11,7 +11,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Hustle : Script, IScriptChangeOffensiveStatValue, IScriptChangeAccuracy
{
/// <inheritdoc />
public void ChangeOffensiveStatValue(IExecutingMove move, IPokemon target, byte hit, uint defensiveStat,
public void ChangeOffensiveStatValue(IExecutingMove move, IBattlePokemon target, byte hit, uint defensiveStat,
ImmutableStatisticSet<uint> targetStats, Statistic stat, ref uint value)
{
if (stat != Statistic.Attack)
@@ -20,7 +20,8 @@ public class Hustle : Script, IScriptChangeOffensiveStatValue, IScriptChangeAccu
}
/// <inheritdoc />
public void ChangeAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref int modifiedAccuracy)
public void ChangeAccuracy(IExecutingMove executingMove, IBattlePokemon target, byte hitIndex,
ref int modifiedAccuracy)
{
if (executingMove.UseMove.Category == MoveCategory.Physical)
{

View File

@@ -8,12 +8,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "hydration")]
public class Hydration : Script, IScriptOnEndTurn
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Hydration can only be added to a Pokemon script source.");
_pokemon = pokemon;
}

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class HyperCutter : Script, IScriptPreventStatBoostChange
{
/// <inheritdoc />
public void PreventStatBoostChange(IPokemon target, Statistic stat, sbyte amount, bool selfInflicted,
public void PreventStatBoostChange(IBattlePokemon target, Statistic stat, sbyte amount, bool selfInflicted,
ref bool prevent)
{
if (stat != Statistic.Attack)

View File

@@ -8,12 +8,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "ice_body")]
public class IceBody : Script, IScriptOnEndTurn, IScriptCustomTrigger
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Ice Body can only be added to a Pokemon script source.");
_pokemon = pokemon;
}

View File

@@ -8,24 +8,21 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "illusion")]
public class Illusion : Script, IScriptOnIncomingHit, IScriptOnSwitchIn
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Illusion can only be added to a Pokemon script source.");
_pokemon = pokemon;
}
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battleData = pokemon.BattleData;
if (battleData is null)
return;
var lastNonFaintedPokemon = battleData.Battle.Parties.FirstOrDefault(p => p.Party.Any(pkmn => pkmn == pokemon))
?.Party.WhereNotNull().FirstOrDefault(x => x.IsUsable);
var lastNonFaintedPokemon = pokemon.Battle.Parties.FirstOrDefault(p => p.BattlePokemon.Contains(pokemon))
?.BattlePokemon.WhereNotNull().FirstOrDefault(x => x.IsUsable);
if (lastNonFaintedPokemon is null || lastNonFaintedPokemon == pokemon)
return;
@@ -39,17 +36,17 @@ public class Illusion : Script, IScriptOnIncomingHit, IScriptOnSwitchIn
return;
_pokemon.SetDisplaySpecies(null, null);
_pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_pokemon));
_pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(_pokemon));
}
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
if (_pokemon?.BattleData?.Battle is null)
if (_pokemon?.Battle is null)
return;
// Remove the illusion when the Pokémon takes damage
_pokemon.SetDisplaySpecies(null, null);
_pokemon.BattleData.Battle.EventHook.Invoke(new AbilityTriggerEvent(_pokemon));
_pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(_pokemon));
}
}

View File

@@ -9,7 +9,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Immunity : Script, IScriptPreventStatusChange
{
/// <inheritdoc />
public void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, ref bool preventStatus)
public void PreventStatusChange(IBattlePokemon pokemon, StringKey status, bool selfInflicted,
ref bool preventStatus)
{
if (status == ScriptUtils.ResolveName<Status.Poisoned>() ||
status == ScriptUtils.ResolveName<Status.BadlyPoisoned>())

View File

@@ -10,7 +10,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class IncreasedStab : Script, IScriptChangeStabModifier
{
/// <inheritdoc />
public void ChangeStabModifier(IExecutingMove executingMove, IPokemon target, byte hitNumber, bool isStab,
public void ChangeStabModifier(IExecutingMove executingMove, IBattlePokemon target, byte hitNumber, bool isStab,
ref float modifier)
{
if (!isStab || !modifier.IsApproximatelyEqualTo(1.5f))

View File

@@ -8,16 +8,16 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "innards_out")]
public class InnardsOut : Script, IScriptOnIncomingHit, IScriptOnDamage
{
private IPokemon? _lastPokemonToHit;
private IBattlePokemon? _lastPokemonToHit;
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
_lastPokemonToHit = move.User;
}
/// <inheritdoc />
public void OnDamage(IPokemon pokemon, DamageSource source, uint oldHealth, uint newHealth)
public void OnDamage(IBattlePokemon pokemon, DamageSource source, uint oldHealth, uint newHealth)
{
if (newHealth != 0 || source is not DamageSource.MoveDamage)
return;
@@ -26,7 +26,7 @@ public class InnardsOut : Script, IScriptOnIncomingHit, IScriptOnDamage
EventBatchId batchId = new();
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
BatchId = batchId,
});

View File

@@ -10,12 +10,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "inner_focus")]
public class InnerFocus : Script, IScriptPreventVolatileAdd
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Illusion can only be added to a Pokemon script source.");
_pokemon = pokemon;
}
@@ -25,7 +25,7 @@ public class InnerFocus : Script, IScriptPreventVolatileAdd
{
if (script is not FlinchEffect)
return;
_pokemon?.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_pokemon));
_pokemon?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_pokemon));
preventVolatileAdd = true;
}
}

View File

@@ -9,11 +9,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Insomnia : Script, IScriptPreventStatusChange
{
/// <inheritdoc />
public void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, ref bool preventStatus)
public void PreventStatusChange(IBattlePokemon pokemon, StringKey status, bool selfInflicted,
ref bool preventStatus)
{
if (status != ScriptUtils.ResolveName<Status.Sleep>())
return;
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
preventStatus = true;
}
}

View File

@@ -9,14 +9,14 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Intimidate : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
var battle = pokemon.BattleData?.Battle;
var battle = pokemon.Battle;
if (battle is null)
return;
var opponents = battle.Sides.Where(side => side != pokemon.BattleData?.BattleSide)
.SelectMany(side => side.Pokemon).WhereNotNull().Where(opponent => opponent.IsUsable);
var opponents = battle.Sides.Where(side => side != pokemon.BattleSide).SelectMany(side => side.Pokemon)
.WhereNotNull().Where(opponent => opponent.IsUsable);
EventBatchId batchId = new();
battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class IronBarbs : Script, IScriptOnIncomingHit
{
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
if (move.GetHitData(target, hit).IsContact)
{

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class IronFist : Script, IScriptChangeBasePower
{
/// <inheritdoc />
public void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
public void ChangeBasePower(IExecutingMove move, IBattlePokemon target, byte hit, ref ushort basePower)
{
if (move.UseMove.HasFlag(MoveFlags.Punch))
basePower = basePower.MultiplyOrMax(1.2f);

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Justified : Script, IScriptOnIncomingHit
{
/// <inheritdoc />
public void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
public void OnIncomingHit(IExecutingMove move, IBattlePokemon target, byte hit)
{
if (move.GetHitData(target, hit).Type?.Name != TypeNames.Dark)
return;

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class KeenEye : Script, IScriptPreventStatBoostChange
{
/// <inheritdoc />
public void PreventStatBoostChange(IPokemon target, Statistic stat, sbyte amount, bool selfInflicted,
public void PreventStatBoostChange(IBattlePokemon target, Statistic stat, sbyte amount, bool selfInflicted,
ref bool prevent)
{
if (stat == Statistic.Accuracy && amount < 0)

View File

@@ -16,7 +16,7 @@ public class Klutz : Script, IScriptOnBeforeAnyHookInvoked, IScriptPreventHeldIt
}
/// <inheritdoc />
public void PreventHeldItemConsume(IPokemon pokemon, IItem heldItem, ref bool prevented)
public void PreventHeldItemConsume(IBattlePokemon pokemon, IItem heldItem, ref bool prevented)
{
prevented = true;
}

View File

@@ -9,9 +9,10 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class LeafGuard : Script, IScriptPreventStatusChange
{
/// <inheritdoc />
public void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, ref bool preventStatus)
public void PreventStatusChange(IBattlePokemon pokemon, StringKey status, bool selfInflicted,
ref bool preventStatus)
{
if (pokemon.BattleData?.Battle.WeatherName != ScriptUtils.ResolveName<Weather.HarshSunlight>())
if (pokemon.Battle.WeatherName != ScriptUtils.ResolveName<Weather.HarshSunlight>())
return;
if (selfInflicted)
return;

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Levitate : Script, IScriptIsFloating
{
/// <inheritdoc />
public void IsFloating(IPokemon pokemon, ref bool isFloating)
public void IsFloating(IBattlePokemon pokemon, ref bool isFloating)
{
isFloating = true;
}

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class LightningRod : Script, IScriptChangeIncomingTargets, IScriptChangeEffectiveness
{
/// <inheritdoc />
public void ChangeIncomingTargets(IMoveChoice moveChoice, ref IReadOnlyList<IPokemon?> targets)
public void ChangeIncomingTargets(IMoveChoice moveChoice, ref IReadOnlyList<IBattlePokemon?> targets)
{
if (moveChoice.ChosenMove.MoveData.MoveType.Name == TypeNames.Electric && targets.Count == 1)
{
@@ -18,7 +18,7 @@ public class LightningRod : Script, IScriptChangeIncomingTargets, IScriptChangeE
}
/// <inheritdoc />
public void ChangeEffectiveness(IExecutingMove move, IPokemon target, byte hit, ref float effectiveness)
public void ChangeEffectiveness(IExecutingMove move, IBattlePokemon target, byte hit, ref float effectiveness)
{
if (move.GetHitData(target, hit).Type?.Name != TypeNames.Electric)
return;

View File

@@ -9,7 +9,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Limber : Script, IScriptPreventStatusChange
{
/// <inheritdoc />
public void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, ref bool preventStatus)
public void PreventStatusChange(IBattlePokemon pokemon, StringKey status, bool selfInflicted,
ref bool preventStatus)
{
if (status != ScriptUtils.ResolveName<Status.Paralyzed>())
return;
@@ -18,7 +19,7 @@ public class Limber : Script, IScriptPreventStatusChange
if (selfInflicted)
return;
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
preventStatus = true;
}
}

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class LiquidVoice : Script, IScriptChangeMoveType
{
/// <inheritdoc />
public void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, ref TypeIdentifier? typeIdentifier)
public void ChangeMoveType(IExecutingMove move, IBattlePokemon target, byte hit, ref TypeIdentifier? typeIdentifier)
{
if (move.UseMove.HasFlag(MoveFlags.Sound) &&
move.Battle.Library.StaticLibrary.Types.TryGetTypeIdentifier(TypeNames.Water, out var waterType))

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class LongReach : Script, IScriptModifyIsContact
{
/// <inheritdoc />
public void ModifyIsContact(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool isContact)
public void ModifyIsContact(IExecutingMove executingMove, IBattlePokemon target, byte hitIndex, ref bool isContact)
{
isContact = false;
}

View File

@@ -9,12 +9,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class MagicBounce : Script, IScriptChangeIncomingTargets
{
/// <inheritdoc />
public void ChangeIncomingTargets(IMoveChoice moveChoice, ref IReadOnlyList<IPokemon?> targets)
public void ChangeIncomingTargets(IMoveChoice moveChoice, ref IReadOnlyList<IBattlePokemon?> targets)
{
if (moveChoice.ChosenMove.MoveData.HasFlag(MoveFlags.Reflectable))
{
var target = targets[0];
target?.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
targets = [moveChoice.User];
}
}

View File

@@ -9,11 +9,9 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class MagicGuard : Script, IScriptChangeIncomingDamage
{
/// <inheritdoc />
public void ChangeIncomingDamage(IPokemon pokemon, DamageSource source, ref uint damage)
public void ChangeIncomingDamage(IBattlePokemon pokemon, DamageSource source, ref uint damage)
{
// Magic Guard doesn't work if the Pokémon is not in battle.
if (pokemon.BattleData is null)
return;
if (source is DamageSource.MoveDamage or DamageSource.Struggle or DamageSource.FormChange)
{

View File

@@ -11,7 +11,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Magician : Script, IScriptOnSecondaryEffect
{
/// <inheritdoc />
public void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
public void OnSecondaryEffect(IExecutingMove move, IBattlePokemon target, byte hit)
{
if (move.UseMove.Category is MoveCategory.Status)
return;

View File

@@ -9,21 +9,22 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class MagmaArmor : Script, IScriptOnSwitchIn, IScriptPreventStatusChange
{
/// <inheritdoc />
public void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, ref bool preventStatus)
public void PreventStatusChange(IBattlePokemon pokemon, StringKey status, bool selfInflicted,
ref bool preventStatus)
{
if (status == ScriptUtils.ResolveName<Status.Frozen>())
{
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
preventStatus = true;
}
}
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
if (pokemon.HasStatus(ScriptUtils.ResolveName<Status.Frozen>()))
{
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
pokemon.ClearStatus();
}
}

View File

@@ -9,8 +9,8 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class MarvelScale : Script, IScriptChangeIncomingMoveDefensiveStatValue
{
/// <inheritdoc />
public void ChangeIncomingMoveDefensiveStatValue(IExecutingMove move, IPokemon target, byte hit, uint offensiveStat,
StatisticSet<uint> statisticSet, Statistic stat, ref uint value)
public void ChangeIncomingMoveDefensiveStatValue(IExecutingMove move, IBattlePokemon target, byte hit,
uint offensiveStat, StatisticSet<uint> statisticSet, Statistic stat, ref uint value)
{
if (!target.StatusScript.IsEmpty && stat == Statistic.Defense)
{

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class MegaLauncher : Script, IScriptChangeBasePower, IScriptCustomTrigger
{
/// <inheritdoc />
public void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
public void ChangeBasePower(IExecutingMove move, IBattlePokemon target, byte hit, ref ushort basePower)
{
if (move.UseMove.HasFlag(MoveFlags.Pulse))
{

View File

@@ -11,7 +11,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Merciless : Script, IScriptChangeCriticalStage
{
/// <inheritdoc />
public void ChangeCriticalStage(IExecutingMove move, IPokemon target, byte hit, ref byte stage)
public void ChangeCriticalStage(IExecutingMove move, IBattlePokemon target, byte hit, ref byte stage)
{
if (target.StatusScript.Script?.Name == ScriptUtils.ResolveName<Poisoned>() ||
target.StatusScript.Script?.Name == ScriptUtils.ResolveName<BadlyPoisoned>())

View File

@@ -9,10 +9,10 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Minus : Script, IScriptChangeOffensiveStatValue
{
/// <inheritdoc />
public void ChangeOffensiveStatValue(IExecutingMove move, IPokemon target, byte hit, uint defensiveStat,
public void ChangeOffensiveStatValue(IExecutingMove move, IBattlePokemon target, byte hit, uint defensiveStat,
ImmutableStatisticSet<uint> targetStats, Statistic stat, ref uint value)
{
var battleData = move.User.BattleData;
var battleData = move.User;
if (battleData is null)
return;
if (battleData.BattleSide.Pokemon.WhereNotNull()

View File

@@ -9,20 +9,20 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class MistySurge : Script, IScriptOnSwitchIn
{
/// <inheritdoc />
public void OnSwitchIn(IPokemon pokemon, byte position)
public void OnSwitchIn(IBattlePokemon pokemon, byte position)
{
if (pokemon.BattleData?.Battle is null)
if (pokemon.Battle is null)
return;
var terrainName = ScriptUtils.ResolveName<Terrain.MistyTerrain>();
if (pokemon.BattleData.Battle.TerrainName == terrainName)
if (pokemon.Battle.TerrainName == terrainName)
return;
EventBatchId batchId = new();
pokemon.BattleData.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
pokemon.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
BatchId = batchId,
});
pokemon.BattleData.Battle.SetTerrain(terrainName, batchId);
pokemon.Battle.SetTerrain(terrainName, batchId);
}
}

View File

@@ -8,12 +8,12 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "moody")]
public class Moody : Script, IScriptOnEndTurn
{
private IPokemon? _pokemon;
private IBattlePokemon? _pokemon;
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is not IPokemon pokemon)
if (source is not IBattlePokemon pokemon)
throw new InvalidOperationException("Moody script must be attached to a Pokemon.");
_pokemon = pokemon;
}

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class MotorDrive : Script, IScriptIsInvulnerableToMove
{
/// <inheritdoc />
public void IsInvulnerableToMove(IExecutingMove move, IPokemon target, ref bool invulnerable)
public void IsInvulnerableToMove(IExecutingMove move, IBattlePokemon target, ref bool invulnerable)
{
if (move.UseMove.MoveType.Name != TypeNames.Electric)
return;

View File

@@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
public class Moxie : Script, IScriptOnOpponentFaints
{
/// <inheritdoc />
public void OnOpponentFaints(IExecutingMove move, IPokemon target, byte hit)
public void OnOpponentFaints(IExecutingMove move, IBattlePokemon target, byte hit)
{
move.User.ChangeStatBoost(Statistic.Attack, 1, true, false);
}

Some files were not shown because too many files have changed in this diff Show More