Move all battle state from IPokemon to an ephemeral IBattlePokemon wrapper
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>())
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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?>
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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>())
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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>())
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user