public PBEMoveLockPacket(PBEPokemon moveUser, PBEMove lockedMove, PBETarget lockedTargets, PBEMoveLockType moveLockType) { var bytes = new List <byte>(); bytes.AddRange(BitConverter.GetBytes(Code)); bytes.Add((byte)(MoveUser = moveUser.FieldPosition)); bytes.Add((MoveUserTeam = moveUser.Team).Id); bytes.AddRange(BitConverter.GetBytes((ushort)(LockedMove = lockedMove))); bytes.Add((byte)(LockedTargets = lockedTargets)); bytes.Add((byte)(MoveLockType = moveLockType)); Buffer = BitConverter.GetBytes((short)bytes.Count).Concat(bytes); }
/// <summary> /// Determines whether chosen targets are valid for a given move. /// </summary> /// <param name="pkmn">The Pokémon that will act.</param> /// <param name="move">The move the Pokémon wishes to use.</param> /// <param name="targets">The targets bitfield to validate.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="targets"/>, <paramref name="move"/>, <paramref name="pkmn"/>'s <see cref="PBEPokemon.FieldPosition"/>, or <paramref name="pkmn"/>'s <see cref="PBEBattle"/>'s <see cref="BattleFormat"/> is invalid.</exception> public static bool AreTargetsValid(PBEPokemon pkmn, PBEMove move, PBETarget targets) { if (move == PBEMove.None || move >= PBEMove.MAX) { throw new ArgumentOutOfRangeException(nameof(move)); } PBEMoveTarget possibleTargets = pkmn.GetMoveTargets(move); switch (pkmn.Team.Battle.BattleFormat) { case PBEBattleFormat.Single: { switch (possibleTargets) { case PBEMoveTarget.All: { if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == (PBETarget.AllyCenter | PBETarget.FoeCenter)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllFoes: case PBEMoveTarget.AllFoesSurrounding: case PBEMoveTarget.AllSurrounding: case PBEMoveTarget.SingleFoeSurrounding: case PBEMoveTarget.SingleNotSelf: case PBEMoveTarget.SingleSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == PBETarget.FoeCenter); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllTeam: case PBEMoveTarget.Self: case PBEMoveTarget.SelfOrAllySurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == PBETarget.AllyCenter); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.RandomFoeSurrounding: case PBEMoveTarget.SingleAllySurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(true); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } default: throw new ArgumentOutOfRangeException(nameof(possibleTargets)); } } case PBEBattleFormat.Double: { switch (possibleTargets) { case PBEMoveTarget.All: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.AllyLeft | PBETarget.AllyRight | PBETarget.FoeLeft | PBETarget.FoeRight)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllFoes: case PBEMoveTarget.AllFoesSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.FoeLeft | PBETarget.FoeRight)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllTeam: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.AllyLeft | PBETarget.AllyRight)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == (PBETarget.AllyRight | PBETarget.FoeLeft | PBETarget.FoeRight)); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.AllyLeft | PBETarget.FoeLeft | PBETarget.FoeRight)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.Self: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == PBETarget.AllyLeft); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyRight); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.SelfOrAllySurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyRight); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.SingleAllySurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == PBETarget.AllyRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyLeft); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.SingleFoeSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.FoeLeft || targets == PBETarget.FoeRight); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.SingleNotSelf: case PBEMoveTarget.SingleSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == PBETarget.AllyRight || targets == PBETarget.FoeLeft || targets == PBETarget.FoeRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyLeft || targets == PBETarget.FoeLeft || targets == PBETarget.FoeRight); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.RandomFoeSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Right) { return(true); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } default: throw new ArgumentOutOfRangeException(nameof(possibleTargets)); } } case PBEBattleFormat.Triple: { switch (possibleTargets) { case PBEMoveTarget.All: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.AllyLeft | PBETarget.AllyCenter | PBETarget.AllyRight | PBETarget.FoeLeft | PBETarget.FoeCenter | PBETarget.FoeRight)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllFoes: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.FoeLeft | PBETarget.FoeCenter | PBETarget.FoeRight)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllFoesSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == (PBETarget.FoeCenter | PBETarget.FoeRight)); } else if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == (PBETarget.FoeLeft | PBETarget.FoeCenter | PBETarget.FoeRight)); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.FoeLeft | PBETarget.FoeCenter)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == (PBETarget.AllyCenter | PBETarget.FoeCenter | PBETarget.FoeRight)); } else if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == (PBETarget.AllyLeft | PBETarget.AllyRight | PBETarget.FoeLeft | PBETarget.FoeCenter | PBETarget.FoeRight)); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.AllyCenter | PBETarget.FoeLeft | PBETarget.FoeCenter)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllTeam: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.AllyLeft | PBETarget.AllyCenter | PBETarget.AllyRight)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.Self: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == PBETarget.AllyLeft); } else if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == PBETarget.AllyCenter); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyRight); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.SelfOrAllySurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyCenter); } else if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyCenter || targets == PBETarget.AllyRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyCenter || targets == PBETarget.AllyRight); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.SingleAllySurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == PBETarget.AllyCenter); } else if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyCenter); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.SingleFoeSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.SingleNotSelf: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == PBETarget.AllyCenter || targets == PBETarget.AllyRight || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyRight || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyCenter || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.SingleSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left) { return(targets == PBETarget.AllyCenter || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Center) { return(targets == PBETarget.AllyLeft || targets == PBETarget.AllyRight || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter || targets == PBETarget.FoeRight); } else if (pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyCenter || targets == PBETarget.FoeLeft || targets == PBETarget.FoeCenter); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.RandomFoeSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right) { return(true); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } default: throw new ArgumentOutOfRangeException(nameof(possibleTargets)); } } case PBEBattleFormat.Rotation: { switch (possibleTargets) { case PBEMoveTarget.All: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == (PBETarget.AllyCenter | PBETarget.FoeCenter)); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllFoes: case PBEMoveTarget.AllFoesSurrounding: case PBEMoveTarget.AllSurrounding: case PBEMoveTarget.SingleFoeSurrounding: case PBEMoveTarget.SingleNotSelf: case PBEMoveTarget.SingleSurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.FoeCenter); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.AllTeam: case PBEMoveTarget.Self: case PBEMoveTarget.SelfOrAllySurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right) { return(targets == PBETarget.AllyCenter); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } case PBEMoveTarget.RandomFoeSurrounding: case PBEMoveTarget.SingleAllySurrounding: { if (pkmn.FieldPosition == PBEFieldPosition.Left || pkmn.FieldPosition == PBEFieldPosition.Center || pkmn.FieldPosition == PBEFieldPosition.Right) { return(true); } else { throw new ArgumentOutOfRangeException(nameof(pkmn.FieldPosition)); } } default: throw new ArgumentOutOfRangeException(nameof(possibleTargets)); } } default: throw new ArgumentOutOfRangeException(nameof(pkmn.Team.Battle.BattleFormat)); } }
/// <summary> /// Gets all Pokémon that will be hit. /// </summary> /// <param name="user">The Pokémon that will act.</param> /// <param name="requestedTargets">The targets the Pokémon wishes to hit.</param> /// <param name="canHitFarCorners">Whether the move can hit far Pokémon in a triple battle.</param> static PBEPokemon[] GetRuntimeTargets(PBEPokemon user, PBETarget requestedTargets, bool canHitFarCorners) { PBETeam opposingTeam = user.Team == user.Team.Battle.Teams[0] ? user.Team.Battle.Teams[1] : user.Team.Battle.Teams[0]; var targets = new List <PBEPokemon>(); if (requestedTargets.HasFlag(PBETarget.AllyLeft)) { targets.Add(user.Team.TryGetPokemon(PBEFieldPosition.Left)); } if (requestedTargets.HasFlag(PBETarget.AllyCenter)) { targets.Add(user.Team.TryGetPokemon(PBEFieldPosition.Center)); } if (requestedTargets.HasFlag(PBETarget.AllyRight)) { targets.Add(user.Team.TryGetPokemon(PBEFieldPosition.Right)); } if (requestedTargets.HasFlag(PBETarget.FoeLeft)) { PBEPokemon pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left); if (pkmn == null) { if (user.Team.Battle.BattleFormat == PBEBattleFormat.Double) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right); } else if (user.Team.Battle.BattleFormat == PBEBattleFormat.Triple) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Center); // Center fainted as well and user can reach far right if (pkmn == null && (user.FieldPosition != PBEFieldPosition.Right || canHitFarCorners)) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right); } } } targets.Add(pkmn); } if (requestedTargets.HasFlag(PBETarget.FoeCenter)) { PBEPokemon pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Center); // Target fainted, fallback to its teammate if (pkmn == null) { if (user.Team.Battle.BattleFormat == PBEBattleFormat.Triple) { if (user.FieldPosition == PBEFieldPosition.Left) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right); // Right fainted as well and user can reach far left if (pkmn == null && (user.FieldPosition != PBEFieldPosition.Left || canHitFarCorners)) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left); } } else if (user.FieldPosition == PBEFieldPosition.Right) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left); // Left fainted as well and user can reach far right if (pkmn == null && (user.FieldPosition != PBEFieldPosition.Right || canHitFarCorners)) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right); } } else // Center { PBEPokemon oppLeft = opposingTeam.TryGetPokemon(PBEFieldPosition.Left), oppRight = opposingTeam.TryGetPokemon(PBEFieldPosition.Right); // Left is dead but not right if (oppLeft == null && oppRight != null) { pkmn = oppRight; } // Right is dead but not left else if (oppLeft != null && oppRight == null) { pkmn = oppLeft; } // Randomly select left or right else { pkmn = PBEUtils.RNG.NextBoolean() ? oppLeft : oppRight; } } } } targets.Add(pkmn); } if (requestedTargets.HasFlag(PBETarget.FoeRight)) { PBEPokemon pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Right); // Target fainted, fallback to its teammate if (pkmn == null) { if (user.Team.Battle.BattleFormat == PBEBattleFormat.Double) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left); } else if (user.Team.Battle.BattleFormat == PBEBattleFormat.Triple) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Center); // Center fainted as well and user can reach far left if (pkmn == null && (user.FieldPosition != PBEFieldPosition.Left || canHitFarCorners)) { pkmn = opposingTeam.TryGetPokemon(PBEFieldPosition.Left); } } } targets.Add(pkmn); } return(targets.Where(p => p != null).Distinct().ToArray()); // Remove duplicate targets }