Exemple #1
0
        private void DetermineTurnOrder()
        {
            _turnOrder.Clear();
            IEnumerable <PBEPokemon> pkmnSwitchingOut = ActiveBattlers.Where(p => p.TurnAction.Decision == PBETurnDecision.SwitchOut);
            IEnumerable <PBEPokemon> pkmnFighting     = ActiveBattlers.Where(p => p.TurnAction.Decision == PBETurnDecision.Fight);

            // Switching happens first:
            _turnOrder.AddRange(GetActingOrder(pkmnSwitchingOut, true));
            // Moves:
            sbyte GetPrio(PBEPokemon p)
            {
                PBEMoveData mData = PBEMoveData.Data[p.TurnAction.FightMove];

                return((sbyte)PBEUtils.Clamp(mData.Priority + (p.Ability == PBEAbility.Prankster && mData.Category == PBEMoveCategory.Status ? 1 : 0), sbyte.MinValue, sbyte.MaxValue));
            }

            foreach (sbyte priority in pkmnFighting.Select(p => GetPrio(p)).Distinct().OrderByDescending(p => p))
            {
                PBEPokemon[] pkmnWithThisPriority = pkmnFighting.Where(p => GetPrio(p) == priority).ToArray();
                if (pkmnWithThisPriority.Length > 0)
                {
                    Debug.WriteLine("Priority {0} bracket...", priority);
                    _turnOrder.AddRange(GetActingOrder(pkmnWithThisPriority, false));
                }
            }
        }
Exemple #2
0
        private void RunActionsInOrder()
        {
            foreach (PBEPokemon pkmn in _turnOrder.ToArray()) // Copy the list so a faint or ejection does not cause a collection modified exception
            {
                if (Winner != null)                           // Do not broadcast winner by calling WinCheck() in here; do it in TurnEnded()
                {
                    return;
                }
                else if (ActiveBattlers.Contains(pkmn))
                {
                    switch (pkmn.TurnAction.Decision)
                    {
                    case PBETurnDecision.Fight:
                    {
                        UseMove(pkmn, pkmn.TurnAction.FightMove, pkmn.TurnAction.FightTargets);
                        break;
                    }

                    case PBETurnDecision.SwitchOut:
                    {
                        SwitchTwoPokemon(pkmn, TryGetPokemon(pkmn.TurnAction.SwitchPokemonId), false);
                        break;
                    }

                    default: throw new ArgumentOutOfRangeException(nameof(pkmn.TurnAction.Decision));
                    }
                }
            }
        }
Exemple #3
0
        void RunActionsInOrder()
        {
            foreach (PBEPokemon pkmn in turnOrder.ToArray()) // Copy the list so a faint or ejection does not cause a collection modified exception
            {
                if (ActiveBattlers.Contains(pkmn))
                {
                    switch (pkmn.SelectedAction.Decision)
                    {
                    case PBEDecision.Fight:
                    {
                        UseMove(pkmn);
                        break;
                    }

                    case PBEDecision.SwitchOut:
                    {
                        SwitchTwoPokemon(pkmn, TryGetPokemon(pkmn.SelectedAction.SwitchPokemonId), false);
                        break;
                    }

                    default: throw new ArgumentOutOfRangeException(nameof(pkmn.SelectedAction.Decision));
                    }
                }
            }
        }
Exemple #4
0
 /// <summary>Gets a specific active <see cref="PBEPokemon"/> by its <see cref="PBEPokemon.FieldPosition"/>.</summary>
 /// <param name="pos">The <see cref="PBEFieldPosition"/> of the <see cref="PBEPokemon"/>.</param>
 public PBEPokemon TryGetPokemon(PBEFieldPosition pos)
 {
     if (IsDisposed)
     {
         throw new ObjectDisposedException(null);
     }
     return(ActiveBattlers.SingleOrDefault(p => p.FieldPosition == pos));
 }
Exemple #5
0
        void DetermineTurnOrder()
        {
            turnOrder.Clear();
            IEnumerable <PBEPokemon> pkmnSwitchingOut = ActiveBattlers.Where(p => p.SelectedAction.Decision == PBEDecision.SwitchOut);
            IEnumerable <PBEPokemon> pkmnFighting     = ActiveBattlers.Where(p => p.SelectedAction.Decision == PBEDecision.Fight);

            // Switching happens first:
            turnOrder.AddRange(GetActingOrder(pkmnSwitchingOut, true));
            // Moves:
            foreach (sbyte priority in pkmnFighting.Select(p => PBEMoveData.Data[p.SelectedAction.FightMove].Priority).Distinct().OrderByDescending(p => p))
            {
                IEnumerable <PBEPokemon> pkmnWithThisPriority = pkmnFighting.Where(p => PBEMoveData.Data[p.SelectedAction.FightMove].Priority == priority);
                if (pkmnWithThisPriority.Count() > 0)
                {
                    Debug.WriteLine("Priority {0} bracket...", priority);
                    turnOrder.AddRange(GetActingOrder(pkmnWithThisPriority, false));
                }
            }
        }
