Adds more abilities

This commit is contained in:
2025-06-07 10:58:58 +02:00
parent 232b94b04c
commit b2ba3d96ba
25 changed files with 429 additions and 16 deletions

View File

@@ -92,20 +92,45 @@
"effect": "color_change"
},
"comatose": {
"effect": "comatose",
"canBeChanged": false
},
"competitive": {},
"compound_eyes": {},
"contrary": {},
"corrosion": {},
"cursed_body": {},
"cute_charm": {},
"damp": {},
"dancer": {},
"dark_aura": {},
"dazzling": {},
"defeatist": {},
"defiant": {},
"competitive": {
"effect": "competitive"
},
"compound_eyes": {
"effect": "compound_eyes"
},
"contrary": {
"effect": "contrary"
},
"corrosion": {
"effect": "corrosion"
},
"cursed_body": {
"effect": "cursed_body"
},
"cute_charm": {
"effect": "cute_charm"
},
"damp": {
"effect": "damp"
},
"dancer": {
"effect": "dancer"
},
"dark_aura": {
"effect": "dark_aura"
},
"dazzling": {
"effect": "dazzling"
},
"defeatist": {
"effect": "defeatist"
},
"defiant": {
"effect": "defiant"
},
"delta_stream": {},
"desolate_land": {},
"disguise": {

View File

@@ -1,7 +1,32 @@
using PkmnLib.Static.Utils;
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Aura Break is an ability that reverses the effects of Dark Aura and Fairy Aura.
/// When this ability is present, Dark-type and Fairy-type moves are reduced in power by 25% instead of being boosted.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Aura_Break_(Ability)">Bulbapedia - Aura Break</see>
/// </summary>
[Script(ScriptCategory.Ability, "aura_break")]
public class AuraBreak : Script
{
// FIXME: Implement together with Dark Aura and Fairy Aura.
/// <inheritdoc />
public override void CustomTrigger(StringKey eventName, IDictionary<StringKey, object?>? parameters)
{
if (eventName != CustomTriggers.ModifyAuraEffect || parameters == null)
return;
if (!parameters.TryGetValue("aura_type", out var auraTypeObj) || auraTypeObj is not string auraType)
return;
if (auraType is "dark" or "fairy")
{
if (parameters.TryGetValue("modifier", out var modifierObj) && modifierObj is float)
{
// Reverse the aura effect by reducing power by 25%
parameters["modifier"] = 0.75f;
}
}
}
}

View File

@@ -0,0 +1,32 @@
using PkmnLib.Static.Utils;
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Comatose is an ability that makes the Pokémon always be in a sleep state, but still able to attack.
/// The Pokémon cannot be affected by other status conditions, and moves that would normally fail on sleeping Pokémon
/// will work normally. The Pokémon will still be affected by sleep-related moves and abilities.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Comatose_(Ability)">Bulbapedia - Comatose</see>
/// </summary>
[Script(ScriptCategory.Ability, "comatose")]
public class Comatose : Script
{
/// <inheritdoc />
public override void PreventStatusChange(IPokemon pokemonImpl, StringKey status, ref bool preventStatus)
{
if (status == ScriptUtils.ResolveName<Status.Sleep>())
{
preventStatus = true;
}
}
/// <inheritdoc />
public override void CustomTrigger(StringKey eventName, IDictionary<StringKey, object?>? parameters)
{
if (eventName == CustomTriggers.BypassSleep && parameters != null)
{
parameters["bypass_sleep"] = true;
}
}
}

View File

@@ -0,0 +1,27 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Competitive is an ability that raises the Pokémon's Special Attack by two stages whenever any of its stats are lowered.
/// This includes stat drops from moves, abilities, or items. The ability will not activate if the stat drop is self-inflicted.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Competitive_(Ability)">Bulbapedia - Competitive</see>
/// </summary>
[Script(ScriptCategory.Ability, "competitive")]
public class Competitive : Script
{
/// <inheritdoc />
/// <inheritdoc />
public override void OnAfterStatBoostChange(IPokemon pokemon, Statistic stat, bool selfInflicted, sbyte change)
{
if (change >= 0)
return;
if (selfInflicted)
return;
EventBatchId batchId = new();
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
BatchId = batchId,
});
pokemon.ChangeStatBoost(Statistic.SpecialAttack, 2, true, batchId);
}
}

View File

