diff --git a/PkmnLib.Dynamic/ScriptHandling/Script.cs b/PkmnLib.Dynamic/ScriptHandling/Script.cs index 410d0c5..297f04e 100644 --- a/PkmnLib.Dynamic/ScriptHandling/Script.cs +++ b/PkmnLib.Dynamic/ScriptHandling/Script.cs @@ -774,7 +774,7 @@ public abstract class Script : IDeepCloneable /// /// This function allows a script to prevent a Pokémon from being affected by a volatile status condition. /// - public virtual void PreventVolatileAdd(Script script, ref bool preventVolatileAdd) + public virtual void PreventVolatileAdd(IScriptSource parent, Script script, ref bool preventVolatileAdd) { } diff --git a/PkmnLib.Dynamic/ScriptHandling/ScriptSet.cs b/PkmnLib.Dynamic/ScriptHandling/ScriptSet.cs index 135bf91..5ab6681 100644 --- a/PkmnLib.Dynamic/ScriptHandling/ScriptSet.cs +++ b/PkmnLib.Dynamic/ScriptHandling/ScriptSet.cs @@ -86,7 +86,7 @@ public interface IScriptSet : IEnumerable /// public class ScriptSet : IScriptSet { - private IScriptSource _source; + private readonly IScriptSource _source; private readonly List _scripts = []; @@ -108,7 +108,7 @@ public class ScriptSet : IScriptSet if (!forceAdd) { var preventVolatileAdd = false; - _source.RunScriptHook(x => x.PreventVolatileAdd(script, ref preventVolatileAdd)); + _source.RunScriptHook(x => x.PreventVolatileAdd(_source, script, ref preventVolatileAdd)); if (preventVolatileAdd) return null; } diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/InnerFocus.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/InnerFocus.cs index 1bdd4c7..d772b58 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/InnerFocus.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/InnerFocus.cs @@ -21,7 +21,7 @@ public class InnerFocus : Script } /// - public override void PreventVolatileAdd(Script script, ref bool preventVolatileAdd) + public override void PreventVolatileAdd(IScriptSource parent, Script script, ref bool preventVolatileAdd) { if (script is not FlinchEffect) return; diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Oblivious.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Oblivious.cs index 7a3f8c0..7955420 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Oblivious.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Oblivious.cs @@ -11,7 +11,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; public class Oblivious : Script { /// - public override void PreventVolatileAdd(Script script, ref bool preventVolatileAdd) + public override void PreventVolatileAdd(IScriptSource parent, Script script, ref bool preventVolatileAdd) { preventVolatileAdd = script switch { diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/OwnTempo.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/OwnTempo.cs index cf61eb8..07931bb 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/OwnTempo.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/OwnTempo.cs @@ -9,7 +9,7 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; public class OwnTempo : Script { /// - public override void PreventVolatileAdd(Script script, ref bool preventVolatileAdd) + public override void PreventVolatileAdd(IScriptSource parent, Script script, ref bool preventVolatileAdd) { if (script is Pokemon.Confusion) preventVolatileAdd = true; diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/SafeguardEffect.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/SafeguardEffect.cs index 590d3b5..5c1f12f 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/SafeguardEffect.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/SafeguardEffect.cs @@ -12,7 +12,7 @@ public class SafeguardEffect : Script } /// - public override void PreventVolatileAdd(Script script, ref bool preventVolatileAdd) + public override void PreventVolatileAdd(IScriptSource parent, Script script, ref bool preventVolatileAdd) { if (script.Category == ScriptCategory.Pokemon && script.Name == ScriptUtils.ResolveName()) preventVolatileAdd = true; diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/ElectricTerrain.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/ElectricTerrain.cs index 8d737d1..2c2d6f8 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/ElectricTerrain.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/ElectricTerrain.cs @@ -3,5 +3,36 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Terrain; [Script(ScriptCategory.Terrain, "electric_terrain")] public class ElectricTerrain : Script { - // TODO: Implement Terrain + private static bool IsAffectedByTerrain(IPokemon pokemon) => + !pokemon.IsFloating; + + /// + public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower) + { + if (!IsAffectedByTerrain(move.User)) + return; + var type = move.GetHitData(target, hit).Type; + if (type?.Name == "electric") + basePower = basePower.MultiplyOrMax(1.5f); + } + + /// + public override void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, + ref bool preventStatus) + { + if (!IsAffectedByTerrain(pokemon)) + return; + if (status == ScriptUtils.ResolveName()) + preventStatus = true; + } + + /// + public override void PreventVolatileAdd(IScriptSource parent, Script script, ref bool preventVolatileAdd) + { + if (parent is IPokemon pokemon && !IsAffectedByTerrain(pokemon)) + return; + + if (script is Pokemon.YawnEffect) + preventVolatileAdd = true; + } } \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/GrassyTerrain.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/GrassyTerrain.cs index d82c38a..1174d52 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/GrassyTerrain.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/GrassyTerrain.cs @@ -3,5 +3,46 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Terrain; [Script(ScriptCategory.Terrain, "grassy_terrain")] public class GrassyTerrain : Script { - // TODO: Implement Terrain + private static bool IsAffectedByTerrain(IPokemon pokemon) => + !pokemon.IsFloating; + + /// + public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower) + { + // It boosts the power of Grass-type moves used by affected Pokémon by 50% (regardless of whether the target of + // the move is affected by Grassy Terrain). + if (IsAffectedByTerrain(move.User)) + { + var type = move.GetHitData(target, hit).Type; + if (type?.Name == "grass") + { + basePower = basePower.MultiplyOrMax(1.5f); + } + } + + // The power of Bulldoze, Earthquake, and Magnitude is halved against affected targets (regardless of whether the + // user of the move is affected by Grassy Terrain). + if (IsAffectedByTerrain(target)) + { + var moveName = move.UseMove.Name; + if (moveName == "bulldoze" || moveName == "earthquake" || moveName == "magnitude") + { + basePower /= 2; + } + } + } + + /// + public override void OnEndTurn(IScriptSource owner, IBattle battle) + { + // At the end of each turn, Grassy Terrain restores 1/16 of the maximum HP of each affected Pokémon. + foreach (var pokemon in battle.Sides.SelectMany(x => x.Pokemon).WhereNotNull()) + { + if (!IsAffectedByTerrain(pokemon) || pokemon.IsFainted) + continue; + + var healing = pokemon.MaxHealth / 16f; + pokemon.Heal((uint)healing); + } + } } \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/MistyTerrain.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/MistyTerrain.cs index 029ca0a..86ee828 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/MistyTerrain.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/MistyTerrain.cs @@ -3,5 +3,26 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Terrain; [Script(ScriptCategory.Terrain, "misty_terrain")] public class MistyTerrain : Script { - // TODO: Implement Terrain + private static bool IsAffectedByTerrain(IPokemon pokemon) => + !pokemon.IsFloating; + + /// + public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower) + { + if (!IsAffectedByTerrain(target)) + return; + if (move.GetHitData(target, hit).Type?.Name == "dragon") + { + basePower /= 2; + } + } + + /// + public override void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, + ref bool preventStatus) + { + if (!IsAffectedByTerrain(pokemon)) + return; + preventStatus = true; + } } \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/PsychicTerrain.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/PsychicTerrain.cs index 489d8db..62cb6f9 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/PsychicTerrain.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Terrain/PsychicTerrain.cs @@ -3,5 +3,34 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Terrain; [Script(ScriptCategory.Terrain, "psychic_terrain")] public class PsychicTerrain : Script { - // TODO: Implement Terrain + private static bool IsAffectedByTerrain(IPokemon pokemon) => + !pokemon.IsFloating; + + /// + public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower) + { + if (!IsAffectedByTerrain(move.User)) + return; + + // It boosts the power of Psychic-type moves used by affected Pokémon by 50% (regardless of whether the target of + // the move is affected by Psychic Terrain). + var type = move.GetHitData(target, hit).Type; + if (type?.Name == "psychic") + { + basePower = basePower.MultiplyOrMax(1.5f); + } + } + + /// + public override void IsInvulnerableToMove(IExecutingMove move, IPokemon target, ref bool invulnerable) + { + if (!IsAffectedByTerrain(target)) + return; + + // Psychic Terrain prevents priority moves from affecting affected Pokémon. + if (move.MoveChoice.Priority > 0) + { + invulnerable = true; + } + } } \ No newline at end of file