using PkmnLib.Static.Moves; namespace PkmnLib.Dynamic.Models.BattleFlow; /// /// Helper class for resolving the targets of a move. /// public static class TargetResolver { /// /// Get the targets of a move based on the target type, and the selected side and position to target. /// public static IReadOnlyList ResolveTargets(IBattle battle, byte side, byte position, MoveTarget target) { return target switch { MoveTarget.Adjacent or MoveTarget.AdjacentAlly or MoveTarget.AdjacentAllySelf or MoveTarget.AdjacentOpponent or MoveTarget.Any or MoveTarget.RandomOpponent or MoveTarget.SelfUse => [battle.GetPokemon(side, position)], MoveTarget.All => GetAllTargets(battle), MoveTarget.AllAdjacentOpponent => GetAllAdjacentAndOpponent(battle, side, position), MoveTarget.AllAdjacent => GetAllAdjacent(battle, side, position), MoveTarget.AllAlly => battle.Sides[side].Pokemon.ToList(), MoveTarget.AllOpponent => battle.Sides[GetOppositeSide(side)].Pokemon.ToList(), _ => throw new ArgumentOutOfRangeException(nameof(target), target, null), }; } private static IReadOnlyList GetAllTargets(IBattle battle) => battle.Sides.SelectMany(x => x.Pokemon).ToList(); private static byte GetOppositeSide(byte side) => side == 0 ? (byte)1 : (byte)0; /// /// Gets all Pokémon that are adjacent to of directly opposite of a Pokémon. This means the target, /// the Pokémon left of it, the Pokémon right of it, and the Pokémon opposite of it. /// private static IReadOnlyList GetAllAdjacentAndOpponent(IBattle battle, byte side, byte position) { var left = position - 1; var right = position + 1; if (left < 0 && right >= battle.PositionsPerSide) { return [battle.GetPokemon(side, position), battle.GetPokemon(GetOppositeSide(side), position)]; } if (left < 0) { return [ battle.GetPokemon(side, position), battle.GetPokemon(GetOppositeSide(side), position), battle.GetPokemon(side, (byte)right), ]; } if (right >= battle.PositionsPerSide) { return [ battle.GetPokemon(side, position), battle.GetPokemon(GetOppositeSide(side), position), battle.GetPokemon(side, (byte)left), ]; } return [ battle.GetPokemon(side, position), battle.GetPokemon(GetOppositeSide(side), position), battle.GetPokemon(side, (byte)left), battle.GetPokemon(side, (byte)right), ]; } private static IReadOnlyList GetAllAdjacent(IBattle battle, byte side, byte position) { var left = position - 1; var right = position + 1; if (left < 0 && right >= battle.PositionsPerSide) { return [battle.GetPokemon(side, position)]; } if (left < 0) { return [battle.GetPokemon(side, position), battle.GetPokemon(side, (byte)right)]; } if (right >= battle.PositionsPerSide) { return [battle.GetPokemon(side, position), battle.GetPokemon(side, (byte)left)]; } return [ battle.GetPokemon(side, position), battle.GetPokemon(side, (byte)left), battle.GetPokemon(side, (byte)right), ]; } }