using System.Linq; using PkmnLib.Static.Utils; namespace PkmnLib.Plugin.Gen7.Scripts.Moves; [Script(ScriptCategory.Move, "conversion_2")] public class Conversion2 : Script { /// public override void OnSecondaryEffect(IExecutingMove move, IPokemon target, byte hit) { var previousTurnChoices = target.BattleData?.Battle.PreviousTurnChoices; var nextExecutingChoice = target.BattleData?.Battle.ChoiceQueue?.Peek(); var lastMoveByTarget = previousTurnChoices? // The previous turn choices include the choices of the current turn, so we need to have special handling for // the current turn .Select((x, index) => { // All choices before the current turn are valid if (index < previousTurnChoices.Count - 1) return x; // If there is no next choice, we're at the end of the list, so we can just return the whole list if (nextExecutingChoice == null) return x; // Otherwise we determine where the next choice is and return everything before that var indexOfNext = x.IndexOf(nextExecutingChoice); if (indexOfNext == -1) return x; return x.Take(indexOfNext); }) .SelectMany(x => x) // We only want the last move choice by the target .OfType().FirstOrDefault(x => x.User == target); if (lastMoveByTarget == null) { move.GetHitData(target, hit).Fail(); return; } var typeLibrary = move.User.BattleData!.Battle.Library.StaticLibrary.Types; // Get all types against which the last move would be not very effective var type = typeLibrary.GetAllEffectivenessFromAttacking(lastMoveByTarget.ChosenMove.MoveData.MoveType) .Where(x => x.effectiveness < 1) // Shuffle them randomly, but deterministically .OrderBy(_ => move.User.BattleData.Battle.Random.GetInt()) .ThenBy(x => x.type.Value) // And grab the first one .Select(x => x.type) .FirstOrDefault(); if (type == null) { move.GetHitData(target, hit).Fail(); return; } move.User.SetTypes([type]); } }