Exemple #6
0
 /// <summary>Gets a specific active <see cref="PBEBattlePokemon"/> by its <see cref="PBEBattlePokemon.FieldPosition"/>.</summary>
 /// <param name="pos">The <see cref="PBEFieldPosition"/> of the <see cref="PBEBattlePokemon"/>.</param>
 public PBEBattlePokemon TryGetPokemon(PBEFieldPosition pos)
 {
     return(ActiveBattlers.SingleOrDefault(p => p.FieldPosition == pos));
 }
Exemple #7
0
        private void SwitchesOrActions()
        {
            BattleState = PBEBattleState.Processing;
            OnStateChanged?.Invoke(this);

            PBETeam[] teamsWithSwitchIns = Teams.Where(t => t.SwitchInQueue.Count > 0).ToArray();
            if (teamsWithSwitchIns.Length > 0)
            {
                foreach (PBETeam team in teamsWithSwitchIns)
                {
                    ActiveBattlers.AddRange(team.SwitchInQueue);
                    BroadcastPkmnSwitchIn(team, team.SwitchInQueue.Select(p => CreateSwitchInInfo(p)).ToArray(), false);
                }
                DoSwitchInEffects(teamsWithSwitchIns.SelectMany(t => t.SwitchInQueue));
            }

            foreach (PBETeam team in Teams)
            {
                int available = team.NumPkmnAlive - team.NumPkmnOnField;
                team.SwitchInsRequired = 0;
                team.SwitchInQueue.Clear();
                switch (BattleFormat)
                {
                case PBEBattleFormat.Single:
                {
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Center) == null)
                    {
                        team.SwitchInsRequired = 1;
                    }
                    break;
                }

                case PBEBattleFormat.Double:
                {
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Left) == null)
                    {
                        available--;
                        team.SwitchInsRequired++;
                    }
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Right) == null)
                    {
                        team.SwitchInsRequired++;
                    }
                    break;
                }

                case PBEBattleFormat.Rotation:
                case PBEBattleFormat.Triple:
                {
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Left) == null)
                    {
                        available--;
                        team.SwitchInsRequired++;
                    }
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Center) == null)
                    {
                        available--;
                        team.SwitchInsRequired++;
                    }
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Right) == null)
                    {
                        team.SwitchInsRequired++;
                    }
                    break;
                }

                default: throw new ArgumentOutOfRangeException(nameof(BattleFormat));
                }
            }
            teamsWithSwitchIns = Teams.Where(t => t.SwitchInsRequired > 0).ToArray();
            if (teamsWithSwitchIns.Length > 0)
            {
                BattleState = PBEBattleState.WaitingForSwitchIns;
                OnStateChanged?.Invoke(this);
                foreach (PBETeam team in teamsWithSwitchIns)
                {
                    BroadcastSwitchInRequest(team);
                }
            }
            else
            {
                if (WinCheck())
                {
                    return;
                }

                foreach (PBEPokemon pkmn in ActiveBattlers)
                {
                    pkmn.SpeedBoost_AbleToSpeedBoostThisTurn = pkmn.Ability == PBEAbility.SpeedBoost;
                    if (pkmn.Status2.HasFlag(PBEStatus2.Flinching))
                    {
                        pkmn.Status2 &= ~PBEStatus2.Flinching;
                        BroadcastStatus2(pkmn, pkmn, PBEStatus2.Flinching, PBEStatusAction.Ended);
                    }
                    if (pkmn.Status2.HasFlag(PBEStatus2.HelpingHand))
                    {
                        pkmn.Status2 &= ~PBEStatus2.HelpingHand;
                        BroadcastStatus2(pkmn, pkmn, PBEStatus2.HelpingHand, PBEStatusAction.Ended);
                    }
                    if (pkmn.Status2.HasFlag(PBEStatus2.Protected))
                    {
                        pkmn.Status2 &= ~PBEStatus2.Protected;
                        BroadcastStatus2(pkmn, pkmn, PBEStatus2.Protected, PBEStatusAction.Ended);
                    }
                }
                foreach (PBETeam team in Teams)
                {
                    if (team.TeamStatus.HasFlag(PBETeamStatus.WideGuard))
                    {
                        team.TeamStatus &= ~PBETeamStatus.WideGuard;
                        BroadcastTeamStatus(team, PBETeamStatus.WideGuard, PBETeamStatusAction.Ended);
                    }
                }
                foreach (PBETeam team in Teams)
                {
                    team.ActionsRequired.Clear();
                    team.ActionsRequired.AddRange(team.ActiveBattlers);
                }

                if (BattleFormat == PBEBattleFormat.Triple && Teams.All(t => t.NumPkmnAlive == 1))
                {
                    PBEPokemon pkmn1 = ActiveBattlers[0],
                               pkmn2 = ActiveBattlers[1];
                    if ((pkmn1.FieldPosition == PBEFieldPosition.Left && pkmn2.FieldPosition == PBEFieldPosition.Right) || (pkmn1.FieldPosition == PBEFieldPosition.Right && pkmn2.FieldPosition == PBEFieldPosition.Left))
                    {
                        PBEFieldPosition pkmn1OldPos = pkmn1.FieldPosition,
                                         pkmn2OldPos = pkmn2.FieldPosition;
                        pkmn2.FieldPosition = pkmn1.FieldPosition = PBEFieldPosition.Center;
                        BroadcastAutoCenter(pkmn1.Id, pkmn1OldPos, pkmn1.Team, pkmn2.Id, pkmn2OldPos, pkmn2.Team);
                    }
                }

                TurnNumber++;
                BroadcastTurnBegan();
                foreach (PBETeam team in Teams)
                {
                    bool old = team.MonFaintedThisTurn; // Fire events in a specific order
                    team.MonFaintedThisTurn = false;
                    team.MonFaintedLastTurn = old;
                }
                BattleState = PBEBattleState.WaitingForActions;
                OnStateChanged?.Invoke(this);
                foreach (PBETeam team in Teams)
                {
                    BroadcastActionsRequest(team);
                }
            }
        }
