namespace PkmnLib.Plugin.Gen7.Scripts.Status; [Script(ScriptCategory.Status, "sleep")] public class Sleep : Script, IScriptChangeNumberOfHits, IAIInfoScriptNumberTurnsLeft { private IPokemon? _pokemon; public int Turns { get; set; } /// public override void OnAddedToParent(IScriptSource source) { // Rare case where the script is added again. Can happen for example when baton pass is used. if (Turns != 0) return; if (source is not IPokemon pokemon) throw new InvalidOperationException("Sleep script can only be added to a Pokemon."); _pokemon = pokemon; var battleData = pokemon.BattleData; if (battleData != null) { // 1-3 turns of sleep Turns = battleData.Battle.Random.GetInt(1, 4); var args = new CustomTriggers.ModifySleepTurnsArgs(pokemon, Turns); source.RunScriptHook(x => x.CustomTrigger(CustomTriggers.ModifySleepTurns, args)); Turns = Math.Max(1, args.Turns); } } /// /// /// This is slightly hacky, but setting number of hits to 0 stops the move *before* the MoveUseEvent is triggered, /// so this is cleaner for UI. /// public void ChangeNumberOfHits(IMoveChoice choice, ref byte numberOfHits) { Turns--; if (Turns < 0) { choice.User.ClearStatus(); return; } if (choice.ChosenMove.MoveData.HasFlag(MoveFlags.UsableWhileAsleep)) return; var args = new CustomTriggers.BypassSleepArgs(choice, false); choice.RunScriptHook(x => x.CustomTrigger(CustomTriggers.BypassSleep, args)); if (args.Bypass) return; numberOfHits = 0; } /// public override void OnRemove() { if (_pokemon is { IsFainted: false }) { _pokemon.BattleData?.Battle.EventHook.Invoke(new DialogEvent("pokemon_woke_up", new Dictionary { { "pokemon", _pokemon }, })); } } /// public int TurnsLeft() => Turns; }