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 _targetedPokemon = []; /// 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)); } } /// public void PreventOpponentRunAway(IFleeChoice choice, ref bool prevent) { if (_targetedPokemon.Any(x => x.Pokemon == choice.User)) prevent = true; } /// public void PreventOpponentSwitch(ISwitchChoice choice, ref bool prevent) { if (_targetedPokemon.Any(x => x.Pokemon == choice.User)) prevent = true; } /// public void OnEndTurn(IScriptSource owner, IBattle battle) { if (_user == null) return; List? 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); } } /// 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); } } }