Exemple #8
0
 /// <summary>
 /// Gets a specific active Pokémon by its position.
 /// </summary>
 /// <param name="pos">The position of the Pokémon you want to get.</param>
 /// <returns>null if no Pokémon was found was found at <paramref name="pos"/>; otherwise the <see cref="PBEPokemon"/>.</returns>
 public PBEPokemon TryGetPokemon(PBEFieldPosition pos) => ActiveBattlers.SingleOrDefault(p => p.FieldPosition == pos);
Exemple #9
0
        private void SwitchesOrActions()
        {
            BattleState = PBEBattleState.Processing;
            OnStateChanged?.Invoke(this);

            // Checking SwitchInQueue count since SwitchInsRequired is set to 0 after submitting switches
            PBETrainer[] trainersWithSwitchIns = Trainers.Where(t => t.SwitchInQueue.Count > 0).ToArray();
            if (trainersWithSwitchIns.Length > 0)
            {
                var list = new List <PBEBattlePokemon>(6);
                foreach (PBETrainer trainer in trainersWithSwitchIns)
                {
                    int count    = trainer.SwitchInQueue.Count;
                    var switches = new PBEPkmnSwitchInPacket.PBESwitchInInfo[count];
                    for (int i = 0; i < count; i++)
                    {
                        (PBEBattlePokemon pkmn, PBEFieldPosition pos) = trainer.SwitchInQueue[i];
                        pkmn.FieldPosition = pos;
                        switches[i]        = CreateSwitchInInfo(pkmn);
                        PBETrainer.SwitchTwoPokemon(pkmn, pos);
                        ActiveBattlers.Add(pkmn); // Add before broadcast
                        list.Add(pkmn);
                    }
                    BroadcastPkmnSwitchIn(trainer, switches);
                }
                DoSwitchInEffects(list);
            }

            foreach (PBETrainer trainer in Trainers)
            {
                int available = trainer.NumConsciousPkmn - trainer.NumPkmnOnField;
                trainer.SwitchInsRequired = 0;
                trainer.SwitchInQueue.Clear();
                if (available > 0)
                {
                    switch (BattleFormat)
                    {
                    case PBEBattleFormat.Single:
                    {
                        if (trainer.TryGetPokemon(PBEFieldPosition.Center) == null)
                        {
                            trainer.SwitchInsRequired = 1;
                        }
                        break;
                    }

                    case PBEBattleFormat.Double:
                    {
                        if (trainer.OwnsSpot(PBEFieldPosition.Left) && trainer.TryGetPokemon(PBEFieldPosition.Left) == null)
                        {
                            available--;
                            trainer.SwitchInsRequired++;
                        }
                        if (available > 0 && trainer.OwnsSpot(PBEFieldPosition.Right) && trainer.TryGetPokemon(PBEFieldPosition.Right) == null)
                        {
                            trainer.SwitchInsRequired++;
                        }
                        break;
                    }

                    case PBEBattleFormat.Rotation:
                    case PBEBattleFormat.Triple:
                    {
                        if (trainer.OwnsSpot(PBEFieldPosition.Left) && trainer.TryGetPokemon(PBEFieldPosition.Left) == null)
                        {
                            available--;
                            trainer.SwitchInsRequired++;
                        }
                        if (available > 0 && trainer.OwnsSpot(PBEFieldPosition.Center) && trainer.TryGetPokemon(PBEFieldPosition.Center) == null)
                        {
                            available--;
                            trainer.SwitchInsRequired++;
                        }
                        if (available > 0 && trainer.OwnsSpot(PBEFieldPosition.Right) && trainer.TryGetPokemon(PBEFieldPosition.Right) == null)
                        {
                            trainer.SwitchInsRequired++;
                        }
                        break;
                    }

                    default: throw new ArgumentOutOfRangeException(nameof(BattleFormat));
                    }
                }
            }
            trainersWithSwitchIns = Trainers.Where(t => t.SwitchInsRequired > 0).ToArray();
            if (trainersWithSwitchIns.Length > 0)
            {
                BattleState = PBEBattleState.WaitingForSwitchIns;
                OnStateChanged?.Invoke(this);
                foreach (PBETrainer trainer in trainersWithSwitchIns)
                {
                    BroadcastSwitchInRequest(trainer);
                }
            }
            else
            {
                if (WinCheck())
                {
                    return;
                }

                foreach (PBEBattlePokemon pkmn in ActiveBattlers)
                {
                    pkmn.HasUsedMoveThisTurn = false;
                    pkmn.TurnAction          = null;
                    pkmn.SpeedBoost_AbleToSpeedBoostThisTurn = pkmn.Ability == PBEAbility.SpeedBoost;

                    if (pkmn.Status2.HasFlag(PBEStatus2.Flinching))
                    {
                        BroadcastStatus2(pkmn, pkmn, PBEStatus2.Flinching, PBEStatusAction.Ended);
                    }
                    if (pkmn.Status2.HasFlag(PBEStatus2.HelpingHand))
                    {
                        BroadcastStatus2(pkmn, pkmn, PBEStatus2.HelpingHand, PBEStatusAction.Ended);
                    }
                    if (pkmn.Status2.HasFlag(PBEStatus2.LockOn))
                    {
                        if (--pkmn.LockOnTurns == 0)
                        {
                            pkmn.LockOnPokemon = null;
                            BroadcastStatus2(pkmn, pkmn, PBEStatus2.LockOn, PBEStatusAction.Ended);
                        }
                    }
                    if (pkmn.Protection_Used)
                    {
                        pkmn.Protection_Counter++;
                        pkmn.Protection_Used = false;
                        if (pkmn.Status2.HasFlag(PBEStatus2.Protected))
                        {
                            BroadcastStatus2(pkmn, pkmn, PBEStatus2.Protected, PBEStatusAction.Ended);
                        }
                    }
                    else
                    {
                        pkmn.Protection_Counter = 0;
                    }
                    if (pkmn.Status2.HasFlag(PBEStatus2.Roost))
                    {
                        pkmn.EndRoost();
                        BroadcastStatus2(pkmn, pkmn, PBEStatus2.Roost, PBEStatusAction.Ended);
                    }
                }
                foreach (PBETeam team in Teams)
                {
                    if (team.TeamStatus.HasFlag(PBETeamStatus.QuickGuard))
                    {
                        BroadcastTeamStatus(team, PBETeamStatus.QuickGuard, PBETeamStatusAction.Ended);
                    }
                    if (team.TeamStatus.HasFlag(PBETeamStatus.WideGuard))
                    {
                        BroadcastTeamStatus(team, PBETeamStatus.WideGuard, PBETeamStatusAction.Ended);
                    }
                }
                foreach (PBETrainer trainer in Trainers)
                {
                    trainer.ActionsRequired.Clear();
                    trainer.ActionsRequired.AddRange(trainer.ActiveBattlers);
                }

                if (BattleFormat == PBEBattleFormat.Triple && Teams.All(t => t.NumConsciousPkmn == 1))
                {
                    PBEBattlePokemon pkmn0 = ActiveBattlers[0],
                                     pkmn1 = ActiveBattlers[1];
                    if ((pkmn0.FieldPosition == PBEFieldPosition.Left && pkmn1.FieldPosition == PBEFieldPosition.Left) || (pkmn0.FieldPosition == PBEFieldPosition.Right && pkmn1.FieldPosition == PBEFieldPosition.Right))
                    {
                        PBEFieldPosition pkmn0OldPos = pkmn0.FieldPosition,
                                         pkmn1OldPos = pkmn1.FieldPosition;
                        pkmn0.FieldPosition = PBEFieldPosition.Center;
                        pkmn1.FieldPosition = PBEFieldPosition.Center;
                        BroadcastAutoCenter(pkmn0, pkmn0OldPos, pkmn1, pkmn1OldPos);
                    }
                }

                TurnNumber++;
                BroadcastTurnBegan();
                foreach (PBETeam team in Teams)
                {
                    bool old = team.MonFaintedThisTurn; // Fire events in a specific order
                    team.MonFaintedThisTurn = false;
                    team.MonFaintedLastTurn = old;
                }
                BattleState = PBEBattleState.WaitingForActions;
                OnStateChanged?.Invoke(this);
                foreach (PBETrainer trainer in Trainers.Where(t => t.NumConsciousPkmn > 0))
                {
                    BroadcastActionsRequest(trainer);
                }
            }
        }
