More abilities
All checks were successful
Build / Build (push) Successful in 49s

This commit is contained in:
Deukhoofd 2025-06-01 11:23:01 +02:00
parent b090aa65f9
commit 232b94b04c
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
8 changed files with 114 additions and 17 deletions

View File

@ -263,6 +263,11 @@ public interface IPokemon : IScriptSource, IDeepCloneable
/// </summary> /// </summary>
bool ConsumeHeldItem(); bool ConsumeHeldItem();
/// <summary>
/// Uses an item on the Pokemon.
/// </summary>
void UseItem(IItem item);
/// <summary> /// <summary>
/// Change a boosted stat by a certain amount. /// Change a boosted stat by a certain amount.
/// </summary> /// </summary>
@ -805,8 +810,15 @@ public class PokemonImpl : ScriptSource, IPokemon
BattleData.MarkItemAsConsumed(HeldItem); BattleData.MarkItemAsConsumed(HeldItem);
} }
UseItem(SetHeldItem(null)!);
return true;
}
public void UseItem(IItem item)
{
// TODO: actually consume the item // TODO: actually consume the item
throw new NotImplementedException();
this.RunScriptHook(x => x.OnAfterItemConsume(this, item));
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@ -557,7 +557,7 @@ public abstract class Script : IDeepCloneable
/// This function is triggered on a Pokemon and its parents when the given Pokemon consumes the /// This function is triggered on a Pokemon and its parents when the given Pokemon consumes the
/// held item it had. /// held item it had.
/// </summary> /// </summary>
public virtual void OnAfterHeldItemConsume(IPokemon pokemon, IItem item) public virtual void OnAfterItemConsume(IPokemon pokemon, IItem item)
{ {
} }

View File

@ -72,22 +72,24 @@
"effect": "bulletproof" "effect": "bulletproof"
}, },
"cheek_pouch": { "cheek_pouch": {
"effect": "CheekPouch" "effect": "cheek_pouch"
}, },
"chlorophyll": { "chlorophyll": {
"effect": "DoubleSpeedInWeather", "effect": "speed_modifier_in_weather",
"parameters": { "parameters": {
"weather": "HarshSunlight" "weather": "sunny",
"modifier": 2.0
} }
}, },
"clear_body": { "clear_body": {
"effect": "PreventStatLowering" "effect": "prevent_stat_lowering"
// By not specifying a stat, it applies to all stats
}, },
"cloud_nine": { "cloud_nine": {
"effect": "SuppressWeather" "effect": "suppress_weather"
}, },
"color_change": { "color_change": {
"effect": "ColorChange" "effect": "color_change"
}, },
"comatose": { "comatose": {
"canBeChanged": false "canBeChanged": false

View File

@ -69,7 +69,7 @@ public class Gen7Plugin : Plugin<Gen7PluginConfiguration>, IResourceProvider
typeof(Gen7Plugin).Assembly), typeof(Gen7Plugin).Assembly),
ResourceFileType.Items => new AssemblyResourceResult("PkmnLib.Plugin.Gen7.Data.Items.json", ResourceFileType.Items => new AssemblyResourceResult("PkmnLib.Plugin.Gen7.Data.Items.json",
typeof(Gen7Plugin).Assembly), typeof(Gen7Plugin).Assembly),
ResourceFileType.Abilities => new AssemblyResourceResult("PkmnLib.Plugin.Gen7.Data.Abilities.json", ResourceFileType.Abilities => new AssemblyResourceResult("PkmnLib.Plugin.Gen7.Data.Abilities.jsonc",
typeof(Gen7Plugin).Assembly), typeof(Gen7Plugin).Assembly),
ResourceFileType.GrowthRates => new AssemblyResourceResult("PkmnLib.Plugin.Gen7.Data.GrowthRates.json", ResourceFileType.GrowthRates => new AssemblyResourceResult("PkmnLib.Plugin.Gen7.Data.GrowthRates.json",
typeof(Gen7Plugin).Assembly), typeof(Gen7Plugin).Assembly),

