Example #1
0
        protected override bool ProcessPacket(IPBEPacket packet)
        {
            switch (packet)
            {
            case PBEAbilityPacket ap:
            {
                PBEBattlePokemon abilityOwner = ap.AbilityOwnerTrainer.TryGetPokemon(ap.AbilityOwner);
                abilityOwner.Ability      = ap.Ability;
                abilityOwner.KnownAbility = ap.Ability;
                break;
            }

            case PBEAbilityReplacedPacket arp:
            {
                PBEBattlePokemon abilityOwner = arp.AbilityOwnerTrainer.TryGetPokemon(arp.AbilityOwner);
                abilityOwner.Ability      = arp.NewAbility;
                abilityOwner.KnownAbility = arp.NewAbility;
                break;
            }

            case PBEBattleStatusPacket bsp:
            {
                switch (bsp.BattleStatusAction)
                {
                case PBEBattleStatusAction.Added: Battle.BattleStatus |= bsp.BattleStatus; break;

                case PBEBattleStatusAction.Cleared:
                case PBEBattleStatusAction.Ended: Battle.BattleStatus &= ~bsp.BattleStatus; break;

                default: throw new ArgumentOutOfRangeException(nameof(bsp.BattleStatusAction));
                }
                break;
            }

            case PBECapturePacket cp:
            {
                if (cp.Success)
                {
                    PBEBattlePokemon pokemon = cp.PokemonTrainer.TryGetPokemon(cp.Pokemon);
                    pokemon.CaughtBall      = cp.Ball;
                    pokemon.KnownCaughtBall = cp.Ball;
                }
                break;
            }

            case PBEHazePacket _:
            {
                foreach (PBEBattlePokemon pkmn in Battle.ActiveBattlers)
                {
                    pkmn.ClearStatChanges();
                }
                break;
            }

            case PBEIllusionPacket ilp:
            {
                PBEBattlePokemon pokemon = ilp.PokemonTrainer.TryGetPokemon(ilp.Pokemon);
                pokemon.Ability    = pokemon.KnownAbility = PBEAbility.Illusion;
                pokemon.Gender     = pokemon.KnownGender = ilp.ActualGender;
                pokemon.CaughtBall = pokemon.KnownCaughtBall = ilp.ActualCaughtBall;
                pokemon.Nickname   = pokemon.KnownNickname = ilp.ActualNickname;
                pokemon.Shiny      = pokemon.KnownShiny = ilp.ActualShiny;
                pokemon.Species    = pokemon.KnownSpecies = ilp.ActualSpecies;
                pokemon.Form       = pokemon.KnownForm = ilp.ActualForm;
                pokemon.Type1      = pokemon.KnownType1 = ilp.ActualType1;
                pokemon.Type2      = pokemon.KnownType2 = ilp.ActualType2;
                pokemon.Weight     = pokemon.KnownWeight = ilp.ActualWeight;
                return(true);
            }

            case PBEItemPacket ip:
            {
                PBEBattlePokemon itemHolder = ip.ItemHolderTrainer.TryGetPokemon(ip.ItemHolder);
                switch (ip.ItemAction)
                {
                case PBEItemAction.Announced:
                case PBEItemAction.Damage:
                case PBEItemAction.RestoredHP: itemHolder.Item = itemHolder.KnownItem = ip.Item; break;

                case PBEItemAction.Consumed: itemHolder.Item = itemHolder.KnownItem = PBEItem.None; break;

                default: throw new ArgumentOutOfRangeException(nameof(ip.ItemAction));
                }
                break;
            }

            case PBEMoveLockPacket mlp:
            {
                PBEBattlePokemon moveUser = mlp.MoveUserTrainer.TryGetPokemon(mlp.MoveUser);
                switch (mlp.MoveLockType)
                {
                case PBEMoveLockType.ChoiceItem: moveUser.ChoiceLockedMove = mlp.LockedMove; break;

                case PBEMoveLockType.Temporary: moveUser.TempLockedMove = mlp.LockedMove; break;

                default: throw new ArgumentOutOfRangeException(nameof(mlp.MoveLockType));
                }
                if (mlp.LockedTargets.HasValue)
                {
                    moveUser.TempLockedTargets = mlp.LockedTargets.Value;
                }
                return(true);
            }

            case PBEMovePPChangedPacket mpcp:
            {
                PBEBattlePokemon moveUser = mpcp.MoveUserTrainer.TryGetPokemon(mpcp.MoveUser);
                moveUser.UpdateKnownPP(mpcp.Move, mpcp.AmountReduced);
                return(true);
            }

            case PBEMoveUsedPacket mup:
            {
                PBEBattlePokemon moveUser = mup.MoveUserTrainer.TryGetPokemon(mup.MoveUser);
                if (mup.Owned && !moveUser.KnownMoves.Contains(mup.Move))
                {
                    moveUser.KnownMoves[PBEMove.MAX].Move = mup.Move;
                    PBEBattleMoveset.PBEBattleMovesetSlot slot = moveUser.Moves[PBEMove.MAX];
                    if (slot != null)
                    {
                        slot.Move = mup.Move;     // Copy to Moves as well so Transform doesn't break for spectators/allies
                    }
                }
                break;
            }

            case PBEPkmnFaintedPacket pfp:
            {
                bool             ret     = base.ProcessPacket(packet); // Process before removal
                PBEBattlePokemon pokemon = pfp.PokemonTrainer.TryGetPokemon(pfp.Pokemon);
                Battle.ActiveBattlers.Remove(pokemon);
                pokemon.ClearForFaint();
                return(ret);
            }

            case PBEPkmnFormChangedPacket pfcp:
            {
                PBEBattlePokemon pokemon = pfcp.PokemonTrainer.TryGetPokemon(pfcp.Pokemon);
                pokemon.Attack       = pfcp.NewAttack;
                pokemon.Defense      = pfcp.NewDefense;
                pokemon.SpAttack     = pfcp.NewSpAttack;
                pokemon.SpDefense    = pfcp.NewSpDefense;
                pokemon.Speed        = pfcp.NewSpeed;
                pokemon.Ability      = pfcp.NewAbility;
                pokemon.KnownAbility = pfcp.NewKnownAbility;
                pokemon.Form         = pokemon.KnownForm = pfcp.NewForm;
                pokemon.Type1        = pokemon.KnownType1 = pfcp.NewType1;
                pokemon.Type2        = pokemon.KnownType2 = pfcp.NewType2;
                pokemon.Weight       = pokemon.KnownWeight = pfcp.NewWeight;
                if (pfcp.IsRevertForm)
                {
                    pokemon.RevertForm    = pfcp.NewForm;
                    pokemon.RevertAbility = pfcp.NewAbility;
                }
                break;
            }

            case PBEPkmnHPChangedPacket phcp:
            {
                PBEBattlePokemon pokemon = phcp.PokemonTrainer.TryGetPokemon(phcp.Pokemon);
                pokemon.HP           = phcp.NewHP;
                pokemon.HPPercentage = phcp.NewHPPercentage;
                break;
            }

            case PBEPkmnStatChangedPacket pscp:
            {
                PBEBattlePokemon pokemon = pscp.PokemonTrainer.TryGetPokemon(pscp.Pokemon);
                pokemon.SetStatChange(pscp.Stat, pscp.NewValue);
                break;
            }

            case PBEPkmnSwitchInPacket psip:
            {
                foreach (PBEPkmnAppearedInfo info in psip.SwitchIns)
                {
                    PBEBattlePokemon pokemon = psip.Trainer.TryGetPokemon(info.Pokemon);
                    pokemon.FieldPosition = info.FieldPosition;
                    PBETrainer.SwitchTwoPokemon(pokemon, info.FieldPosition);
                    DoDisguisedAppearance(pokemon, info);
                    Battle.ActiveBattlers.Add(pokemon);
                }
                break;
            }

            case PBEPkmnSwitchOutPacket psop:
            {
                bool             ret     = base.ProcessPacket(packet); // Process before removal
                PBEBattlePokemon pokemon = psop.PokemonTrainer.TryGetPokemon(psop.Pokemon);
                Battle.ActiveBattlers.Remove(pokemon);
                pokemon.ClearForSwitch();
                return(ret);
            }

            case PBEPsychUpPacket pup:
            {
                PBEBattlePokemon user   = pup.UserTrainer.TryGetPokemon(pup.User);
                PBEBattlePokemon target = pup.TargetTrainer.TryGetPokemon(pup.Target);
                user.AttackChange    = target.AttackChange = pup.AttackChange;
                user.DefenseChange   = target.DefenseChange = pup.DefenseChange;
                user.SpAttackChange  = target.SpAttackChange = pup.SpAttackChange;
                user.SpDefenseChange = target.SpDefenseChange = pup.SpDefenseChange;
                user.SpeedChange     = target.SpeedChange = pup.SpeedChange;
                user.AccuracyChange  = target.AccuracyChange = pup.AccuracyChange;
                user.EvasionChange   = target.EvasionChange = pup.EvasionChange;
                break;
            }

            case PBEReflectTypePacket rtp:
            {
                PBEBattlePokemon user   = rtp.UserTrainer.TryGetPokemon(rtp.User);
                PBEBattlePokemon target = rtp.TargetTrainer.TryGetPokemon(rtp.Target);
                user.Type1 = user.KnownType1 = target.KnownType1 = target.Type1 = rtp.Type1;
                user.Type2 = user.KnownType2 = target.KnownType2 = target.Type2 = rtp.Type2;
                break;
            }

            case PBEStatus1Packet s1p:
            {
                PBEBattlePokemon status1Receiver = s1p.Status1ReceiverTrainer.TryGetPokemon(s1p.Status1Receiver);
                switch (s1p.StatusAction)
                {
                case PBEStatusAction.Added:
                case PBEStatusAction.Announced:
                case PBEStatusAction.CausedImmobility:
                case PBEStatusAction.Damage: status1Receiver.Status1 = s1p.Status1; break;

                case PBEStatusAction.Cleared:
                case PBEStatusAction.Ended: status1Receiver.Status1 = PBEStatus1.None; break;

                default: throw new ArgumentOutOfRangeException(nameof(s1p.StatusAction));
                }
                break;
            }

            case PBEStatus2Packet s2p:
            {
                PBEBattlePokemon status2Receiver = s2p.Status2ReceiverTrainer.TryGetPokemon(s2p.Status2Receiver);
                PBEBattlePokemon pokemon2        = s2p.Pokemon2Trainer.TryGetPokemon(s2p.Pokemon2);
                switch (s2p.StatusAction)
                {
                case PBEStatusAction.Added:
                case PBEStatusAction.Announced:
                case PBEStatusAction.CausedImmobility:
                case PBEStatusAction.Damage: status2Receiver.Status2 |= s2p.Status2; status2Receiver.KnownStatus2 |= s2p.Status2; break;

                case PBEStatusAction.Cleared:
                case PBEStatusAction.Ended: status2Receiver.Status2 &= ~s2p.Status2; status2Receiver.KnownStatus2 &= ~s2p.Status2; break;

                default: throw new ArgumentOutOfRangeException(nameof(s2p.StatusAction));
                }
                switch (s2p.Status2)
                {
                case PBEStatus2.Infatuated:
                {
                    switch (s2p.StatusAction)
                    {
                    case PBEStatusAction.Added: status2Receiver.InfatuatedWithPokemon = pokemon2; break;

                    case PBEStatusAction.Cleared:
                    case PBEStatusAction.Ended: status2Receiver.InfatuatedWithPokemon = null; break;
                    }
                    break;
                }

                case PBEStatus2.LeechSeed:
                {
                    switch (s2p.StatusAction)
                    {
                    case PBEStatusAction.Added: status2Receiver.SeededPosition = pokemon2.FieldPosition; status2Receiver.SeededTeam = pokemon2.Team; break;
                    }
                    break;
                }

                case PBEStatus2.LockOn:
                {
                    switch (s2p.StatusAction)
                    {
                    case PBEStatusAction.Added: status2Receiver.LockOnPokemon = pokemon2; break;

                    case PBEStatusAction.Ended: status2Receiver.LockOnPokemon = null; break;
                    }
                    break;
                }

                case PBEStatus2.PowerTrick:
                {
                    switch (s2p.StatusAction)
                    {
                    case PBEStatusAction.Added: status2Receiver.ApplyPowerTrickChange(); break;
                    }
                    break;
                }

                case PBEStatus2.Roost:
                {
                    switch (s2p.StatusAction)
                    {
                    case PBEStatusAction.Added: status2Receiver.StartRoost(); break;

                    case PBEStatusAction.Ended: status2Receiver.EndRoost(); break;
                    }
                    break;
                }

                case PBEStatus2.Transformed:
                    switch (s2p.StatusAction)
                    {
                    case PBEStatusAction.Added: status2Receiver.Transform(pokemon2); break;
                    }
                    break;
                }
                break;
            }

            case PBETeamStatusPacket tsp:
            {
                PBETeam team = tsp.Team;
                switch (tsp.TeamStatusAction)
                {
                case PBETeamStatusAction.Added:
                case PBETeamStatusAction.Damage: team.TeamStatus |= tsp.TeamStatus; break;

                case PBETeamStatusAction.Cleared:
                case PBETeamStatusAction.Ended: team.TeamStatus &= ~tsp.TeamStatus; break;

                default: throw new ArgumentOutOfRangeException(nameof(tsp.TeamStatusAction));
                }
                switch (tsp.TeamStatus)
                {
                case PBETeamStatus.Spikes:
                {
                    switch (tsp.TeamStatusAction)
                    {
                    case PBETeamStatusAction.Added: team.SpikeCount++; break;
                        //case PBETeamStatusAction.Cleared: team.SpikeCount = 0; break;
                    }
                    break;
                }

                case PBETeamStatus.ToxicSpikes:
                {
                    switch (tsp.TeamStatusAction)
                    {
                    case PBETeamStatusAction.Added: team.ToxicSpikeCount++; break;

                    case PBETeamStatusAction.Cleared: team.ToxicSpikeCount = 0; break;
                    }
                    break;
                }
                }
                break;
            }

            case PBETransformPacket tp:
            {
                PBEBattlePokemon target = tp.TargetTrainer.TryGetPokemon(tp.Target);
                target.Attack          = tp.TargetAttack;
                target.Defense         = tp.TargetDefense;
                target.SpAttack        = tp.TargetSpAttack;
                target.SpDefense       = tp.TargetSpDefense;
                target.Speed           = tp.TargetSpeed;
                target.AttackChange    = tp.TargetAttackChange;
                target.DefenseChange   = tp.TargetDefenseChange;
                target.SpAttackChange  = tp.TargetSpAttackChange;
                target.SpDefenseChange = tp.TargetSpDefenseChange;
                target.SpeedChange     = tp.TargetSpeedChange;
                target.AccuracyChange  = tp.TargetAccuracyChange;
                target.EvasionChange   = tp.TargetEvasionChange;
                target.Ability         = target.KnownAbility = tp.TargetAbility;
                for (int i = 0; i < Battle.Settings.NumMoves; i++)
                {
                    target.Moves[i].Move = tp.TargetMoves[i];
                }
                target.Species = target.KnownSpecies = tp.TargetSpecies;
                target.Form    = target.KnownForm = tp.TargetForm;
                target.Type1   = target.KnownType1 = tp.TargetType1;
                target.Type2   = target.KnownType2 = tp.TargetType2;
                target.Weight  = target.KnownWeight = tp.TargetWeight;
                return(true);
            }

            case PBETypeChangedPacket tcp:
            {
                PBEBattlePokemon pokemon = tcp.PokemonTrainer.TryGetPokemon(tcp.Pokemon);
                pokemon.Type1 = pokemon.KnownType1 = tcp.Type1;
                pokemon.Type2 = pokemon.KnownType2 = tcp.Type2;
                break;
            }

            case PBEWeatherPacket wp:
            {
                switch (wp.WeatherAction)
                {
                case PBEWeatherAction.Added:
                case PBEWeatherAction.CausedDamage: Battle.Weather = wp.Weather; break;

                case PBEWeatherAction.Ended: Battle.Weather = PBEWeather.None; break;

                default: throw new ArgumentOutOfRangeException(nameof(wp.WeatherAction));
                }
                break;
            }

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

            case IPBEAutoCenterPacket acp:
            {
                PBEBattlePokemon pokemon0 = acp.Pokemon0Trainer.TryGetPokemon(acp.Pokemon0OldPosition);
                PBEBattlePokemon pokemon1 = acp.Pokemon1Trainer.TryGetPokemon(acp.Pokemon1OldPosition);
                pokemon0.FieldPosition = PBEFieldPosition.Center;
                pokemon1.FieldPosition = PBEFieldPosition.Center;
                break;
            }

            case PBEBattleResultPacket brp:
            {
                Battle.BattleResult = brp.BattleResult;
                break;
            }

            case PBETurnBeganPacket tbp:
            {
                Battle.TurnNumber = tbp.TurnNumber;
                break;
            }
            }
            return(base.ProcessPacket(packet));
        }