2025-07-11 17:03:08 +02:00

94 lines
2.8 KiB
C#

namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
[Script(ScriptCategory.Pokemon, "whirlpool")]
public class WhirlpoolEffect : Script, IScriptOnEndTurn, IScriptPreventOpponentRunAway, IScriptPreventOpponentSwitch,
IAIInfoScriptExpectedEndOfTurnDamage
{
public record PokemonTurn
{
public PokemonTurn(IPokemon pokemon, int turns, float damagePercent)
{
Pokemon = pokemon;
Turns = turns;
DamagePercent = damagePercent;
}
public IPokemon Pokemon { get; }
public int Turns { get; set; }
public float DamagePercent { get; }
}
private IPokemon? _user;
private readonly IList<PokemonTurn> _targetedPokemon = [];
/// <inheritdoc />
public override void OnAddedToParent(IScriptSource source)
{
if (source is IPokemon pokemon)
{
_user = pokemon;
}
else
{
throw new InvalidOperationException("WhirlpoolEffect can only be added to a Pokemon.");
}
}
public void AddTargetedPokemon(IPokemon pokemon, int turns, float damagePercent)
{
if (_targetedPokemon.All(x => x.Pokemon != pokemon))
{
_targetedPokemon.Add(new PokemonTurn(pokemon, turns, damagePercent));
}
}
/// <inheritdoc />
public void PreventOpponentRunAway(IFleeChoice choice, ref bool prevent)
{
if (_targetedPokemon.Any(x => x.Pokemon == choice.User))
prevent = true;
}
/// <inheritdoc />
public void PreventOpponentSwitch(ISwitchChoice choice, ref bool prevent)
{
if (_targetedPokemon.Any(x => x.Pokemon == choice.User))
prevent = true;
}
/// <inheritdoc />
public void OnEndTurn(IScriptSource owner, IBattle battle)
{
if (_user == null)
return;
List<PokemonTurn>? pokemonToRemove = null;
foreach (var pokemonTurn in _targetedPokemon.Where(x => x.Pokemon.BattleData?.IsOnBattlefield == true))
{
var pokemon = pokemonTurn.Pokemon;
pokemon.Damage((uint)(pokemon.MaxHealth * pokemonTurn.DamagePercent), DamageSource.Misc);
pokemonTurn.Turns--;
if (pokemonTurn.Turns <= 0)
{
pokemonToRemove ??= [];
pokemonToRemove.Add(pokemonTurn);
}
}
if (pokemonToRemove == null)
return;
foreach (var turn in pokemonToRemove)
{
_targetedPokemon.Remove(turn);
}
}
/// <inheritdoc />
public void ExpectedEndOfTurnDamage(IPokemon pokemon, ref int damage)
{
var turn = _targetedPokemon.FirstOrDefault(x => x.Pokemon == pokemon);
if (turn != null)
{
damage += (int)(pokemon.MaxHealth * turn.DamagePercent);
}
}
}