@@ -0,0 +1,18 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Compound Eyes is an ability that increases the accuracy of the Pokémon's moves by 30%.
/// This applies to all moves used by the Pokémon, making it particularly effective with low-accuracy moves.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Compound_Eyes_(Ability)">Bulbapedia - Compound Eyes</see>
/// </summary>
[Script(ScriptCategory.Ability, "compound_eyes")]
public class CompoundEyes : Script
{
/// <inheritdoc />
public override void ChangeAccuracy(IExecutingMove move, IPokemon target, byte hit, ref int modifiedAccuracy)
{
move.Battle.EventHook.Invoke(new AbilityTriggerEvent(move.User));
modifiedAccuracy = (int)(modifiedAccuracy * 1.3f);
}
}

View File

@@ -0,0 +1,20 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Contrary is an ability that inverts all stat changes for the Pokémon.
/// When a stat would normally be raised, it is lowered instead, and vice versa.
/// This applies to both self-inflicted stat changes and those caused by other Pokémon.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Contrary_(Ability)">Bulbapedia - Contrary</see>
/// </summary>
[Script(ScriptCategory.Ability, "contrary")]
public class Contrary : Script
{
/// <inheritdoc />
public override void ChangeStatBoostChange(IPokemon target, Statistic stat, bool selfInflicted, ref sbyte amount)
{
// Invert the stat change
amount = (sbyte)-amount;
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
}
}

View File

@@ -0,0 +1,13 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Corrosion is an ability that allows the Pokémon to poison Steel-type and Poison-type Pokémon.
/// This ability bypasses the natural immunity these types have to poison status.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Corrosion_(Ability)">Bulbapedia - Corrosion</see>
/// </summary>
[Script(ScriptCategory.Ability, "corrosion")]
public class Corrosion : Script
{
// TODO: Implement Corrosion ability logic
}

View File

@@ -0,0 +1,25 @@
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Cursed Body is an ability that has a 30% chance to disable the last move used against the Pokémon.
/// When triggered, the opponent's move becomes disabled for 4 turns, preventing its use.
/// This ability can be triggered by any damaging move that hits the Pokémon.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Cursed_Body_(Ability)">Bulbapedia - Cursed Body</see>
/// </summary>
[Script(ScriptCategory.Ability, "cursed_body")]
public class CursedBody : Script
{
/// <inheritdoc />
public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
{
// 30% chance to disable the move
if (move.Battle.Random.GetFloat() > 0.3f)
return;
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.Volatile.Add(new DisableEffect(move.ChosenMove.MoveData.Name));
}
}

View File

@@ -0,0 +1,34 @@
using PkmnLib.Plugin.Gen7.Scripts.Pokemon;
using PkmnLib.Static.Species;
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Cute Charm is an ability that has a 30% chance to infatuate the opponent when hit by a contact move.
/// Infatuation prevents the affected Pokémon from attacking 50% of the time.
/// This ability only works on Pokémon of the opposite gender.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Cute_Charm_(Ability)">Bulbapedia - Cute Charm</see>
/// </summary>
[Script(ScriptCategory.Ability, "cute_charm")]
public class CuteCharm : Script
{
/// <inheritdoc />
public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
{
// Only trigger on contact moves
if (!move.UseMove.HasFlag("contact"))
return;
// 30% chance to infatuate
if (move.Battle.Random.GetFloat() > 0.3f)
return;
if (target.Gender == move.User.Gender || target.Gender == Gender.Genderless ||
move.User.Gender == Gender.Genderless)
return;
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
move.User.Volatile.Add(new Infatuated());
}
}

View File

@@ -0,0 +1,21 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Damp is an ability that prevents the use of Self-Destruct and Explosion moves.
/// When a Pokémon with this ability is on the field, any attempt to use these moves will fail.
/// This ability affects both allies and opponents.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Damp_(Ability)">Bulbapedia - Damp</see>
/// </summary>
[Script(ScriptCategory.Ability, "damp")]
public class Damp : Script
{
/// <inheritdoc />
public override void FailIncomingMove(IExecutingMove move, IPokemon target, ref bool fail)
{
if (move.UseMove.Name == "self_destruct" || move.UseMove.Name == "explosion")
{
fail = true;
}
}
}

View File

@@ -0,0 +1,13 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Dancer is an ability that allows the Pokémon to copy any dance move used by any Pokémon on the field.
/// When a dance move is used, the Pokémon with Dancer will immediately use the same move after the original user.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Dancer_(Ability)">Bulbapedia - Dancer</see>
/// </summary>
[Script(ScriptCategory.Ability, "dancer")]
public class Dancer : Script
{
// TODO: Implement Dancer ability logic
}

