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