From 802481c1f51eb1f379637e9010f8feb9698df6e1 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sun, 26 Jan 2025 10:48:13 +0100 Subject: [PATCH] Adds bind --- PkmnLib.Dynamic/ScriptHandling/Script.cs | 4 ++ PkmnLib.Static/Utils/DictionaryHelpers.cs | 11 +++++ PkmnLib.Tests/Data/Moves.json | 5 +- .../Scripts/CustomTriggers.cs | 12 +++++ .../Scripts/Moves/AuroraVeil.cs | 13 +++++- .../PkmnLib.Plugin.Gen7/Scripts/Moves/Bind.cs | 27 +++++++++++ .../Scripts/Pokemon/BindEffect.cs | 46 +++++++++++++++++++ 7 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 PkmnLib.Static/Utils/DictionaryHelpers.cs create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/CustomTriggers.cs create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Bind.cs create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/BindEffect.cs diff --git a/PkmnLib.Dynamic/ScriptHandling/Script.cs b/PkmnLib.Dynamic/ScriptHandling/Script.cs index 2582f9a..1e76680 100644 --- a/PkmnLib.Dynamic/ScriptHandling/Script.cs +++ b/PkmnLib.Dynamic/ScriptHandling/Script.cs @@ -512,4 +512,8 @@ public abstract class Script : IDeepCloneable public virtual void BlockIncomingHit(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref bool block) { } + + public virtual void CustomTrigger(StringKey eventName, IDictionary? parameters) + { + } } \ No newline at end of file diff --git a/PkmnLib.Static/Utils/DictionaryHelpers.cs b/PkmnLib.Static/Utils/DictionaryHelpers.cs new file mode 100644 index 0000000..13ab1e7 --- /dev/null +++ b/PkmnLib.Static/Utils/DictionaryHelpers.cs @@ -0,0 +1,11 @@ +namespace PkmnLib.Static.Utils; + +public static class DictionaryHelpers +{ + public static TValue GetOrDefault(this IDictionary dictionary, TKey key, TValue defaultValue) + { + if (dictionary.TryGetValue(key, out var value)) + return value; + return defaultValue; + } +} \ No newline at end of file diff --git a/PkmnLib.Tests/Data/Moves.json b/PkmnLib.Tests/Data/Moves.json index 54e23d8..baff058 100755 --- a/PkmnLib.Tests/Data/Moves.json +++ b/PkmnLib.Tests/Data/Moves.json @@ -845,7 +845,10 @@ "contact", "protect", "mirror" - ] + ], + "effect": { + "name": "bind" + } }, { "name": "bite", diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/CustomTriggers.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/CustomTriggers.cs new file mode 100644 index 0000000..9b043ea --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/CustomTriggers.cs @@ -0,0 +1,12 @@ +using PkmnLib.Static.Utils; + +namespace PkmnLib.Plugin.Gen7.Scripts; + +public static class CustomTriggers +{ + public static readonly StringKey AuroraVeilDuration = "aurora_veil_duration"; + + public static readonly StringKey BindNumberOfTurns = "bind_number_of_turns"; + + public static readonly StringKey BindPercentOfMaxHealth = "bind_percent_of_max_health"; +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/AuroraVeil.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/AuroraVeil.cs index ba9eb0c..b9b1c6f 100644 --- a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/AuroraVeil.cs +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/AuroraVeil.cs @@ -1,8 +1,11 @@ +using System.Collections.Generic; using PkmnLib.Dynamic.Models; using PkmnLib.Dynamic.ScriptHandling; using PkmnLib.Dynamic.ScriptHandling.Registry; +using PkmnLib.Plugin.Gen7.Scripts; using PkmnLib.Plugin.Gen7.Scripts.Side; using PkmnLib.Plugin.Gen7.Scripts.Weather; +using PkmnLib.Static.Utils; namespace PkmnLib.Plugin.Gen7.Moves; @@ -41,7 +44,15 @@ public class AuroraVeil : Script } var side = battle.Sides[move.User.BattleData!.SideIndex]; - var numberOfTurns = move.User.HasHeldItem("light_clay") ? 8 : 5; + + var numberOfTurns = 5; + var dict = new Dictionary() + { + { "duration", numberOfTurns } + }; + move.User.RunScriptHook(x => x.CustomTrigger(CustomTriggers.AuroraVeilDuration, dict)); + numberOfTurns = (int)dict.GetOrDefault("duration", numberOfTurns)!; + var script = side.VolatileScripts.StackOrAdd(ScriptUtils.ResolveName(), () => { var effect = new AuroraVeilEffect(numberOfTurns); diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Bind.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Bind.cs new file mode 100644 index 0000000..70bbda2 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Moves/Bind.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using PkmnLib.Dynamic.Models; +using PkmnLib.Dynamic.ScriptHandling; +using PkmnLib.Dynamic.ScriptHandling.Registry; +using PkmnLib.Plugin.Gen7.Scripts.Pokemon; +using PkmnLib.Static.Utils; + +namespace PkmnLib.Plugin.Gen7.Scripts.Moves; + +[Script(ScriptCategory.Move, "bind")] +public class Bind : Script +{ + /// + public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit) + { + var bindTurnsParameters = new Dictionary { { "bind_number_of_turns", 5 } }; + move.User.RunScriptHook(x => x.CustomTrigger(CustomTriggers.BindNumberOfTurns, bindTurnsParameters)); + var bindDamageParameters = new Dictionary { { "bind_percent_of_max_health", 1f / 8f } }; + move.User.RunScriptHook(x => x.CustomTrigger(CustomTriggers.BindPercentOfMaxHealth, bindDamageParameters)); + + var bindTurns = bindTurnsParameters.GetOrDefault("bind_number_of_turns", 5) as int? ?? 5; + var bindDamage = bindDamageParameters.GetOrDefault("bind_percent_of_max_health", 1f / 8f) as float? ?? 1f / 8f; + + var bindEffect = new BindEffect(target, bindTurns, bindDamage); + target.Volatile.Add(bindEffect); + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/BindEffect.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/BindEffect.cs new file mode 100644 index 0000000..946be2e --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Pokemon/BindEffect.cs @@ -0,0 +1,46 @@ +using PkmnLib.Dynamic.Models; +using PkmnLib.Dynamic.Models.Choices; +using PkmnLib.Dynamic.ScriptHandling; +using PkmnLib.Dynamic.ScriptHandling.Registry; + +namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon; + +[Script(ScriptCategory.Pokemon, "bind")] +public class BindEffect : Script +{ + private readonly IPokemon? _owner; + private int _turns; + private readonly float _percentOfMaxHealth; + + private BindEffect(float percentOfMaxHealth) + { + _percentOfMaxHealth = percentOfMaxHealth; + } + + public BindEffect(IPokemon owner, int turns, float percentOfMaxHealth) + { + _owner = owner; + _turns = turns; + _percentOfMaxHealth = percentOfMaxHealth; + } + + /// + public override void OnEndTurn(IBattle battle) + { + if (_owner == null) + return; + if (_turns > 0) + { + _turns--; + _owner.Damage((uint)(_owner.MaxHealth * _percentOfMaxHealth), DamageSource.Misc); + } + if (_turns <= 0) + RemoveSelf(); + } + + /// + public override void PreventSelfSwitch(ISwitchChoice choice, ref bool prevent) => prevent = _turns > 0; + + /// + public override void PreventSelfRunAway(IFleeChoice choice, ref bool prevent) => prevent = _turns > 0; +} \ No newline at end of file