View File

@@ -0,0 +1,35 @@
using PkmnLib.Static.Utils;
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Dark Aura is an ability that increases the power of Dark-type moves by 33% for all Pokémon on the field.
/// The effect can be modified by other abilities (such as Aura Break) via a custom script hook.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Dark_Aura_(Ability)">Bulbapedia - Dark Aura</see>
/// </summary>
[Script(ScriptCategory.Ability, "dark_aura")]
public class DarkAura : Script
{
/// <inheritdoc />
public override void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
{
if (move.GetHitData(target, hit).Type?.Name == "dark")
{
var auraModifier = 5448f / 4096f;
var parameters = new Dictionary<StringKey, object?>
{
["aura_type"] = "dark",
["modifier"] = auraModifier,
};
move.Battle.Sides.SelectMany(side => side.Pokemon).WhereNotNull()
.RunScriptHook(x => x.CustomTrigger(CustomTriggers.ModifyAuraEffect, parameters));
if (parameters.TryGetValue("modifier", out var modObj) && modObj is float modValue)
{
auraModifier = modValue;
}
modifier *= auraModifier;
move.Battle.EventHook.Invoke(new AbilityTriggerEvent(move.User));
}
}
}

View File

@@ -0,0 +1,20 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Dazzling is an ability that prevents opposing Pokémon from using moves with increased priority.
/// This includes moves like Quick Attack, Aqua Jet, and Extreme Speed.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Dazzling_(Ability)">Bulbapedia - Dazzling</see>
/// </summary>
[Script(ScriptCategory.Ability, "dazzling")]
public class Dazzling : Script
{
/// <inheritdoc />
public override void FailIncomingMove(IExecutingMove move, IPokemon target, ref bool fail)
{
if (move.UseMove.Priority > 0)
{
fail = true;
}
}
}

View File

@@ -0,0 +1,20 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Defeatist is an ability that halves the Pokémon's Attack and Special Attack when its HP drops below 50%.
/// This reduction applies to all moves used by the Pokémon, making it significantly weaker when damaged.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Defeatist_(Ability)">Bulbapedia - Defeatist</see>
/// </summary>
[Script(ScriptCategory.Ability, "defeatist")]
public class Defeatist : Script
{
/// <inheritdoc />
public override void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
{
if (move.User.CurrentHealth < move.User.MaxHealth / 2)
{
modifier *= 0.5f;
}
}
}

View File

@@ -0,0 +1,27 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
/// <summary>
/// Defiant is an ability that raises the Pokémon's Attack by two stages whenever any of its stats are lowered.
/// This includes stat drops from moves, abilities, or items. The ability will not activate if the stat drop is self-inflicted.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Defiant_(Ability)">Bulbapedia - Defiant</see>
/// </summary>
[Script(ScriptCategory.Ability, "defiant")]
public class Defiant : Script
{
/// <inheritdoc />
/// <inheritdoc />
public override void OnAfterStatBoostChange(IPokemon pokemon, Statistic stat, bool selfInflicted, sbyte change)
{
if (change >= 0)
return;
if (selfInflicted)
return;
EventBatchId batchId = new();
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon)
{
BatchId = batchId,
});
pokemon.ChangeStatBoost(Statistic.Attack, 2, true, batchId);
}
}

View File

@@ -18,7 +18,7 @@ public class SpeedModifierInWeather : Script
throw new ArgumentException("Parameter 'weather' is required and must be a string.", nameof(parameters));
if (!parameters.TryGetValue("modifier", out var modifierObj))
throw new ArgumentException("Parameter 'modifier' is required", nameof(parameters));
if (modifierObj is not float modifier && modifierObj is not int)
if (modifierObj is not float && modifierObj is not int)
throw new ArgumentException("Parameter 'modifier' must be a float or int.", nameof(parameters));
var weatherModifier = modifierObj is float modFloat ? modFloat : (int)modifierObj;

View File

@@ -19,4 +19,6 @@ public static class CustomTriggers
public static readonly StringKey BypassSleep = "bypass_sleep";
public static readonly StringKey Whirlpool = "whirlpool";
public static readonly StringKey ModifyAuraEffect = "modify_aura_effect";
}

View File

@@ -1,5 +1,4 @@
using PkmnLib.Static.Moves;
using PkmnLib.Static.Utils;
namespace PkmnLib.Plugin.Gen7.Scripts.Status;