protected override bool ProcessPacket(IPBEPacket packet)
        {
            switch (packet)
            {
            case PBEActionsRequestPacket arp:
            {
                PBETrainer t = arp.Trainer;
                if (t == Trainer)
                {
                    _ = new ActionsBuilder(BattleView, Trainer, OnActionsReady);
                }
                else
                {
                    CreateBattleThread(GetAI(t).CreateActions);
                }
                return(true);
            }

            case PBESwitchInRequestPacket sirp:
            {
                PBETrainer t = sirp.Trainer;
                if (t == Trainer)
                {
                    _ = new SwitchesBuilder(BattleView, sirp.Amount, OnSwitchesReady);
                }
                else
                {
                    CreateBattleThread(GetAI(t).CreateSwitches);
                }
                return(true);
            }
            }
            return(base.ProcessPacket(packet));
        }
        protected override bool ProcessPacket(IPBEPacket packet)
        {
            switch (packet)
            {
            case PBEMovePPChangedPacket mpcp:
            {
                PBEBattlePokemon moveUser = mpcp.MoveUserTrainer.GetPokemon(mpcp.MoveUser);
                if (moveUser.Trainer == Trainer)
                {
                    moveUser.Moves[mpcp.Move] !.PP -= mpcp.AmountReduced;
                }
                break;
            }

            case PBEActionsRequestPacket arp:
            {
                if (arp.Trainer == Trainer)
                {
                    _ = new ActionsBuilder(BattleView, Trainer, OnActionsReady);
                }
                else if (Trainer is null || Trainer.NumConsciousPkmn == 0)     // Spectators/KO'd
                {
                    BattleView.AddMessage("Waiting for players...", messageLog: false);
                }
                return(true);
            }

            case PBESwitchInRequestPacket sirp:
            {
                PBETrainer t = sirp.Trainer;
                t.SwitchInsRequired = sirp.Amount;
                if (t == Trainer)
                {
                    _ = new SwitchesBuilder(BattleView, sirp.Amount, OnSwitchesReady);
                }
                else if (BattleView.Actions.SwitchesBuilder?.SwitchesRequired == 0)     // No need to switch/Spectators/KO'd
                {
                    BattleView.AddMessage("Waiting for players...", messageLog: false);
                }
                return(true);
            }

            case PBEPkmnFaintedPacket_Hidden pfph:
            {
                bool             ret     = base.ProcessPacket(packet); // Process before removal
                PBEBattlePokemon pokemon = pfph.PokemonTrainer.GetPokemon(pfph.OldPosition);
                Battle.ActiveBattlers.Remove(pokemon);
                pokemon.FieldPosition = PBEFieldPosition.None;
                PBETrainer.Remove(pokemon);
                return(ret);
            }

            case PBEPkmnFormChangedPacket_Hidden pfcph:
            {
                PBEBattlePokemon pokemon = pfcph.PokemonTrainer.GetPokemon(pfcph.Pokemon);
                pokemon.HPPercentage = pfcph.NewHPPercentage;
                pokemon.KnownAbility = pfcph.NewKnownAbility;
                pokemon.KnownForm    = pfcph.NewForm;
                pokemon.KnownType1   = pfcph.NewType1;
                pokemon.KnownType2   = pfcph.NewType2;
                pokemon.KnownWeight  = pfcph.NewWeight;
                break;
            }

            case PBEPkmnHPChangedPacket_Hidden phcph:
            {
                PBEBattlePokemon pokemon = phcph.PokemonTrainer.GetPokemon(phcph.Pokemon);
                pokemon.HPPercentage = phcph.NewHPPercentage;
                break;
            }

            case PBEPkmnSwitchInPacket_Hidden psiph:
            {
                foreach (PBEPkmnSwitchInPacket_Hidden.PBEPkmnSwitchInInfo info in psiph.SwitchIns)
                {
                    _ = new PBEBattlePokemon(psiph.Trainer, info);
                }
                break;
            }

            case PBEPkmnSwitchOutPacket_Hidden psoph:
            {
                bool             ret     = base.ProcessPacket(packet); // Process before removal
                PBEBattlePokemon pokemon = psoph.PokemonTrainer.GetPokemon(psoph.OldPosition);
                Battle.ActiveBattlers.Remove(pokemon);
                PBETrainer.Remove(pokemon);
                return(ret);
            }

            case PBEReflectTypePacket_Hidden rtph:
            {
                PBEBattlePokemon user   = rtph.UserTrainer.GetPokemon(rtph.User);
                PBEBattlePokemon target = rtph.TargetTrainer.GetPokemon(rtph.Target);
                user.Type1 = user.KnownType1 = target.KnownType1;     // Set Type1 and Type2 so Transform works
                user.Type2 = user.KnownType2 = target.KnownType2;
                break;
            }

            case PBEWildPkmnAppearedPacket wpap:
            {
                PBETrainer wildTrainer = Battle.Teams[1].Trainers[0];
                foreach (PBEPkmnAppearedInfo info in wpap.Pokemon)
                {
                    PBEBattlePokemon pokemon = wildTrainer.GetPokemon(info.Pokemon);
                    pokemon.FieldPosition = info.FieldPosition;
                    Battle.ActiveBattlers.Add(pokemon);
                }
                break;
            }

            case PBEWildPkmnAppearedPacket_Hidden wpaph:
            {
                foreach (PBEWildPkmnAppearedPacket_Hidden.PBEWildPkmnInfo info in wpaph.Pokemon)
                {
                    _ = new PBEBattlePokemon(Battle, info);
                }
                break;
            }
            }
            return(base.ProcessPacket(packet));
        }