View File

@ -0,0 +1,15 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "cheek_pouch")]
public class CheekPouch : Script
{
/// <inheritdoc />
public override void OnAfterItemConsume(IPokemon pokemon, IItem item)
{
if (item.Category == ItemCategory.Berry)
{
pokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(pokemon));
pokemon.Heal(pokemon.MaxHealth / 3);
}
}
}

View File

@ -0,0 +1,16 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "color_change")]
public class ColorChange : Script
{
/// <inheritdoc />
public override void OnIncomingHit(IExecutingMove move, IPokemon target, byte hit)
{
var hitData = move.GetHitData(target, hit);
if (hitData.Type != null && (hitData.Type != target.Types.FirstOrDefault() || target.Types.Count > 1))
{
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
target.SetTypes([hitData.Type.Value]);
}
}
}

View File

@ -5,26 +5,37 @@ namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "prevent_stat_lowering")] [Script(ScriptCategory.Ability, "prevent_stat_lowering")]
public class PreventStatLowering : Script public class PreventStatLowering : Script
{ {
private Statistic _statistic; /// <summary>
/// The statistic that this ability prevents from being lowered.
/// Null means it prevents all stat lowering.
/// </summary>
private Statistic? _statistic;
/// <inheritdoc /> /// <inheritdoc />
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters) public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
{ {
if (parameters is null) if (parameters is null)
throw new ArgumentNullException(nameof(parameters), "Parameters cannot be null."); throw new ArgumentNullException(nameof(parameters), "Parameters cannot be null.");
if (!parameters.TryGetValue("stat", out var statObj) || statObj is not string statStr) if (parameters.TryGetValue("stat", out var statObj) && statObj is string statStr)
throw new ArgumentException("Parameter 'stat' is required and must be a string.", nameof(parameters)); {
if (!Enum.TryParse(statStr, true, out Statistic stat)) if (!Enum.TryParse(statStr, true, out Statistic stat))
throw new ArgumentException($"Invalid statistic '{statStr}' provided.", nameof(statStr)); throw new ArgumentException($"Invalid statistic '{statStr}' provided.", nameof(statStr));
_statistic = stat; _statistic = stat;
} }
}
/// <inheritdoc /> /// <inheritdoc />
public override void PreventStatBoostChange(IPokemon target, Statistic stat, sbyte amount, bool selfInflicted, public override void PreventStatBoostChange(IPokemon target, Statistic stat, sbyte amount, bool selfInflicted,
ref bool prevent) ref bool prevent)
{ {
if (_statistic is not null && _statistic != stat)
return;
if (amount >= 0)
return;
if (!selfInflicted) if (!selfInflicted)
prevent = false; {
target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
prevent = true;
}
} }
} }

View File

@ -0,0 +1,41 @@
using PkmnLib.Static.Utils;
namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;
[Script(ScriptCategory.Ability, "speed_modifier_in_weather")]
public class SpeedModifierInWeather : Script
{
private StringKey _weather;
private float _modifier;
/// <inheritdoc />
public override void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
{
if (parameters is null)
throw new ArgumentNullException(nameof(parameters));
if (!parameters.TryGetValue("weather", out var weatherObj) || weatherObj is not string weatherStr)
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)
throw new ArgumentException("Parameter 'modifier' must be a float or int.", nameof(parameters));
var weatherModifier = modifierObj is float modFloat ? modFloat : (int)modifierObj;
_weather = weatherStr;
_modifier = weatherModifier;
}
/// <inheritdoc />
public override void ChangeSpeed(ITurnChoice choice, ref uint speed)
{
var battle = choice.User.BattleData?.Battle;
if (battle is null)
return;
var weather = battle.WeatherName;
if (weather == _weather)
{
speed = speed.MultiplyOrMax(_modifier);
}
}
}