From df9846b8d8ce6c6921cab899668ceef399ad8bca Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 14 Jun 2025 12:25:29 +0200 Subject: [PATCH] More abilities --- .../PkmnLib.Plugin.Gen7/Data/Abilities.jsonc | 31 ++++-- Plugins/PkmnLib.Plugin.Gen7/Data/Moves.jsonc | 61 +++++------ Plugins/PkmnLib.Plugin.Gen7/Data/Pokemon.json | 102 ++++++++++++++++++ .../Scripts/Abilities/RKSSystem.cs | 31 ++++++ .../Scripts/Abilities/RainDish.cs | 40 +++++++ .../Scripts/Abilities/Rattled.cs | 22 ++++ .../Scripts/Abilities/Reckless.cs | 19 ++++ .../Scripts/Abilities/Refrigerate.cs | 26 +++++ .../Scripts/Abilities/Regenerator.cs | 24 +++++ .../Scripts/Abilities/Rivalry.cs | 23 ++++ 10 files changed, 338 insertions(+), 41 deletions(-) create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/RKSSystem.cs create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/RainDish.cs create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Rattled.cs create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Reckless.cs create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Refrigerate.cs create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Regenerator.cs create mode 100644 Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Rivalry.cs diff --git a/Plugins/PkmnLib.Plugin.Gen7/Data/Abilities.jsonc b/Plugins/PkmnLib.Plugin.Gen7/Data/Abilities.jsonc index 189ea87..6b869bc 100755 --- a/Plugins/PkmnLib.Plugin.Gen7/Data/Abilities.jsonc +++ b/Plugins/PkmnLib.Plugin.Gen7/Data/Abilities.jsonc @@ -473,19 +473,34 @@ "quick_feet": { "effect": "quick_feet" }, - "rain_dish": {}, - "rattled": {}, + "rain_dish": { + "effect": "rain_dish" + }, + "rattled": { + "effect": "rattled" + }, "receiver": { "flags": [ "cant_be_copied" - ] + ], + // This ability has the exact same effect as Power of Alchemy + "effect": "power_of_alchemy" + }, + "reckless": { + "effect": "reckless" + }, + "refrigerate": { + "effect": "refrigerate" + }, + "regenerator": { + "effect": "regenerator" + }, + "rivalry": { + "effect": "rivalry" }, - "reckless": {}, - "refrigerate": {}, - "regenerator": {}, - "rivalry": {}, "rks_system": { - "canBeChanged": false + "canBeChanged": false, + "effect": "rks_system" }, "rock_head": {}, "rough_skin": {}, diff --git a/Plugins/PkmnLib.Plugin.Gen7/Data/Moves.jsonc b/Plugins/PkmnLib.Plugin.Gen7/Data/Moves.jsonc index 445c248..25dc2e1 100755 --- a/Plugins/PkmnLib.Plugin.Gen7/Data/Moves.jsonc +++ b/Plugins/PkmnLib.Plugin.Gen7/Data/Moves.jsonc @@ -1175,7 +1175,8 @@ "contact", "protect", "mirror", - "distance" + "distance", + "recoil" ], "effect": { "name": "recoil", @@ -2557,7 +2558,8 @@ "flags": [ "contact", "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "recoil", @@ -3833,7 +3835,8 @@ "contact", "protect", "mirror", - "defrost" + "defrost", + "recoil" ], "effect": { "name": "flare_blitz" @@ -4912,7 +4915,8 @@ "flags": [ "contact", "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "recoil", @@ -4933,7 +4937,8 @@ "flags": [ "contact", "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "recoil", @@ -5234,7 +5239,8 @@ "contact", "protect", "mirror", - "gravity" + "gravity", + "recoil" ], "effect": { "name": "high_jump_kick" @@ -5982,7 +5988,8 @@ "contact", "protect", "mirror", - "gravity" + "gravity", + "recoil" ], "effect": { "name": "high_jump_kick" @@ -6299,7 +6306,8 @@ "category": "special", "flags": [ "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "recoil", @@ -6336,7 +6344,8 @@ "flags": [ "contact", "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "change_target_defense", @@ -11123,7 +11132,8 @@ "flags": [ "contact", "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "recoil", @@ -11585,7 +11595,8 @@ "flags": [ "contact", "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "recoil", @@ -11841,25 +11852,6 @@ } } }, - { - "name": "thunder_fang", - "type": "electric", - "power": 65, - "pp": 15, - "accuracy": 95, - "priority": 0, - "target": "Any", - "category": "physical", - "flags": [ - "contact", - "protect", - "mirror", - "bite" - ], - "effect": { - "name": "thunder_fang" - } - }, { "name": "thunder_punch", "type": "electric", @@ -12450,7 +12442,8 @@ "flags": [ "contact", "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "volt_tackle" @@ -12680,7 +12673,8 @@ "flags": [ "contact", "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "recoil", @@ -12791,7 +12785,8 @@ "flags": [ "contact", "protect", - "mirror" + "mirror", + "recoil" ], "effect": { "name": "recoil", diff --git a/Plugins/PkmnLib.Plugin.Gen7/Data/Pokemon.json b/Plugins/PkmnLib.Plugin.Gen7/Data/Pokemon.json index 12e7e4f..2b3a712 100755 --- a/Plugins/PkmnLib.Plugin.Gen7/Data/Pokemon.json +++ b/Plugins/PkmnLib.Plugin.Gen7/Data/Pokemon.json @@ -115609,6 +115609,108 @@ ], "formeChange": [] } + }, + "silvally_dark": { + "inheritFrom": "default", + "types": [ + "dark" + ] + }, + "silvally_dragon": { + "inheritFrom": "default", + "types": [ + "dragon" + ] + }, + "silvally_electric": { + "inheritFrom": "default", + "types": [ + "electric" + ] + }, + "silvally_fairy": { + "inheritFrom": "default", + "types": [ + "fairy" + ] + }, + "silvally_fighting": { + "inheritFrom": "default", + "types": [ + "fighting" + ] + }, + "silvally_fire": { + "inheritFrom": "default", + "types": [ + "fire" + ] + }, + "silvally_flying": { + "inheritFrom": "default", + "types": [ + "flying" + ] + }, + "silvally_ghost": { + "inheritFrom": "default", + "types": [ + "ghost" + ] + }, + "silvally_grass": { + "inheritFrom": "default", + "types": [ + "grass" + ] + }, + "silvally_ground": { + "inheritFrom": "default", + "types": [ + "ground" + ] + }, + "silvally_ice": { + "inheritFrom": "default", + "types": [ + "ice" + ] + }, + "silvally_poison": { + "inheritFrom": "default", + "types": [ + "poison" + ] + }, + "silvally_psychic": { + "inheritFrom": "default", + "types": [ + "psychic" + ] + }, + "silvally_rock": { + "inheritFrom": "default", + "types": [ + "rock" + ] + }, + "silvally_steel": { + "inheritFrom": "default", + "types": [ + "steel" + ] + }, + "silvally_water": { + "inheritFrom": "default", + "types": [ + "water" + ] + }, + "silvally_normal": { + "inheritFrom": "default", + "types": [ + "normal" + ] } }, "evolutions": [] diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/RKSSystem.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/RKSSystem.cs new file mode 100644 index 0000000..5b96164 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/RKSSystem.cs @@ -0,0 +1,31 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// RKS System is an ability that changes the Pokémon's type based on its held Memory. +/// +/// Bulbapedia - RKS System +/// +[Script(ScriptCategory.Ability, "rks_system")] +public class RKSSystem : Script +{ + /// + public override void OnAfterHeldItemChange(IPokemon pokemon, IItem? previous, IItem? item) + { + if (pokemon.Species.Name != "silvally") + return; + if (item is null && pokemon.Form.Name != "default") + { + pokemon.ChangeForm(pokemon.Species.GetDefaultForm()); + } + else if (item is not null && item.Name.ToString().EndsWith("_memory", StringComparison.OrdinalIgnoreCase)) + { + var memoryPrefix = + item.Name.ToString().Replace("_memory", string.Empty, StringComparison.OrdinalIgnoreCase); + var formName = $"silvally_{memoryPrefix}"; + if (pokemon.Species.TryGetForm(formName, out var form)) + { + pokemon.ChangeForm(form); + } + } + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/RainDish.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/RainDish.cs new file mode 100644 index 0000000..d493c54 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/RainDish.cs @@ -0,0 +1,40 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Rain Dish is an ability that heals the Pokémon for 1/16 of its maximum HP each turn during rain. +/// +/// Bulbapedia - Rain Dish +/// +[Script(ScriptCategory.Ability, "rain_dish")] +public class RainDish : Script +{ + private IPokemon? _owner; + + /// + public override void OnAddedToParent(IScriptSource source) + { + if (source is not IPokemon pokemon) + throw new ArgumentException("RainDish script can only be added to a Pokemon.", nameof(source)); + _owner = pokemon; + } + + /// + public override void OnEndTurn(IBattle battle) + { + if (_owner is null) + return; + if (battle.WeatherName != ScriptUtils.ResolveName()) + return; + + var healAmount = _owner.MaxHealth / 16; + if (healAmount <= 0) + return; + + EventBatchId batchId = new(); + battle.EventHook.Invoke(new AbilityTriggerEvent(_owner) + { + BatchId = batchId, + }); + _owner.Heal(healAmount, batchId: batchId); + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Rattled.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Rattled.cs new file mode 100644 index 0000000..7fcc0d5 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Rattled.cs @@ -0,0 +1,22 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Rattled is an ability that raises Speed when hit by a Bug-, Ghost-, or Dark-type move. +/// +/// Bulbapedia - Rattled +/// +[Script(ScriptCategory.Ability, "rattled")] +public class Rattled : Script +{ + /// + public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit) + { + var type = move.GetHitData(target, hit).Type; + if (type is null) + return; + if (type.Value.Name != "bug" && type.Value.Name != "ghost" && type.Value.Name != "dark") + return; + target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target)); + target.ChangeStatBoost(Statistic.Speed, 1, true, false); + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Reckless.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Reckless.cs new file mode 100644 index 0000000..a321a4b --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Reckless.cs @@ -0,0 +1,19 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Reckless is an ability that boosts the power of moves that have recoil or crash damage. +/// +/// Bulbapedia - Reckless +/// +[Script(ScriptCategory.Ability, "reckless")] +public class Reckless : Script +{ + /// + public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower) + { + if (move.UseMove.HasFlag("recoil")) + { + basePower = basePower.MultiplyOrMax(1.2f); + } + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Refrigerate.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Refrigerate.cs new file mode 100644 index 0000000..05a2d28 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Refrigerate.cs @@ -0,0 +1,26 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Refrigerate is an ability that turns Normal-type moves into Ice-type moves and boosts their power. +/// +/// Bulbapedia - Refrigerate +/// +[Script(ScriptCategory.Ability, "refrigerate")] +public class Refrigerate : Script +{ + /// + public override void ChangeMoveType(IExecutingMove move, IPokemon target, byte hit, + ref TypeIdentifier? typeIdentifier) + { + if (typeIdentifier?.Name == "normal" && + move.Battle.Library.StaticLibrary.Types.TryGetTypeIdentifier("ice", out var iceType)) + typeIdentifier = iceType; + } + + /// + public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower) + { + if (move.GetHitData(target, hit).Type?.Name == "ice") + basePower = (ushort)(basePower * 1.2f); // Boost Normal-type moves by 30% + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Regenerator.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Regenerator.cs new file mode 100644 index 0000000..ff4c131 --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Regenerator.cs @@ -0,0 +1,24 @@ +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Regenerator is an ability that restores a little HP when the Pokémon switches out. +/// +/// Bulbapedia - Regenerator +/// +[Script(ScriptCategory.Ability, "regenerator")] +public class Regenerator : Script +{ + /// + public override void OnSwitchOut(IPokemon oldPokemon, byte position) + { + if (!oldPokemon.IsUsable) + return; + + EventBatchId batchId = new(); + oldPokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(oldPokemon) + { + BatchId = batchId, + }); + oldPokemon.Heal(oldPokemon.MaxHealth / 3, batchId: batchId); + } +} \ No newline at end of file diff --git a/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Rivalry.cs b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Rivalry.cs new file mode 100644 index 0000000..a38119c --- /dev/null +++ b/Plugins/PkmnLib.Plugin.Gen7/Scripts/Abilities/Rivalry.cs @@ -0,0 +1,23 @@ +using PkmnLib.Static.Species; + +namespace PkmnLib.Plugin.Gen7.Scripts.Abilities; + +/// +/// Rivalry is an ability that increases damage to Pokémon of the same gender and decreases it to the opposite gender. +/// +/// Bulbapedia - Rivalry +/// +[Script(ScriptCategory.Ability, "rivalry")] +public class Rivalry : Script +{ + /// + public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower) + { + if (move.User.Gender == Gender.Genderless || target.Gender == Gender.Genderless) + return; + if (move.User.Gender == target.Gender) + basePower = basePower.MultiplyOrMax(1.25f); + else + basePower = (ushort)(basePower * 0.75f); + } +} \ No newline at end of file