diff --git a/PkmnLib.Dynamic/Models/Pokemon.cs b/PkmnLib.Dynamic/Models/Pokemon.cs
index 94e2ed6..6e5ee65 100644
--- a/PkmnLib.Dynamic/Models/Pokemon.cs
+++ b/PkmnLib.Dynamic/Models/Pokemon.cs
@@ -450,6 +450,8 @@ public interface IPokemonBattleData : IDeepCloneable
void MarkItemAsConsumed(IItem itemName);
uint SwitchInTurn { get; internal set; }
+
+ IBattleSide BattleSide { get; }
}
///
@@ -1254,4 +1256,7 @@ public class PokemonBattleDataImpl : IPokemonBattleData
///
public uint SwitchInTurn { get; set; }
+
+ ///
+ public IBattleSide BattleSide => Battle.Sides[SideIndex];
}
\ No newline at end of file
diff --git a/PkmnLib.Tests/Data/Moves.json b/PkmnLib.Tests/Data/Moves.json
index 5680291..8a9fccd 100755
--- a/PkmnLib.Tests/Data/Moves.json
+++ b/PkmnLib.Tests/Data/Moves.json
@@ -6178,7 +6178,10 @@
"protect",
"reflectable",
"mirror"
- ]
+ ],
+ "effect": {
+ "name": "leech_seed"
+ }
},
{
"name": "leer",
@@ -6215,7 +6218,14 @@
"contact",
"protect",
"mirror"
- ]
+ ],
+ "effect": {
+ "name": "set_status",
+ "chance": 30,
+ "parameters": {
+ "status": "paralyzed"
+ }
+ }
},
{
"name": "light_of_ruin",
@@ -6229,7 +6239,13 @@
"flags": [
"protect",
"mirror"
- ]
+ ],
+ "effect": {
+ "name": "recoil",
+ "parameters": {
+ "recoil_percentage": 0.5
+ }
+ }
},
{
"name": "light_screen",
@@ -6242,7 +6258,10 @@
"category": "status",
"flags": [
"snatch"
- ]
+ ],
+ "effect": {
+ "name": "light_screen"
+ }
},
{
"name": "liquidation",
@@ -6257,7 +6276,14 @@
"contact",
"protect",
"mirror"
- ]
+ ],
+ "effect": {
+ "name": "change_target_defense",
+ "chance": 20,
+ "parameters": {
+ "amount": -1
+ }
+ }
},
{
"name": "lock_on",
diff --git a/Plugins/PkmnLib.Plugin.Gen7/Libraries/Gen7BattleStatCalculator.cs b/Plugins/PkmnLib.Plugin.Gen7/Libraries/Gen7BattleStatCalculator.cs
index 8b7cb00..fa05f16 100644
--- a/Plugins/PkmnLib.Plugin.Gen7/Libraries/Gen7BattleStatCalculator.cs
+++ b/Plugins/PkmnLib.Plugin.Gen7/Libraries/Gen7BattleStatCalculator.cs
@@ -58,6 +58,8 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
x => x.ChangeAccuracyModifier(executingMove, target, hitIndex, ref accuracyModifier));
var modifiedAccuracy = (int)(moveAccuracy * accuracyModifier);
executingMove.RunScriptHook(x => x.ChangeAccuracy(executingMove, target, hitIndex, ref modifiedAccuracy));
+ if (modifiedAccuracy == 255)
+ return 255;
var targetEvasion = target.StatBoost.Evasion;
var ignoreEvasion = false;
executingMove.RunScriptHook(x => x.BypassEvasionStatBoosts(executingMove, target, hitIndex, ref ignoreEvasion));
diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/CustomTriggers.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/CustomTriggers.cs
index 4083fdd..392d3f8 100644
--- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/CustomTriggers.cs
+++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/CustomTriggers.cs
@@ -9,4 +9,8 @@ public static class CustomTriggers
public static readonly StringKey BindNumberOfTurns = "bind_number_of_turns";
public static readonly StringKey BindPercentOfMaxHealth = "bind_percent_of_max_health";
+
+ public static readonly StringKey IgnoreHail = "ignores_hail";
+
+ public static readonly StringKey LightScreenNumberOfTurns = "light_screen_number_of_turns";
}
\ No newline at end of file
diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/LeechSeed.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/LeechSeed.cs
new file mode 100644
index 0000000..9ed2893
--- /dev/null
+++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/LeechSeed.cs
@@ -0,0 +1,19 @@
+using System.Linq;
+using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
+
+namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
+
+[Script(ScriptCategory.Move, "leech_seed")]
+public class LeechSeed : Script
+{
+ ///
+ public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
+ {
+ if (target.Types.Any(x => x.Name == "grass"))
+ {
+ move.GetHitData(target, hit).Fail();
+ return;
+ }
+ target.Volatile.Add(new LeechSeedEffect(target, move.User));
+ }
+}
\ No newline at end of file
diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/LightScreen.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/LightScreen.cs
new file mode 100644
index 0000000..13f97a3
--- /dev/null
+++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/LightScreen.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using PkmnLib.Plugin.Gen7.Scripts.Side;
+using PkmnLib.Static.Utils;
+
+namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
+
+[Script(ScriptCategory.Move, "light_screen")]
+public class LightScreen : Script
+{
+ ///
+ public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
+ {
+ var battleData = move.User.BattleData;
+ if (battleData == null)
+ return;
+
+ var turns = 5;
+ var dict = new Dictionary()
+ {
+ { "duration", turns },
+ };
+ move.RunScriptHook(x => x.CustomTrigger(CustomTriggers.LightScreenNumberOfTurns, dict));
+ turns = (int)dict.GetOrDefault("duration", turns)!;
+
+ battleData.BattleSide.VolatileScripts.StackOrAdd(ScriptUtils.ResolveName(),
+ () => new LightScreenEffect(turns));
+ }
+}
\ No newline at end of file
diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/LeechSeedEffect.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/LeechSeedEffect.cs
new file mode 100644
index 0000000..ce59aaa
--- /dev/null
+++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/LeechSeedEffect.cs
@@ -0,0 +1,28 @@
+namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
+
+[Script(ScriptCategory.Pokemon, "leech_seed")]
+public class LeechSeedEffect : Script
+{
+ private readonly IPokemon _owner;
+ private readonly IPokemon _placer;
+
+ public LeechSeedEffect(IPokemon owner, IPokemon placer)
+ {
+ _owner = owner;
+ _placer = placer;
+ }
+
+ ///
+ public override void OnEndTurn(IBattle battle)
+ {
+ var damage = _owner.BoostedStats.Hp / 8;
+ if (_owner.CurrentHealth <= damage)
+ damage = _owner.CurrentHealth;
+
+ _owner.Damage(damage, DamageSource.Misc);
+ if (_owner.ActiveAbility?.Name == "liquid_ooze")
+ _placer.Damage(damage, DamageSource.Misc);
+ else
+ _placer.Heal(damage);
+ }
+}
\ No newline at end of file
diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/LightScreenEffect.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/LightScreenEffect.cs
index a363d02..d1b238b 100644
--- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/LightScreenEffect.cs
+++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Side/LightScreenEffect.cs
@@ -1,7 +1,32 @@
+using PkmnLib.Static.Moves;
+
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
[Script(ScriptCategory.Side, "light_screen")]
-public class LightScreenEffect : Script
+public class LightScreenEffect(int turns) : Script
{
- // TODO: Implement LightScreenEffect
+ private int _turns = turns;
+
+ ///
+ public override void ChangeIncomingMoveDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage)
+ {
+ if (move.UseMove.Category != MoveCategory.Special ||
+ // Critical hits are not affected by the barrier
+ move.GetHitData(target, hit).IsCritical)
+ return;
+ var battleData = target.BattleData;
+ // If not a 1v1 battle, damage reduction is only 1/3rd.
+ if (battleData?.Battle.PositionsPerSide > 1)
+ damage = (uint)(damage * (2.0f / 3.0f));
+ else
+ damage = (uint)(damage * 0.5f);
+ }
+
+ ///
+ public override void OnEndTurn(IBattle battle)
+ {
+ _turns -= 1;
+ if (_turns <= 0)
+ RemoveSelf();
+ }
}
\ No newline at end of file
diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Weather/Hail.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Weather/Hail.cs
index fbdc70b..79d421b 100644
--- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Weather/Hail.cs
+++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Weather/Hail.cs
@@ -32,10 +32,11 @@ public class Hail : Script, IWeatherScript
if (pokemon.Types.Contains(iceType))
continue;
var ignoresHail = false;
- pokemon.RunScriptHook(x => x.CustomTrigger("ignores_hail", new Dictionary()
- {
- { "ignoresHail", ignoresHail },
- }));
+ pokemon.RunScriptHook(x => x.CustomTrigger(CustomTriggers.IgnoreHail,
+ new Dictionary()
+ {
+ { "ignoresHail", ignoresHail },
+ }));
if (ignoresHail)
continue;