More moves

This commit is contained in:
Deukhoofd 2025-03-21 13:35:12 +01:00
parent 7f5088b763
commit 85b513092a
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
9 changed files with 149 additions and 11 deletions

View File

@ -450,6 +450,8 @@ public interface IPokemonBattleData : IDeepCloneable
void MarkItemAsConsumed(IItem itemName); void MarkItemAsConsumed(IItem itemName);
uint SwitchInTurn { get; internal set; } uint SwitchInTurn { get; internal set; }
IBattleSide BattleSide { get; }
} }
/// <inheritdoc cref="IPokemon"/> /// <inheritdoc cref="IPokemon"/>
@ -1254,4 +1256,7 @@ public class PokemonBattleDataImpl : IPokemonBattleData
/// <inheritdoc /> /// <inheritdoc />
public uint SwitchInTurn { get; set; } public uint SwitchInTurn { get; set; }
/// <inheritdoc />
public IBattleSide BattleSide => Battle.Sides[SideIndex];
} }

View File

@ -6178,7 +6178,10 @@
"protect", "protect",
"reflectable", "reflectable",
"mirror" "mirror"
] ],
"effect": {
"name": "leech_seed"
}
}, },
{ {
"name": "leer", "name": "leer",
@ -6215,7 +6218,14 @@
"contact", "contact",
"protect", "protect",
"mirror" "mirror"
] ],
"effect": {
"name": "set_status",
"chance": 30,
"parameters": {
"status": "paralyzed"
}
}
}, },
{ {
"name": "light_of_ruin", "name": "light_of_ruin",
@ -6229,7 +6239,13 @@
"flags": [ "flags": [
"protect", "protect",
"mirror" "mirror"
] ],
"effect": {
"name": "recoil",
"parameters": {
"recoil_percentage": 0.5
}
}
}, },
{ {
"name": "light_screen", "name": "light_screen",
@ -6242,7 +6258,10 @@
"category": "status", "category": "status",
"flags": [ "flags": [
"snatch" "snatch"
] ],
"effect": {
"name": "light_screen"
}
}, },
{ {
"name": "liquidation", "name": "liquidation",
@ -6257,7 +6276,14 @@
"contact", "contact",
"protect", "protect",
"mirror" "mirror"
] ],
"effect": {
"name": "change_target_defense",
"chance": 20,
"parameters": {
"amount": -1
}
}
}, },
{ {
"name": "lock_on", "name": "lock_on",

View File

@ -58,6 +58,8 @@ public class Gen7BattleStatCalculator : IBattleStatCalculator
x => x.ChangeAccuracyModifier(executingMove, target, hitIndex, ref accuracyModifier)); x => x.ChangeAccuracyModifier(executingMove, target, hitIndex, ref accuracyModifier));
var modifiedAccuracy = (int)(moveAccuracy * accuracyModifier); var modifiedAccuracy = (int)(moveAccuracy * accuracyModifier);
executingMove.RunScriptHook(x => x.ChangeAccuracy(executingMove, target, hitIndex, ref modifiedAccuracy)); executingMove.RunScriptHook(x => x.ChangeAccuracy(executingMove, target, hitIndex, ref modifiedAccuracy));
if (modifiedAccuracy == 255)
return 255;
var targetEvasion = target.StatBoost.Evasion; var targetEvasion = target.StatBoost.Evasion;
var ignoreEvasion = false; var ignoreEvasion = false;
executingMove.RunScriptHook(x => x.BypassEvasionStatBoosts(executingMove, target, hitIndex, ref ignoreEvasion)); executingMove.RunScriptHook(x => x.BypassEvasionStatBoosts(executingMove, target, hitIndex, ref ignoreEvasion));

View File

@ -9,4 +9,8 @@ public static class CustomTriggers
public static readonly StringKey BindNumberOfTurns = "bind_number_of_turns"; public static readonly StringKey BindNumberOfTurns = "bind_number_of_turns";
public static readonly StringKey BindPercentOfMaxHealth = "bind_percent_of_max_health"; 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";
} }

View File

@ -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
{
/// <inheritdoc />
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));
}
}

View File

@ -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
{
/// <inheritdoc />
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<StringKey, object?>()
{
{ "duration", turns },
};
move.RunScriptHook(x => x.CustomTrigger(CustomTriggers.LightScreenNumberOfTurns, dict));
turns = (int)dict.GetOrDefault("duration", turns)!;
battleData.BattleSide.VolatileScripts.StackOrAdd(ScriptUtils.ResolveName<LightScreenEffect>(),
() => new LightScreenEffect(turns));
}
}

View File

@ -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;
}
/// <inheritdoc />
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);
}
}

View File

@ -1,7 +1,32 @@
using PkmnLib.Static.Moves;
namespace PkmnLib.Plugin.Gen7.Scripts.Side; namespace PkmnLib.Plugin.Gen7.Scripts.Side;
[Script(ScriptCategory.Side, "light_screen")] [Script(ScriptCategory.Side, "light_screen")]
public class LightScreenEffect : Script public class LightScreenEffect(int turns) : Script
{ {
// TODO: Implement LightScreenEffect private int _turns = turns;
/// <inheritdoc />
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);
}
/// <inheritdoc />
public override void OnEndTurn(IBattle battle)
{
_turns -= 1;
if (_turns <= 0)
RemoveSelf();
}
} }

View File

@ -32,10 +32,11 @@ public class Hail : Script, IWeatherScript
if (pokemon.Types.Contains(iceType)) if (pokemon.Types.Contains(iceType))
continue; continue;
var ignoresHail = false; var ignoresHail = false;
pokemon.RunScriptHook(x => x.CustomTrigger("ignores_hail", new Dictionary<StringKey, object?>() pokemon.RunScriptHook(x => x.CustomTrigger(CustomTriggers.IgnoreHail,
{ new Dictionary<StringKey, object?>()
{ "ignoresHail", ignoresHail }, {
})); { "ignoresHail", ignoresHail },
}));
if (ignoresHail) if (ignoresHail)
continue; continue;