Exemple #10
0
        // Sets BattleState to PBEBattleState.Processing/PBEBattleState.WaitingForActions/PBEBattleState.WaitingForSwitches/PBEBattleState.Ended
        void SwitchesOrActions()
        {
            BattleState = PBEBattleState.Processing;
            OnStateChanged?.Invoke(this);

            IEnumerable <PBETeam> teamsWithSwitchIns = Teams.Where(t => t.SwitchInQueue.Count > 0);

            if (teamsWithSwitchIns.Count() > 0)
            {
                foreach (PBETeam team in teamsWithSwitchIns)
                {
                    ActiveBattlers.AddRange(team.SwitchInQueue);
                    BroadcastPkmnSwitchIn(team, team.SwitchInQueue.Select(p => CreateSwitchInInfo(p)), false);
                }
                DoSwitchInEffects(teamsWithSwitchIns.SelectMany(t => t.SwitchInQueue));
            }

            foreach (PBETeam team in Teams)
            {
                int available = team.NumPkmnAlive - team.NumPkmnOnField;
                team.SwitchInsRequired = 0;
                team.SwitchInQueue.Clear();
                switch (BattleFormat)
                {
                case PBEBattleFormat.Single:
                {
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Center) == null)
                    {
                        team.SwitchInsRequired = 1;
                    }
                    break;
                }

                case PBEBattleFormat.Double:
                {
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Left) == null)
                    {
                        available--;
                        team.SwitchInsRequired++;
                    }
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Right) == null)
                    {
                        team.SwitchInsRequired++;
                    }
                    break;
                }

                case PBEBattleFormat.Rotation:
                case PBEBattleFormat.Triple:
                {
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Left) == null)
                    {
                        available--;
                        team.SwitchInsRequired++;
                    }
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Center) == null)
                    {
                        available--;
                        team.SwitchInsRequired++;
                    }
                    if (available > 0 && team.TryGetPokemon(PBEFieldPosition.Right) == null)
                    {
                        team.SwitchInsRequired++;
                    }
                    break;
                }

                default: throw new ArgumentOutOfRangeException(nameof(BattleFormat));
                }
            }
            teamsWithSwitchIns = Teams.Where(t => t.SwitchInsRequired > 0);
            if (teamsWithSwitchIns.Count() > 0)
            {
                BattleState = PBEBattleState.WaitingForSwitchIns;
                OnStateChanged?.Invoke(this);
                foreach (PBETeam team in teamsWithSwitchIns)
                {
                    BroadcastSwitchInRequest(team);
                }
            }
            else
            {
                if (WinCheck())
                {
                    return;
                }

                foreach (PBEPokemon pkmn in ActiveBattlers)
                {
                    pkmn.Status2 &= ~PBEStatus2.Flinching;
                    pkmn.Status2 &= ~PBEStatus2.Protected;
                }
                foreach (PBETeam team in Teams)
                {
                    team.ActionsRequired.Clear();
                    team.ActionsRequired.AddRange(team.ActiveBattlers);
                }

                TurnNumber++;
                BroadcastTurnBegan();
                BattleState = PBEBattleState.WaitingForActions;
                OnStateChanged?.Invoke(this);
                foreach (PBETeam team in Teams)
                {
                    BroadcastActionsRequest(team);
                }
            }
        }