namespace PkmnLib.Plugin.Gen7.Scripts.Battle; [Script(ScriptCategory.Battle, "future_sight")] public class FutureSightEffect : Script, IScriptOnEndTurn { private class PendingStrike { public IMoveChoice MoveChoice { get; } public int Turns { get; set; } public PendingStrike(IMoveChoice moveChoice) { MoveChoice = moveChoice; Turns = 3; } } private readonly List _strikes = new(); public FutureSightEffect(IMoveChoice moveChoice) { AddStrike(moveChoice); } public void AddStrike(IMoveChoice moveChoice) { _strikes.Add(new PendingStrike(moveChoice)); } public bool HasStrikeAt(byte side, byte position) { return _strikes.Exists(x => x.MoveChoice.TargetSide == side && x.MoveChoice.TargetPosition == position); } /// public void OnEndTurn(IScriptSource owner, IBattle battle) { var toRemove = new List(); foreach (var strike in _strikes) { strike.Turns--; if (strike.Turns == 0) { ExecuteStrike(battle, strike.MoveChoice); toRemove.Add(strike); } } foreach (var strike in toRemove) { _strikes.Remove(strike); } if (_strikes.Count == 0) { RemoveSelf(); } } private static void ExecuteStrike(IBattle battle, IMoveChoice moveChoice) { var target = battle.GetPokemon(moveChoice.TargetSide, moveChoice.TargetPosition); if (target is not { IsUsable: true }) { battle.EventHook.Invoke(new DialogEvent("move_failed")); return; } var damageCalculator = battle.Library.DamageCalculator; var executingMove = new ExecutingMoveImpl([target], 1, moveChoice.ChosenMove, moveChoice.ChosenMove.MoveData, moveChoice, battle); var hitData = executingMove.GetHitData(target, 0); var damage = damageCalculator.GetDamage(executingMove, executingMove.UseMove.Category, executingMove.User, target, executingMove.TargetCount, 1, hitData); target.Damage(damage, DamageSource.Misc); } }