Adds a bunch more move scripts
This commit is contained in:
parent
6f2bd678a5
commit
44cd2ee03e
|
@ -0,0 +1,17 @@
|
||||||
|
namespace PkmnLib.Dynamic.Events;
|
||||||
|
|
||||||
|
public class DialogEvent : IEventData
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public EventBatchId BatchId { get; init; } = new();
|
||||||
|
|
||||||
|
public DialogEvent(string message, Dictionary<string, object>? parameters = null)
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
Parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
public Dictionary<string, object>? Parameters { get; set; }
|
||||||
|
}
|
|
@ -93,7 +93,14 @@ public interface IPokemon : IScriptSource
|
||||||
float WeightInKg { get; set; }
|
float WeightInKg { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The height of the Pokemon in meters.
|
/// Sets the weight of the Pokémon in kilograms. Returns whether the weight was changed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="weightInKg">The new weight in kilograms</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool ChangeWeightInKgBy(float weightInKg);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The height of the Pokémon in meters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
float HeightInMeters { get; set; }
|
float HeightInMeters { get; set; }
|
||||||
|
|
||||||
|
@ -543,6 +550,18 @@ public class PokemonImpl : ScriptSource, IPokemon
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public float WeightInKg { get; set; }
|
public float WeightInKg { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool ChangeWeightInKgBy(float weightInKg)
|
||||||
|
{
|
||||||
|
if (WeightInKg <= 0.1f)
|
||||||
|
return false;
|
||||||
|
var newWeight = WeightInKg + weightInKg;
|
||||||
|
if (newWeight <= 0.1f)
|
||||||
|
newWeight = 0.1f;
|
||||||
|
WeightInKg = newWeight;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public float HeightInMeters { get; set; }
|
public float HeightInMeters { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ public static class ScriptUtils
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static StringKey ResolveName(this Script script) => ResolveName(script.GetType());
|
public static StringKey ResolveName(this Script script) => ResolveName(script.GetType());
|
||||||
|
|
||||||
|
public static StringKey ResolveName<T>() where T : Script => ResolveName(typeof(T));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolve name from the <see cref="ScriptAttribute"/> of the given type.
|
/// Resolve name from the <see cref="ScriptAttribute"/> of the given type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -14,8 +14,15 @@ namespace PkmnLib.Dynamic.ScriptHandling;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class Script
|
public abstract class Script
|
||||||
{
|
{
|
||||||
|
internal event Action<Script>? OnRemoveEvent;
|
||||||
|
|
||||||
private int _suppressCount;
|
private int _suppressCount;
|
||||||
|
|
||||||
|
public void RemoveSelf()
|
||||||
|
{
|
||||||
|
OnRemoveEvent?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of a script is its unique identifier.
|
/// The name of a script is its unique identifier.
|
||||||
/// If not overridden, this will resolve the name from the <see cref="ScriptAttribute"/> of the
|
/// If not overridden, this will resolve the name from the <see cref="ScriptAttribute"/> of the
|
||||||
|
|
|
@ -79,6 +79,7 @@ public class ScriptSet : IScriptSet
|
||||||
return existing;
|
return existing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
script.OnRemoveEvent += s => Remove(s.Name);
|
||||||
var container = new ScriptContainer(script);
|
var container = new ScriptContainer(script);
|
||||||
_scripts.Add(container);
|
_scripts.Add(container);
|
||||||
return container;
|
return container;
|
||||||
|
@ -97,6 +98,7 @@ public class ScriptSet : IScriptSet
|
||||||
var script = instantiation();
|
var script = instantiation();
|
||||||
if (script is null)
|
if (script is null)
|
||||||
return null;
|
return null;
|
||||||
|
script.OnRemoveEvent += s => Remove(s.Name);
|
||||||
var container = new ScriptContainer(script);
|
var container = new ScriptContainer(script);
|
||||||
_scripts.Add(container);
|
_scripts.Add(container);
|
||||||
return container;
|
return container;
|
||||||
|
@ -111,6 +113,7 @@ public class ScriptSet : IScriptSet
|
||||||
var script = _scripts.FirstOrDefault(s => s.Script?.Name == scriptKey);
|
var script = _scripts.FirstOrDefault(s => s.Script?.Name == scriptKey);
|
||||||
if (script is null)
|
if (script is null)
|
||||||
return;
|
return;
|
||||||
|
script.Script?.OnRemove();
|
||||||
_scripts.Remove(script);
|
_scripts.Remove(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Weather;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Moves;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This move reduces damage from physical and special moves for five turns. This can be used only in a hailstorm.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Aurora Veil reduces the damage done to the user by physical and special moves for five turns by half; in battles
|
||||||
|
/// beside Single Battles, Aurora Veil protects the user and all allies, but only reduces damage by (roughly) a third
|
||||||
|
/// rather than half (specifically, with a multiplier of 2732/4096). It does not reduce damage done by self-inflicted
|
||||||
|
/// confusion damage, critical hits, or moves that deal direct damage. Aurora Veil can only be used during hail or snow,
|
||||||
|
/// but the effect remains even after hail or snow ends; Cloud Nine and Air Lock will cause Aurora Veil to fail even if
|
||||||
|
/// it is hailing or snowing.
|
||||||
|
/// <br/>
|
||||||
|
/// While it can be active at the same time as Reflect and Light Screen, the damage reduction effects do not stack.
|
||||||
|
/// Aurora Veil is removed from a Pokémon's side of the field if it is hit by Brick Break, Defog, Psychic Fangs, or
|
||||||
|
/// Raging Bull, or if a Pokémon with Screen Cleaner is sent out. Pokémon with the Ability Infiltrator ignore the effects
|
||||||
|
/// of Aurora Veil when attacking.
|
||||||
|
/// <br/>
|
||||||
|
/// If a Light Clay is held when Aurora Veil is used, it will extend the duration of Aurora Veil from 5 to 8 turns.
|
||||||
|
/// </remarks>
|
||||||
|
[Script(ScriptCategory.Move, "aurora_veil")]
|
||||||
|
public class AuroraVeil : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var battle = move.User.BattleData?.Battle;
|
||||||
|
if (battle == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (battle.WeatherName != ScriptUtils.ResolveName<Hail>())
|
||||||
|
{
|
||||||
|
move.GetHitData(target, hit).Fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var side = battle.Sides[move.User.BattleData!.SideIndex];
|
||||||
|
var numberOfTurns = move.User.HasHeldItem("light_clay") ? 8 : 5;
|
||||||
|
var script = side.VolatileScripts.StackOrAdd(ScriptUtils.ResolveName<AuroraVeilEffect>(), () =>
|
||||||
|
{
|
||||||
|
var effect = new AuroraVeilEffect(numberOfTurns);
|
||||||
|
return effect;
|
||||||
|
});
|
||||||
|
((AuroraVeilEffect)script!.Script!).NumberOfTurns = numberOfTurns;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PkmnLib.Dynamic.Events;
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
using PkmnLib.Static;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Moves;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The user sheds part of its body to make itself lighter and sharply raise its Speed stat.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Autotomize raises the user's Speed stat by two stages and (if the user successfully changes its Speed) decreases its
|
||||||
|
/// weight by 220 lbs. (100 kg). If the user successfully changes its weight, the message "Pokémon became nimble!"
|
||||||
|
/// is displayed.
|
||||||
|
/// <br />
|
||||||
|
/// Autotomize cannot decrease the user's weight below the minimum 0.2 lbs (0.1 kg); if the user's weight would drop
|
||||||
|
/// below the minimum, it becomes the minimum instead. Weight loss from Autotomize stacks, so using it multiple times
|
||||||
|
/// will continue to decrease the user's weight accordingly until it reaches the minimum weight. Autotomize's weight
|
||||||
|
/// reduction cannot be transferred by Baton Pass or removed by Haze. A Pokémon's weight is reset if it changes form
|
||||||
|
/// (from Generation VI onward), switches out or faints, or the battle ends.
|
||||||
|
/// </remarks>
|
||||||
|
[Script(ScriptCategory.Move, "autotomize")]
|
||||||
|
public class Autotomize : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var user = move.User;
|
||||||
|
if (user.ChangeStatBoost(Statistic.Speed, 2, true) &&
|
||||||
|
user.ChangeWeightInKgBy(-100.0f))
|
||||||
|
{
|
||||||
|
var battle = user.BattleData?.Battle;
|
||||||
|
battle?.EventHook.Invoke(new DialogEvent("pokemon_became_nimble", new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
{ "pokemon", user }
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PkmnLib.Dynamic.Libraries;
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
using PkmnLib.Static;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Dynamic.Events;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "change_all_target_stats")]
|
||||||
|
public class ChangeAllTargetStats : Script
|
||||||
|
{
|
||||||
|
private sbyte _amount;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnInitialize(IDynamicLibrary library, IReadOnlyDictionary<StringKey, object?>? parameters)
|
||||||
|
{
|
||||||
|
if (parameters == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(parameters));
|
||||||
|
}
|
||||||
|
if (!parameters.TryGetValue("amount", out var amount) || amount == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Parameter 'amount' is required.");
|
||||||
|
}
|
||||||
|
_amount = (sbyte)amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
target.ChangeStatBoost(Statistic.Attack, _amount, target == move.User);
|
||||||
|
target.ChangeStatBoost(Statistic.Defense, _amount, target == move.User);
|
||||||
|
target.ChangeStatBoost(Statistic.SpecialAttack, _amount, target == move.User);
|
||||||
|
target.ChangeStatBoost(Statistic.SpecialDefense, _amount, target == move.User);
|
||||||
|
target.ChangeStatBoost(Statistic.Speed, _amount, target == move.User);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PkmnLib.Dynamic.Libraries;
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
using PkmnLib.Static;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
public abstract class ChangeTargetStats : Script
|
||||||
|
{
|
||||||
|
private readonly Statistic _stat;
|
||||||
|
private sbyte _amount;
|
||||||
|
|
||||||
|
protected ChangeTargetStats(Statistic stat)
|
||||||
|
{
|
||||||
|
_stat = stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnInitialize(IDynamicLibrary library, IReadOnlyDictionary<StringKey, object?>? parameters)
|
||||||
|
{
|
||||||
|
if (parameters == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parameters.TryGetValue("amount", out var amount) || amount == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Parameter 'amount' is required.");
|
||||||
|
}
|
||||||
|
|
||||||
|
_amount = (sbyte)amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
target.ChangeStatBoost(_stat, _amount, target == move.User);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "change_target_attack")]
|
||||||
|
public class ChangeTargetAttack : ChangeTargetStats
|
||||||
|
{
|
||||||
|
public ChangeTargetAttack() : base(Statistic.Attack)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "change_target_defense")]
|
||||||
|
public class ChangeTargetDefense : ChangeTargetStats
|
||||||
|
{
|
||||||
|
public ChangeTargetDefense() : base(Statistic.Defense)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "change_target_special_attack")]
|
||||||
|
public class ChangeTargetSpecialAttack : ChangeTargetStats
|
||||||
|
{
|
||||||
|
public ChangeTargetSpecialAttack() : base(Statistic.SpecialAttack)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "change_target_special_defense")]
|
||||||
|
public class ChangeTargetSpecialDefense : ChangeTargetStats
|
||||||
|
{
|
||||||
|
public ChangeTargetSpecialDefense() : base(Statistic.SpecialDefense)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "change_target_speed")]
|
||||||
|
public class ChangeTargetSpeed : ChangeTargetStats
|
||||||
|
{
|
||||||
|
public ChangeTargetSpeed() : base(Statistic.Speed)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
using System.Linq;
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
using PkmnLib.Static.Utils;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "cure_party_status")]
|
||||||
|
public class CurePartyStatus : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var user = move.User;
|
||||||
|
var battle = user.BattleData?.Battle;
|
||||||
|
if (battle == null)
|
||||||
|
return;
|
||||||
|
var party = battle.Parties.FirstOrDefault(p => p.Party.Contains(user));
|
||||||
|
if (party == null)
|
||||||
|
return;
|
||||||
|
foreach (var pokemon in party.Party.WhereNotNull())
|
||||||
|
{
|
||||||
|
pokemon.ClearStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.Models.Choices;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
using PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "double_power_if_target_damaged_in_turn")]
|
||||||
|
public class DoublePowerIfTargetDamagedInTurn : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnBeforeTurnStart(ITurnChoice choice)
|
||||||
|
{
|
||||||
|
if (choice is IMoveChoice moveChoice)
|
||||||
|
{
|
||||||
|
var battle = choice.User.BattleData?.Battle;
|
||||||
|
if (battle == null)
|
||||||
|
return;
|
||||||
|
var side = battle.Sides[moveChoice.TargetSide];
|
||||||
|
side.VolatileScripts.Add(new DoublePowerIfTargetDamagedInTurnData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref byte basePower)
|
||||||
|
{
|
||||||
|
var battle = move.User.BattleData?.Battle;
|
||||||
|
if (battle == null)
|
||||||
|
return;
|
||||||
|
var side = battle.Sides[target.BattleData!.SideIndex];
|
||||||
|
var script = side.VolatileScripts.Get(ScriptUtils.ResolveName<DoublePowerIfTargetDamagedInTurnData>());
|
||||||
|
if (script?.Script == null)
|
||||||
|
return;
|
||||||
|
var data = (DoublePowerIfTargetDamagedInTurnData)script.Script;
|
||||||
|
if (data._hitPokemon.Contains(target))
|
||||||
|
basePower *= 2;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.Models.Choices;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Move, "struggle")]
|
||||||
|
public class Struggle : Script
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeNumberOfHits(IMoveChoice choice, ref byte numberOfHits)
|
||||||
|
{
|
||||||
|
numberOfHits = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void IsInvulnerableToMove(IExecutingMove move, IPokemon target, ref bool invulnerable)
|
||||||
|
{
|
||||||
|
invulnerable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeEffectiveness(IExecutingMove move, IPokemon target, byte hit, ref float effectiveness)
|
||||||
|
{
|
||||||
|
effectiveness = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit)
|
||||||
|
{
|
||||||
|
var damage = move.User.MaxHealth / 4;
|
||||||
|
if (damage == 0) damage = 1;
|
||||||
|
move.User.Damage(damage, DamageSource.Struggle, new());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
using PkmnLib.Static.Moves;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This move reduces damage from physical and special moves for five turns. This can be used only in a hailstorm.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Aurora Veil reduces the damage done to the user by physical and special moves for five turns by half; in battles
|
||||||
|
/// beside Single Battles, Aurora Veil protects the user and all allies, but only reduces damage by (roughly) a third
|
||||||
|
/// rather than half (specifically, with a multiplier of 2732/4096). It does not reduce damage done by self-inflicted
|
||||||
|
/// confusion damage, critical hits, or moves that deal direct damage. Aurora Veil can only be used during hail or snow,
|
||||||
|
/// but the effect remains even after hail or snow ends; Cloud Nine and Air Lock will cause Aurora Veil to fail even if
|
||||||
|
/// it is hailing or snowing.
|
||||||
|
/// <br/>
|
||||||
|
/// While it can be active at the same time as Reflect and Light Screen, the damage reduction effects do not stack.
|
||||||
|
/// Aurora Veil is removed from a Pokémon's side of the field if it is hit by Brick Break, Defog, Psychic Fangs, or
|
||||||
|
/// Raging Bull, or if a Pokémon with Screen Cleaner is sent out. Pokémon with the Ability Infiltrator ignore the effects
|
||||||
|
/// of Aurora Veil when attacking.
|
||||||
|
/// <br/>
|
||||||
|
/// If a Light Clay is held when Aurora Veil is used, it will extend the duration of Aurora Veil from 5 to 8 turns.
|
||||||
|
/// </remarks>
|
||||||
|
[Script(ScriptCategory.Side, "aurora_veil")]
|
||||||
|
public class AuroraVeilEffect : Script
|
||||||
|
{
|
||||||
|
public int NumberOfTurns { get; set; }
|
||||||
|
|
||||||
|
public AuroraVeilEffect(int numberOfTurns)
|
||||||
|
{
|
||||||
|
NumberOfTurns = numberOfTurns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnEndTurn()
|
||||||
|
{
|
||||||
|
if (NumberOfTurns > 0)
|
||||||
|
NumberOfTurns--;
|
||||||
|
if (NumberOfTurns == 0)
|
||||||
|
RemoveSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void ChangeIncomingDamage(IExecutingMove move, IPokemon target, byte hit, ref uint damage)
|
||||||
|
{
|
||||||
|
var hitData = move.GetHitData(target, hit);
|
||||||
|
if (hitData.IsCritical)
|
||||||
|
return;
|
||||||
|
if (move.User.BattleData?.SideIndex == target.BattleData?.SideIndex)
|
||||||
|
return;
|
||||||
|
var targetSide = target.BattleData?.SideIndex;
|
||||||
|
if (targetSide == null)
|
||||||
|
return;
|
||||||
|
var side = move.User.BattleData!.Battle.Sides[targetSide.Value];
|
||||||
|
switch (move.UseMove.Category)
|
||||||
|
{
|
||||||
|
case MoveCategory.Physical when
|
||||||
|
side.VolatileScripts.Contains(ScriptUtils.ResolveName<ReflectEffect>()):
|
||||||
|
case MoveCategory.Special when
|
||||||
|
side.VolatileScripts.Contains(ScriptUtils.ResolveName<LightScreenEffect>()):
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var modifier = 0.5f;
|
||||||
|
if (target.BattleData!.Battle.PositionsPerSide > 1)
|
||||||
|
modifier = 2732f / 4096f;
|
||||||
|
damage = (uint)(damage * modifier);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PkmnLib.Dynamic.Models;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Side, "double_power_if_target_damaged_in_turn_data")]
|
||||||
|
public class DoublePowerIfTargetDamagedInTurnData : Script
|
||||||
|
{
|
||||||
|
public HashSet<IPokemon> _hitPokemon = new();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnEndTurn()
|
||||||
|
{
|
||||||
|
RemoveSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnDamage(IPokemon pokemon, DamageSource source, uint oldHealth, uint newHealth)
|
||||||
|
{
|
||||||
|
_hitPokemon.Add(pokemon);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Side, "light_screen")]
|
||||||
|
public class LightScreenEffect : Script
|
||||||
|
{
|
||||||
|
// TODO: Implement LightScreenEffect
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Side;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Side, "reflect")]
|
||||||
|
public class ReflectEffect : Script
|
||||||
|
{
|
||||||
|
// TODO: Implement ReflectEffect
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling;
|
||||||
|
using PkmnLib.Dynamic.ScriptHandling.Registry;
|
||||||
|
|
||||||
|
namespace PkmnLib.Plugin.Gen7.Scripts.Weather;
|
||||||
|
|
||||||
|
[Script(ScriptCategory.Weather, "hail")]
|
||||||
|
public class Hail : Script
|
||||||
|
{
|
||||||
|
// TODO: Implement Hail weather effect
|
||||||
|
}
|
Loading…
Reference in New Issue