private double CalculateSpDefense(PBEPokemon user, PBEPokemon target, double initialSpDefense)
        {
            double spDefense = initialSpDefense;

            if (target.Item == PBEItem.DeepSeaScale && target.OriginalSpecies == PBESpecies.Clamperl)
            {
                spDefense *= 2.0;
            }
            if (target.Item == PBEItem.SoulDew && (target.OriginalSpecies == PBESpecies.Latias || target.OriginalSpecies == PBESpecies.Latios))
            {
                spDefense *= 1.5;
            }
            if (target.Item == PBEItem.Eviolite && PBEPokemonData.GetData(target.OriginalSpecies).Evolutions.Count > 0)
            {
                spDefense *= 1.5;
            }
            if (ShouldDoWeatherEffects())
            {
                if (Weather == PBEWeather.Sandstorm && target.HasType(PBEType.Rock))
                {
                    spDefense *= 1.5;
                }
                if (!user.HasCancellingAbility() && Weather == PBEWeather.HarshSunlight && Array.Exists(target.Team.ActiveBattlers, p => p.Ability == PBEAbility.FlowerGift))
                {
                    spDefense *= 1.5;
                }
            }

            return(spDefense);
        }
Beispiel #2
0
        // Stats & PP are set from the shell info
        public PBEPokemon(PBETeam team, byte id, PBEPokemonShell shell)
        {
            Team = team;
            SelectedAction.PokemonId = Id = id;
            Shell          = shell;
            VisualGender   = Shell.Gender;
            VisualNickname = Shell.Nickname;
            VisualShiny    = Shell.Shiny;
            VisualSpecies  = Shell.Species;
            Ability        = Shell.Ability;
            Item           = Shell.Item;
            CalculateStats();
            HP           = MaxHP;
            HPPercentage = 1.0;
            Moves        = Shell.Moves;
            PP           = new byte[Moves.Length];
            MaxPP        = new byte[Moves.Length];
            for (int i = 0; i < Moves.Length; i++)
            {
                PBEMove move = Shell.Moves[i];
                if (move != PBEMove.None)
                {
                    byte tier = PBEMoveData.Data[move].PPTier;
                    PP[i] = MaxPP[i] = (byte)Math.Max(1, (tier * Team.Battle.Settings.PPMultiplier) + (tier * Shell.PPUps[i]));
                }
            }
            PBEPokemonData pData = PBEPokemonData.Data[Shell.Species];

            Type1  = pData.Type1;
            Type2  = pData.Type2;
            Weight = pData.Weight;
            Team.Party.Add(this);
        }
        internal PBEPokemon(PBETeam team, byte id, PBEPokemonShell shell)
        {
            Team    = team;
            Id      = id;
            Species = OriginalSpecies = KnownSpecies = shell.Species;
            var pData = PBEPokemonData.GetData(Species);

            KnownType1       = Type1 = pData.Type1;
            KnownType2       = Type2 = pData.Type2;
            KnownWeight      = Weight = pData.Weight;
            Nickname         = KnownNickname = shell.Nickname;
            Level            = shell.Level;
            Friendship       = shell.Friendship;
            Shiny            = KnownShiny = shell.Shiny;
            Ability          = OriginalAbility = shell.Ability;
            KnownAbility     = PBEAbility.MAX;
            Nature           = shell.Nature;
            Gender           = KnownGender = shell.Gender;
            Item             = OriginalItem = shell.Item;
            KnownItem        = (PBEItem)ushort.MaxValue;
            EffortValues     = new PBEEffortValues(shell.EffortValues);
            IndividualValues = new PBEIndividualValues(shell.IndividualValues);
            SetStats();
            HP                   = MaxHP;
            HPPercentage         = 1D;
            OriginalMoveset      = new PBEMoveset(shell.Moveset);
            Moves                = new PBEBattleMoveset(OriginalMoveset);
            KnownMoves           = new PBEBattleMoveset(Team.Battle.Settings);
            TransformBackupMoves = new PBEBattleMoveset(Team.Battle.Settings);
            team.Party.Add(this);
        }
Beispiel #4
0
        public static PBEGender NextGender(this Random rand, PBESpecies species)
        {
            PBEPokemonData pData = PBEPokemonData.Data[species];

            switch (pData.GenderRatio)
            {
            case PBEGenderRatio.M7_F1: return(rand.ApplyChance(875, 1000) ? PBEGender.Male : PBEGender.Female);

            case PBEGenderRatio.M3_F1: return(rand.ApplyChance(750, 1000) ? PBEGender.Male : PBEGender.Female);

            case PBEGenderRatio.M1_F1: return(rand.ApplyChance(500, 1000) ? PBEGender.Male : PBEGender.Female);

            case PBEGenderRatio.M1_F3: return(rand.ApplyChance(250, 1000) ? PBEGender.Male : PBEGender.Female);

            case PBEGenderRatio.M1_F7: return(rand.ApplyChance(125, 1000) ? PBEGender.Male : PBEGender.Female);

            case PBEGenderRatio.M0_F1: return(PBEGender.Female);

            case PBEGenderRatio.M0_F0: return(PBEGender.Genderless);

            case PBEGenderRatio.M1_F0: return(PBEGender.Male);

            default: throw new ArgumentOutOfRangeException(nameof(pData.GenderRatio));
            }
        }
        internal PBEPokemon(BinaryReader r, PBETeam team)
        {
            Team    = team;
            Id      = r.ReadByte();
            Species = OriginalSpecies = KnownSpecies = (PBESpecies)r.ReadUInt32();
            var pData = PBEPokemonData.GetData(Species);

            KnownType1       = Type1 = pData.Type1;
            KnownType2       = Type2 = pData.Type2;
            KnownWeight      = Weight = pData.Weight;
            Nickname         = KnownNickname = PBEUtils.StringFromBytes(r);
            Level            = r.ReadByte();
            Friendship       = r.ReadByte();
            Shiny            = KnownShiny = r.ReadBoolean();
            Ability          = OriginalAbility = (PBEAbility)r.ReadByte();
            KnownAbility     = PBEAbility.MAX;
            Nature           = (PBENature)r.ReadByte();
            Gender           = KnownGender = (PBEGender)r.ReadByte();
            Item             = OriginalItem = (PBEItem)r.ReadUInt16();
            KnownItem        = (PBEItem)ushort.MaxValue;
            EffortValues     = new PBEEffortValues(Team.Battle.Settings, r);
            IndividualValues = new PBEIndividualValues(Team.Battle.Settings, r);
            SetStats();
            HP                   = MaxHP;
            HPPercentage         = 1D;
            OriginalMoveset      = new PBEMoveset(Species, Level, Team.Battle.Settings, r);
            Moves                = new PBEBattleMoveset(OriginalMoveset);
            KnownMoves           = new PBEBattleMoveset(Team.Battle.Settings);
            TransformBackupMoves = new PBEBattleMoveset(Team.Battle.Settings);
            Team.Party.Add(this);
        }
Beispiel #6
0
        private static List <(PBESpecies, PBEForm)> GetSpecies(PBESpecies species, PBEForm form)
        {
            // Recursion BAYBEE
            // IDK what to name these functions so enjoy Add1 and Add2
            var list = new List <(PBESpecies, PBEForm)>();

            void Add1(PBESpecies s, PBEForm f)
            {
                // Do not take forms if unable to change into them (Wormadam)
                if (PBEDataUtils.CanChangeForm(s, true))
                {
                    foreach (PBEForm cf in PBEDataUtils.GetForms(s, true))
                    {
                        Add2(s, cf);
                    }
                }
                else
                {
                    Add2(s, f);
                }
            }

            void Add2(PBESpecies s, PBEForm f)
            {
                foreach ((PBESpecies cs, PBEForm cf) in PBEPokemonData.GetData(s, f).PreEvolutions)
                {
                    Add1(cs, cf);
                }
                list.Add((s, f));
            }

            Add1(species, form);
            return(list);
        }
        // This constructor is to define a remote Pokémon
        public PBEPokemon(PBETeam team, PBEPkmnSwitchInPacket.PBESwitchInInfo info)
        {
            if (team == null)
            {
                throw new ArgumentNullException(nameof(team));
            }
            if (info == null)
            {
                throw new ArgumentNullException(nameof(info));
            }
            Team                 = team;
            Id                   = info.PokemonId;
            FieldPosition        = info.FieldPosition;
            HP                   = info.HP;
            MaxHP                = info.MaxHP;
            HPPercentage         = info.HPPercentage;
            Status1              = info.Status1;
            Level                = info.Level;
            KnownAbility         = Ability = OriginalAbility = PBEAbility.MAX;
            KnownGender          = Gender = info.Gender;
            KnownItem            = Item = OriginalItem = (PBEItem)ushort.MaxValue;
            Moves                = new PBEBattleMoveset(Team.Battle.Settings);
            KnownMoves           = new PBEBattleMoveset(Team.Battle.Settings);
            TransformBackupMoves = new PBEBattleMoveset(Team.Battle.Settings);
            KnownNickname        = Nickname = info.Nickname;
            KnownShiny           = Shiny = info.Shiny;
            KnownSpecies         = Species = OriginalSpecies = info.Species;
            var pData = PBEPokemonData.GetData(KnownSpecies);

            KnownType1  = Type1 = pData.Type1;
            KnownType2  = Type2 = pData.Type2;
            KnownWeight = Weight = pData.Weight;
            Team.Party.Add(this);
        }
        // This constructor is to define a remote Pokémon
        public PBEPokemon(PBETeam team, PBEPkmnSwitchInPacket.PBESwitchInInfo info)
        {
            Team          = team;
            Id            = info.PokemonId;
            FieldPosition = info.FieldPosition;
            HP            = info.HP;
            MaxHP         = info.MaxHP;
            HPPercentage  = info.HPPercentage;
            Status1       = info.Status1;
            Level         = info.Level;
            KnownAbility  = Ability = OriginalAbility = PBEAbility.MAX;
            KnownGender   = Gender = info.Gender;
            KnownItem     = Item = (PBEItem)ushort.MaxValue;
            Moves         = new PBEMove[Team.Battle.Settings.NumMoves];
            KnownMoves    = new PBEMove[Team.Battle.Settings.NumMoves];
            for (int i = 0; i < Team.Battle.Settings.NumMoves; i++)
            {
                KnownMoves[i] = Moves[i] = PBEMove.MAX;
            }
            PP            = new byte[Team.Battle.Settings.NumMoves];
            MaxPP         = new byte[Team.Battle.Settings.NumMoves];
            KnownNickname = Nickname = info.Nickname;
            KnownShiny    = Shiny = info.Shiny;
            KnownSpecies  = Species = OriginalSpecies = info.Species;
            var pData = PBEPokemonData.GetData(KnownSpecies);

            KnownType1  = Type1 = pData.Type1;
            KnownType2  = Type2 = pData.Type2;
            KnownWeight = Weight = pData.Weight;
            Team.Party.Add(this);
        }
            public async Task Info([Remainder] string speciesName)
            {
                PBESpecies?nSpecies = PBELocalizedString.GetSpeciesByName(speciesName);

                if (!nSpecies.HasValue)
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} Invalid species!");
                }
                else
                {
                    PBESpecies species = nSpecies.Value;
                    var        pData   = PBEPokemonData.GetData(species);
                    string     types   = pData.Type1.ToString();
                    if (pData.Type2 != PBEType.None)
                    {
                        types += ", " + pData.Type2.ToString();
                    }
                    string ratio;
                    switch (pData.GenderRatio)
                    {
                    case PBEGenderRatio.M7_F1: ratio = "87.5% Male, 12.5% Female"; break;

                    case PBEGenderRatio.M3_F1: ratio = "75% Male, 25% Female"; break;

                    case PBEGenderRatio.M1_F1: ratio = "50% Male, 50% Female"; break;

                    case PBEGenderRatio.M1_F3: ratio = "25% Male, 75% Female"; break;

                    case PBEGenderRatio.M0_F1: ratio = "100% Female"; break;

                    case PBEGenderRatio.M1_F0: ratio = "100% Male"; break;

                    case PBEGenderRatio.M0_F0: ratio = "Genderless Species"; break;

                    default: throw new ArgumentOutOfRangeException(nameof(pData.GenderRatio));
                    }

                    EmbedBuilder embed = new EmbedBuilder()
                                         .WithAuthor(Context.User)
                                         .WithColor(Utils.GetColor(pData.Type1, pData.Type2))
                                         .WithTitle($"{PBELocalizedString.GetSpeciesName(species).English} - {PBELocalizedString.GetSpeciesCategory(species).English}")
                                         .WithUrl(Utils.URL)
                                         .WithDescription(PBELocalizedString.GetSpeciesEntry(species).English.Replace('\n', ' '))
                                         .AddField("Types", types, true)
                                         .AddField("Gender Ratio", ratio, true)
                                         .AddField("Weight", $"{pData.Weight:N1} kg", true)
                                         .AddField("Abilities", string.Join(", ", pData.Abilities.Select(a => PBELocalizedString.GetAbilityName(a).English)), false)
                                         .AddField("HP", pData.BaseStats[0], true)
                                         .AddField("Attack", pData.BaseStats[1], true)
                                         .AddField("Defense", pData.BaseStats[2], true)
                                         .AddField("Special Attack", pData.BaseStats[3], true)
                                         .AddField("Special Defense", pData.BaseStats[4], true)
                                         .AddField("Speed", pData.BaseStats[5], true)
                                         .WithImageUrl(Utils.GetPokemonSprite(species, PBEUtils.RandomShiny(), PBEUtils.RandomGender(pData.GenderRatio), false, false));
                    await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());
                }
            }
 public void SetStats()
 {
     MaxHP     = PBEPokemonData.CalculateStat(PBEStat.HP, Species, Nature, EffortValues[PBEStat.HP].Value, IndividualValues[PBEStat.HP].Value, Level, Team.Battle.Settings);
     Attack    = PBEPokemonData.CalculateStat(PBEStat.Attack, Species, Nature, EffortValues[PBEStat.Attack].Value, IndividualValues[PBEStat.Attack].Value, Level, Team.Battle.Settings);
     Defense   = PBEPokemonData.CalculateStat(PBEStat.Defense, Species, Nature, EffortValues[PBEStat.Defense].Value, IndividualValues[PBEStat.Defense].Value, Level, Team.Battle.Settings);
     SpAttack  = PBEPokemonData.CalculateStat(PBEStat.SpAttack, Species, Nature, EffortValues[PBEStat.SpAttack].Value, IndividualValues[PBEStat.SpAttack].Value, Level, Team.Battle.Settings);
     SpDefense = PBEPokemonData.CalculateStat(PBEStat.SpDefense, Species, Nature, EffortValues[PBEStat.SpDefense].Value, IndividualValues[PBEStat.SpDefense].Value, Level, Team.Battle.Settings);
     Speed     = PBEPokemonData.CalculateStat(PBEStat.Speed, Species, Nature, EffortValues[PBEStat.Speed].Value, IndividualValues[PBEStat.Speed].Value, Level, Team.Battle.Settings);
 }
 public TestPokemon(PBESettings settings, PBESpecies species, PBEForm form, byte level, params PBEMove[] moves)
 {
     Species          = species;
     Form             = form;
     Level            = level;
     Nickname         = species.ToString();
     Gender           = PBERandom.RandomGender(PBEPokemonData.GetData(species, form).GenderRatio);
     EffortValues     = new PBEStatCollection(0, 0, 0, 0, 0, 0);
     IndividualValues = new PBEStatCollection(0, 0, 0, 0, 0, 0);
     Moveset          = new TestMoveset(settings, moves);
 }
        // Stats & PP are set from the shell info
        internal PBEPokemon(PBETeam team, byte id, PBEPokemonShell shell)
        {
            Team = team;
            SelectedAction.PokemonId = Id = id;
            Shell        = shell;
            Ability      = OriginalAbility = Shell.Ability;
            KnownAbility = PBEAbility.MAX;
            Gender       = KnownGender = Shell.Gender;
            Item         = Shell.Item;
            KnownItem    = (PBEItem)ushort.MaxValue;
            Moves        = Shell.Moveset.MoveSlots.Select(m => m.Move).ToArray();
            KnownMoves   = new PBEMove[Team.Battle.Settings.NumMoves];
            for (int i = 0; i < Team.Battle.Settings.NumMoves; i++)
            {
                KnownMoves[i] = PBEMove.MAX;
            }
            Nickname = KnownNickname = Shell.Nickname;
            Shiny    = KnownShiny = Shell.Shiny;
            Species  = OriginalSpecies = KnownSpecies = Shell.Species;
            var pData = PBEPokemonData.GetData(Species);

            KnownType1       = Type1 = pData.Type1;
            KnownType2       = Type2 = pData.Type2;
            KnownWeight      = Weight = pData.Weight;
            EffortValues     = new PBEEffortValueCollection(team.Battle.Settings, shell.EffortValues);
            IndividualValues = new PBEIndividualValueCollection(team.Battle.Settings, shell.IndividualValues);
            Friendship       = Shell.Friendship;
            Level            = Shell.Level;
            Nature           = Shell.Nature;
            SetStats();
            HP           = MaxHP;
            HPPercentage = 1.0;
            PP           = new byte[team.Battle.Settings.NumMoves];
            MaxPP        = new byte[team.Battle.Settings.NumMoves];
            for (int i = 0; i < team.Battle.Settings.NumMoves; i++)
            {
                PBEMove move = Moves[i];
                if (move != PBEMove.None)
                {
                    byte tier = PBEMoveData.Data[move].PPTier;
                    PP[i] = MaxPP[i] = (byte)Math.Max(1, (tier * team.Battle.Settings.PPMultiplier) + (tier * Shell.Moveset.MoveSlots[i].PPUps));
                }
            }
            team.Party.Add(this);
        }
        private double CalculateDefense(PBEPokemon user, PBEPokemon target, double initialDefense)
        {
            double defense = initialDefense;

            if (target.Item == PBEItem.MetalPowder && target.OriginalSpecies == PBESpecies.Ditto && !target.Status2.HasFlag(PBEStatus2.Transformed))
            {
                defense *= 2.0;
            }
            if (target.Ability == PBEAbility.MarvelScale && target.Status1 != PBEStatus1.None && !user.HasCancellingAbility())
            {
                defense *= 1.5;
            }
            if (target.Item == PBEItem.Eviolite && PBEPokemonData.GetData(target.OriginalSpecies).Evolutions.Count > 0)
            {
                defense *= 1.5;
            }

            return(defense);
        }
Beispiel #14
0
        // This constructor is to define a remote Pokémon
        public PBEPokemon(PBETeam team, PBEPkmnSwitchInPacket.PBESwitchInInfo info)
        {
            Team  = team;
            Id    = info.PokemonId;
            Shell = new PBEPokemonShell
            {
                Species  = VisualSpecies = info.Species,
                Shiny    = VisualShiny = info.Shiny,
                Nickname = VisualNickname = info.Nickname,
                Level    = info.Level,
                Gender   = VisualGender = info.Gender,
                Ability  = Ability = PBEAbility.MAX,
                Item     = Item = (PBEItem)ushort.MaxValue,
                Nature   = PBENature.MAX,
                Moves    = new PBEMove[Team.Battle.Settings.NumMoves],
                PPUps    = new byte[Team.Battle.Settings.NumMoves],
                EVs      = new byte[6],
                IVs      = new byte[6]
            };
            Moves = new PBEMove[Shell.Moves.Length];
            PP    = new byte[Moves.Length];
            MaxPP = new byte[Moves.Length];
            for (int i = 0; i < Moves.Length; i++)
            {
                Shell.Moves[i] = Moves[i] = PBEMove.MAX;
            }
            FieldPosition = info.FieldPosition;
            HP            = info.HP;
            MaxHP         = info.MaxHP;
            HPPercentage  = info.HPPercentage;
            Status1       = info.Status1;
            PBEPokemonData pData = PBEPokemonData.Data[Shell.Species];

            Type1  = pData.Type1;
            Type2  = pData.Type2;
            Weight = pData.Weight;
            Team.Party.Add(this);
        }
Beispiel #15
0
        /// <summary>
        /// Calculates and sets the Pokémon's stats based on its level, IVs, EVs, nature, and species.
        /// </summary>
        void CalculateStats()
        {
            PBEPokemonData pData = PBEPokemonData.Data[Shell.Species];

            MaxHP = (ushort)(Shell.Species == PBESpecies.Shedinja ? 1 : (((2 * pData.HP + Shell.IVs[0] + (Shell.EVs[0] / 4)) * Shell.Level / Team.Battle.Settings.MaxLevel) + Shell.Level + 10));

            int i = 0;

            ushort OtherStat(byte baseVal)
            {
                double natureMultiplier = 1.0 + (PBEPokemonData.NatureBoosts[Shell.Nature][i] * Team.Battle.Settings.NatureStatBoost);
                ushort val = (ushort)((((2 * baseVal + Shell.IVs[i + 1] + (Shell.EVs[i + 1] / 4)) * Shell.Level / Team.Battle.Settings.MaxLevel) + 5) * natureMultiplier);

                i++;
                return(val);
            }

            Attack    = OtherStat(pData.Attack);
            Defense   = OtherStat(pData.Defense);
            SpAttack  = OtherStat(pData.SpAttack);
            SpDefense = OtherStat(pData.SpDefense);
            Speed     = OtherStat(pData.Speed);
        }
        private static PartyPokemon GetTest(PBESpecies species, PBEForm form, byte level)
        {
            var pData = PBEPokemonData.GetData(species, form);
            var p     = new PartyPokemon
            {
                Status1          = PBEStatus1.Paralyzed,
                Moveset          = new Moveset(),
                Species          = species,
                Form             = form,
                Nickname         = PBELocalizedString.GetSpeciesName(species).English,
                Shiny            = PBEUtils.GlobalRandom.RandomShiny(),
                Level            = level,
                Item             = PBEUtils.GlobalRandom.RandomElement(PBEDataUtils.GetValidItems(species, form)),
                Ability          = PBEUtils.GlobalRandom.RandomElement(pData.Abilities),
                Gender           = PBEUtils.GlobalRandom.RandomGender(pData.GenderRatio),
                Nature           = PBEUtils.GlobalRandom.RandomElement(PBEDataUtils.AllNatures),
                EffortValues     = new EVs(),
                IndividualValues = new IVs()
            };

            p.SetMaxHP(pData);
            p.RandomizeMoves();
            return(p);
        }
Beispiel #17
0
        public static IReadOnlyCollection <PBEMove> GetLegalMoves(PBESpecies species, PBEForm form, byte level, PBESettings settings)
        {
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }
            if (!settings.IsReadOnly)
            {
                throw new ArgumentException("Settings must be read-only.", nameof(settings));
            }
            ValidateSpecies(species, form, true);
            ValidateLevel(level, settings);
            List <(PBESpecies, PBEForm)> speciesToStealFrom = GetSpecies(species, form);

            var moves = new List <PBEMove>();

            foreach ((PBESpecies spe, PBEForm fo) in speciesToStealFrom)
            {
                var pData = PBEPokemonData.GetData(spe, fo);
                // Disallow moves learned after the current level
                moves.AddRange(pData.LevelUpMoves.Where(t => t.Level <= level).Select(t => t.Move));
                // Disallow form-specific moves from other forms (Rotom)
                moves.AddRange(pData.OtherMoves.Where(t => (spe == species && fo == form) || t.ObtainMethod != PBEMoveObtainMethod.Form).Select(t => t.Move));
                // Event Pokémon checking is extremely basic and wrong, but the goal is not to be super restricting or accurate
                if (PBEEventPokemon.Events.TryGetValue(spe, out ReadOnlyCollection <PBEEventPokemon> events))
                {
                    // Disallow moves learned after the current level
                    moves.AddRange(events.Where(e => e.Level <= level).SelectMany(e => e.Moves).Where(m => m != PBEMove.None));
                }
                if (moves.Any(m => PBEMoveData.Data[m].Effect == PBEMoveEffect.Sketch))
                {
                    return(PBEDataUtils.SketchLegalMoves);
                }
            }
            return(moves.Distinct().Where(m => PBEMoveData.IsMoveUsable(m)).ToArray());
        }
Beispiel #18
0
            public async Task Info([Remainder] string speciesName)
            {
                PBESpecies         species   = 0;
                PBELocalizedString localized = PBEPokemonLocalization.Names.Values.FirstOrDefault(l => l.Contains(speciesName));

                if (localized != null)
                {
                    species = PBEPokemonLocalization.Names.First(p => p.Value == localized).Key;
                }
                else
                {
                    Enum.TryParse(speciesName, true, out species);
                }
                if (species != 0)
                {
                    PBEPokemonData pData = PBEPokemonData.Data[species];
                    string         types = pData.Type1.ToString();
                    if (pData.Type2 != PBEType.None)
                    {
                        types += ", " + pData.Type2.ToString();
                    }
                    string ratio;
                    switch (pData.GenderRatio)
                    {
                    case PBEGenderRatio.M7_F1: ratio = "87.5% Male, 12.5% Female"; break;

                    case PBEGenderRatio.M3_F1: ratio = "75% Male, 25% Female"; break;

                    case PBEGenderRatio.M1_F1: ratio = "50% Male, 50% Female"; break;

                    case PBEGenderRatio.M1_F3: ratio = "25% Male, 75% Female"; break;

                    case PBEGenderRatio.M1_F7: ratio = "12.5% Male, 87.5% Female"; break;

                    case PBEGenderRatio.M0_F1: ratio = "100% Female"; break;

                    case PBEGenderRatio.M1_F0: ratio = "100% Male"; break;

                    case PBEGenderRatio.M0_F0: ratio = "Genderless Species"; break;

                    default: throw new ArgumentOutOfRangeException(nameof(pData.GenderRatio));
                    }

                    var embed = new EmbedBuilder()
                                .WithColor(Utils.GetColor(species))
                                .WithUrl("https://github.com/Kermalis/PokemonBattleEngine")
                                .WithTitle(PBEPokemonLocalization.Names[species].English)
                                .WithAuthor(Context.User)
                                .WithImageUrl(Utils.GetPokemonSprite(species, PBEUtils.RNG.NextShiny(), PBEUtils.RNG.NextGender(species), false, false))
                                .AddField("Types", types, true)
                                .AddField("Gender Ratio", ratio, true)
                                .AddField("Weight", $"{pData.Weight:N1} kg", true)
                                .AddField("Abilities", string.Join(", ", pData.Abilities.Select(a => PBEAbilityLocalization.Names[a].English)), false)
                                .AddField("HP", pData.HP, true)
                                .AddField("Attack", pData.Attack, true)
                                .AddField("Defense", pData.Defense, true)
                                .AddField("Special Attack", pData.SpAttack, true)
                                .AddField("Special Defense", pData.SpDefense, true)
                                .AddField("Speed", pData.Speed, true);
                    await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());

                    return;
                }
                await Context.Channel.SendMessageAsync($"{Context.User.Mention} Invalid species!");
            }
Beispiel #19
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 PBEHazePacket _:
            {
                foreach (PBEBattlePokemon pkmn in Battle.ActiveBattlers)
                {
                    pkmn.ClearStatChanges();
                }
                break;
            }

            case PBEIllusionPacket ilp:
            {
                PBEBattlePokemon pokemon = ilp.PokemonTrainer.TryGetPokemon(ilp.Pokemon);
                pokemon.DisguisedAsPokemon = null;
                pokemon.Ability            = pokemon.KnownAbility = PBEAbility.Illusion;
                pokemon.Gender             = pokemon.KnownGender = ilp.ActualGender;
                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.ChangedStatus:
                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.FieldPosition = PBEFieldPosition.None;
                return(ret);
            }

            case PBEPkmnFaintedPacket_Hidden pfph:
            {
                bool             ret     = base.ProcessPacket(packet); // Process before removal
                PBEBattlePokemon pokemon = pfph.PokemonTrainer.TryGetPokemon(pfph.OldPosition);
                Battle.ActiveBattlers.Remove(pokemon);
                pokemon.FieldPosition = PBEFieldPosition.None;
                PBETrainer.Remove(pokemon);
                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 PBEPkmnFormChangedPacket_Hidden pfcph:
            {
                PBEBattlePokemon pokemon = pfcph.PokemonTrainer.TryGetPokemon(pfcph.Pokemon);
                pokemon.KnownAbility = pfcph.NewKnownAbility;
                pokemon.KnownForm    = pfcph.NewForm;
                pokemon.KnownType1   = pfcph.NewType1;
                pokemon.KnownType2   = pfcph.NewType2;
                pokemon.KnownWeight  = pfcph.NewWeight;
                break;
            }

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

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

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

            case PBEPkmnSwitchInPacket psip:
            {
                foreach (PBEPkmnSwitchInPacket.PBESwitchInInfo info in psip.SwitchIns)
                {
                    PBEBattlePokemon pokemon            = psip.Trainer.TryGetPokemon(info.Pokemon);
                    PBEBattlePokemon disguisedAsPokemon = psip.Trainer.TryGetPokemon(info.DisguisedAsPokemon);
                    pokemon.FieldPosition = info.FieldPosition;
                    PBETrainer.SwitchTwoPokemon(pokemon, info.FieldPosition);
                    if (disguisedAsPokemon != pokemon)
                    {
                        pokemon.Status2           |= PBEStatus2.Disguised;
                        pokemon.DisguisedAsPokemon = disguisedAsPokemon;
                        pokemon.KnownGender        = pokemon.DisguisedAsPokemon.Gender;
                        pokemon.KnownNickname      = pokemon.DisguisedAsPokemon.Nickname;
                        pokemon.KnownShiny         = pokemon.DisguisedAsPokemon.Shiny;
                        pokemon.KnownSpecies       = pokemon.DisguisedAsPokemon.OriginalSpecies;
                        pokemon.KnownForm          = pokemon.DisguisedAsPokemon.Form;
                        var pData = PBEPokemonData.GetData(pokemon.KnownSpecies, pokemon.KnownForm);
                        pokemon.KnownType1 = pData.Type1;
                        pokemon.KnownType2 = pData.Type2;
                    }
                    Battle.ActiveBattlers.Add(pokemon);
                }
                break;
            }

            case PBEPkmnSwitchInPacket_Hidden psiph:
            {
                foreach (PBEPkmnSwitchInPacket_Hidden.PBESwitchInInfo info in psiph.SwitchIns)
                {
                    new PBEBattlePokemon(psiph.Trainer, info);
                }
                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 PBEPkmnSwitchOutPacket_Hidden psoph:
            {
                bool             ret     = base.ProcessPacket(packet); // Process before removal
                PBEBattlePokemon pokemon = psoph.PokemonTrainer.TryGetPokemon(psoph.OldPosition);
                Battle.ActiveBattlers.Remove(pokemon);
                PBETrainer.Remove(pokemon);
                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 PBEReflectTypePacket_Hidden rtph:
            {
                PBEBattlePokemon user   = rtph.UserTrainer.TryGetPokemon(rtph.User);
                PBEBattlePokemon target = rtph.TargetTrainer.TryGetPokemon(rtph.Target);
                user.Type1 = user.KnownType1 = target.KnownType1;     // Set Type1 and Type2 so Transform works
                user.Type2 = user.KnownType2 = target.KnownType2;
                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 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 PBETurnBeganPacket tbp:
            {
                Battle.TurnNumber = tbp.TurnNumber;
                break;
            }

            case PBEWinnerPacket win:
            {
                Battle.Winner = win.WinningTeam;
                break;
            }
            }
            return(base.ProcessPacket(packet));
        }
        /// <summary>Sets and clears all information required for switching out.</summary>
        public void ClearForSwitch()
        {
            FieldPosition = PBEFieldPosition.None;
            switch (Ability)
            {
            case PBEAbility.NaturalCure:
            {
                Status1        = PBEStatus1.None;
                Status1Counter = SleepTurns = 0;
                break;
            }

            case PBEAbility.Regenerator:
            {
                HP           = PBEUtils.Clamp((ushort)(HP + (MaxHP / 3)), ushort.MinValue, MaxHP);
                HPPercentage = (double)HP / MaxHP;
                break;
            }
            }
            PBEPokemonData pData;

            if (Shaymin_CannotChangeBackToSkyForm)
            {
                pData   = PBEPokemonData.GetData(Species = KnownSpecies = PBESpecies.Shaymin);
                Ability = pData.Abilities[0];
            }
            else
            {
                pData   = PBEPokemonData.GetData(Species = KnownSpecies = OriginalSpecies);
                Ability = OriginalAbility;
            }
            KnownAbility = PBEAbility.MAX;
            KnownGender  = Gender;
            KnownItem    = (PBEItem)ushort.MaxValue;
            KnownMoves.SetUnknown();
            KnownNickname = Nickname;
            KnownShiny    = Shiny;
            KnownType1    = Type1 = pData.Type1;
            KnownType2    = Type2 = pData.Type2;

            AttackChange = DefenseChange = SpAttackChange = SpDefenseChange = SpeedChange = AccuracyChange = EvasionChange = 0;

            if (Status1 == PBEStatus1.Asleep)
            {
                Status1Counter = 0;
            }
            else if (Status1 == PBEStatus1.BadlyPoisoned)
            {
                Status1Counter = 1;
            }

            ConfusionCounter   = ConfusionTurns = 0;
            DisguisedAsPokemon = null;
            SeededPosition     = PBEFieldPosition.None;
            SeededTeam         = null;
            SubstituteHP       = 0;
            if (Id != byte.MaxValue && Status2.HasFlag(PBEStatus2.Transformed))
            {
                Moves.Reset(TransformBackupMoves);
                TransformBackupMoves.SetUnknown();
            }
            Status2 = PBEStatus2.None;

            TempLockedMove    = ChoiceLockedMove = PBEMove.None;
            TempLockedTargets = PBETurnTarget.None;

            ExecutedMoves.Clear();

            SpeedBoost_AbleToSpeedBoostThisTurn = false;

            if (Id != byte.MaxValue)
            {
                SetStats();
            }
        }
            public async Task Info([Remainder] string input)
            {
                // Inputs for forms should be like "Giratina (Origin Forme)"
                Match  m = Regex.Match(input, @"^(\S+) \((.+)\)$");
                string speciesName;
                string formName;

                if (m.Success)
                {
                    speciesName = m.Groups[1].Value;
                    formName    = m.Groups[2].Value;
                }
                else
                {
                    speciesName = input;
                    formName    = null;
                }
                PBESpecies?nSpecies = PBELocalizedString.GetSpeciesByName(speciesName);

                if (!nSpecies.HasValue)
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} ― Invalid species!");
                }
                else
                {
                    PBESpecies species = nSpecies.Value;
                    speciesName = PBELocalizedString.GetSpeciesName(species).English;
                    PBEForm?nForm = formName == null ? 0 : PBELocalizedString.GetFormByName(species, formName);
                    if (!nForm.HasValue)
                    {
                        await Context.Channel.SendMessageAsync($"{Context.User.Mention} ― Invalid form for {speciesName}!");
                    }
                    else
                    {
                        PBEForm form = nForm.Value;
                        formName = PBEDataUtils.HasForms(species, false) ? $" ({PBELocalizedString.GetFormName(species, form).English})" : string.Empty;
                        var    pData = PBEPokemonData.GetData(species, form);
                        string types = $"{Utils.TypeEmotes[pData.Type1]}";
                        if (pData.Type2 != PBEType.None)
                        {
                            types += $" {Utils.TypeEmotes[pData.Type2]}";
                        }
                        string ratio;
                        switch (pData.GenderRatio)
                        {
                        case PBEGenderRatio.M7_F1: ratio = "87.5% Male, 12.5% Female"; break;

                        case PBEGenderRatio.M3_F1: ratio = "75% Male, 25% Female"; break;

                        case PBEGenderRatio.M1_F1: ratio = "50% Male, 50% Female"; break;

                        case PBEGenderRatio.M1_F3: ratio = "25% Male, 75% Female"; break;

                        case PBEGenderRatio.M0_F1: ratio = "100% Female"; break;

                        case PBEGenderRatio.M1_F0: ratio = "100% Male"; break;

                        case PBEGenderRatio.M0_F0: ratio = "Genderless Species"; break;

                        default: throw new ArgumentOutOfRangeException(nameof(pData.GenderRatio));
                        }
                        string weaknesses  = string.Empty,
                               resistances = string.Empty,
                               immunities  = string.Empty;
                        for (PBEType atk = PBEType.None + 1; atk < PBEType.MAX; atk++)
                        {
                            double d = PBETypeEffectiveness.GetEffectiveness(atk, pData);
                            if (d <= 0)
                            {
                                if (immunities != string.Empty)
                                {
                                    immunities += ' ';
                                }
                                immunities += Utils.TypeEmotes[atk];
                            }
                            else if (d < 1)
                            {
                                if (resistances != string.Empty)
                                {
                                    resistances += ' ';
                                }
                                resistances += Utils.TypeEmotes[atk];
                            }
                            if (d > 1)
                            {
                                if (weaknesses != string.Empty)
                                {
                                    weaknesses += ' ';
                                }
                                weaknesses += Utils.TypeEmotes[atk];
                            }
                        }
                        if (weaknesses == string.Empty)
                        {
                            weaknesses = "No Weaknesses";
                        }
                        if (resistances == string.Empty)
                        {
                            resistances = "No Resistances";
                        }
                        if (immunities == string.Empty)
                        {
                            immunities = "No Immunities";
                        }

                        EmbedBuilder embed = new EmbedBuilder()
                                             .WithAuthor(Context.User)
                                             .WithColor(Utils.GetColor(pData.Type1, pData.Type2))
                                             .WithTitle($"{speciesName}{formName} ― {PBELocalizedString.GetSpeciesCategory(species).English}")
                                             .WithUrl(Utils.URL)
                                             .WithDescription(PBELocalizedString.GetSpeciesEntry(species).English.Replace('\n', ' '))
                                             .AddField("Types", types, true)
                                             .AddField("Gender Ratio", ratio, true)
                                             .AddField("Weight", $"{pData.Weight:N1} kg", true)
                                             .AddField("Abilities", string.Join(", ", pData.Abilities.Select(a => PBELocalizedString.GetAbilityName(a).English)), false)
                                             .AddField("HP", pData.BaseStats.HP, true)
                                             .AddField("Attack", pData.BaseStats.Attack, true)
                                             .AddField("Defense", pData.BaseStats.Defense, true)
                                             .AddField("Special Attack", pData.BaseStats.SpAttack, true)
                                             .AddField("Special Defense", pData.BaseStats.SpDefense, true)
                                             .AddField("Speed", pData.BaseStats.Speed, true)
                                             .AddField("Type Weaknesses", weaknesses, true)
                                             .AddField("Type Resistances", resistances, true)
                                             .AddField("Type Immunities", immunities, true)
                                             .WithImageUrl(Utils.GetPokemonSprite(species, form, PBERandom.RandomShiny(), PBERandom.RandomGender(pData.GenderRatio), false, false));
                        await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());
                    }
                }
            }
Beispiel #22
0
        public static string CustomPokemonToString(PBEPokemon pkmn, bool showRawValues0, bool showRawValues1)
        {
            var sb = new StringBuilder();

            void AddStatChanges()
            {
                PBEStat[] statChanges = pkmn.GetChangedStats();
                if (statChanges.Length > 0)
                {
                    var statStrs = new List <string>(7);
                    if (Array.IndexOf(statChanges, PBEStat.Attack) != -1)
                    {
                        statStrs.Add($"[A] x{PBEBattle.GetStatChangeModifier(pkmn.AttackChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Defense) != -1)
                    {
                        statStrs.Add($"[D] x{PBEBattle.GetStatChangeModifier(pkmn.DefenseChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.SpAttack) != -1)
                    {
                        statStrs.Add($"[SA] x{PBEBattle.GetStatChangeModifier(pkmn.SpAttackChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.SpDefense) != -1)
                    {
                        statStrs.Add($"[SD] x{PBEBattle.GetStatChangeModifier(pkmn.SpDefenseChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Speed) != -1)
                    {
                        statStrs.Add($"[S] x{PBEBattle.GetStatChangeModifier(pkmn.SpeedChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Accuracy) != -1)
                    {
                        statStrs.Add($"[AC] x{PBEBattle.GetStatChangeModifier(pkmn.AccuracyChange, true):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Evasion) != -1)
                    {
                        statStrs.Add($"[E] x{PBEBattle.GetStatChangeModifier(pkmn.EvasionChange, true):0.00}");
                    }
                    sb.AppendLine($"Stat changes: {string.Join(", ", statStrs)}");
                }
            }

            if ((pkmn.Team.Id == 0 && !showRawValues0) || (pkmn.Team.Id == 1 && !showRawValues1))
            {
                sb.AppendLine($"{pkmn.KnownNickname}/{pkmn.KnownSpecies} {(pkmn.Status2.HasFlag(PBEStatus2.Transformed) ? pkmn.GenderSymbol : pkmn.KnownGenderSymbol)} Lv.{pkmn.Level}");
                sb.AppendLine($"HP: {pkmn.HPPercentage:P2}");
                sb.Append($"Known types: {PBELocalizedString.GetTypeName(pkmn.KnownType1).ToString()}");
                if (pkmn.KnownType2 != PBEType.None)
                {
                    sb.Append($"/{PBELocalizedString.GetTypeName(pkmn.KnownType2).ToString()}");
                }
                sb.AppendLine();
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    sb.AppendLine($"Position: {pkmn.Team.TrainerName}'s {pkmn.FieldPosition}");
                }
                if (pkmn.Status1 != PBEStatus1.None)
                {
                    sb.AppendLine($"Main status: {pkmn.Status1}");
                }
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    PBEStatus2 cleanStatus2 = pkmn.Status2;
                    cleanStatus2 &= ~PBEStatus2.Disguised;
                    if (cleanStatus2 != PBEStatus2.None)
                    {
                        sb.AppendLine($"Volatile status: {cleanStatus2}");
                        if (cleanStatus2.HasFlag(PBEStatus2.Infatuated))
                        {
                            sb.AppendLine($"Infatuated with: {((pkmn.InfatuatedWithPokemon.Team.Id == 0 && showRawValues0) || (pkmn.InfatuatedWithPokemon.Team.Id == 1 && showRawValues1) ? pkmn.InfatuatedWithPokemon.Nickname : pkmn.InfatuatedWithPokemon.KnownNickname)}");
                        }
                        if (cleanStatus2.HasFlag(PBEStatus2.LeechSeed))
                        {
                            sb.AppendLine($"Seeded position: {pkmn.SeededTeam.TrainerName}'s {pkmn.SeededPosition}");
                        }
                    }
                }
                PBEPokemonData.GetStatRange(PBEStat.HP, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowHP, out ushort highHP);
                PBEPokemonData.GetStatRange(PBEStat.Attack, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowAttack, out ushort highAttack);
                PBEPokemonData.GetStatRange(PBEStat.Defense, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowDefense, out ushort highDefense);
                PBEPokemonData.GetStatRange(PBEStat.SpAttack, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowSpAttack, out ushort highSpAttack);
                PBEPokemonData.GetStatRange(PBEStat.SpDefense, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowSpDefense, out ushort highSpDefense);
                PBEPokemonData.GetStatRange(PBEStat.Speed, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowSpeed, out ushort highSpeed);
                sb.AppendLine($"Stat range: [HP] {lowHP}-{highHP}, [A] {lowAttack}-{highAttack}, [D] {lowDefense}-{highDefense}, [SA] {lowSpAttack}-{highSpAttack}, [SD] {lowSpDefense}-{highSpDefense}, [S] {lowSpeed}-{highSpeed}, [W] {pkmn.KnownWeight:0.0}");
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    AddStatChanges();
                }
                if (pkmn.KnownAbility == PBEAbility.MAX)
                {
                    sb.AppendLine($"Possible abilities: {string.Join(", ", PBEPokemonData.GetData(pkmn.KnownSpecies).Abilities.Select(a => PBELocalizedString.GetAbilityName(a).ToString()))}");
                }
                else
                {
                    sb.AppendLine($"Known ability: {PBELocalizedString.GetAbilityName(pkmn.KnownAbility).ToString()}");
                }
                sb.AppendLine($"Known item: {(pkmn.KnownItem == (PBEItem)ushort.MaxValue ? "???" : PBELocalizedString.GetItemName(pkmn.KnownItem).ToString())}");
                sb.Append("Known moves: ");
                for (int i = 0; i < pkmn.Team.Battle.Settings.NumMoves; i++)
                {
                    PBEBattleMoveset.PBEBattleMovesetSlot slot = pkmn.KnownMoves[i];
                    PBEMove move  = slot.Move;
                    int     pp    = slot.PP;
                    int     maxPP = slot.MaxPP;
                    if (i > 0)
                    {
                        sb.Append(", ");
                    }
                    sb.Append(move == PBEMove.MAX ? "???" : PBELocalizedString.GetMoveName(move).ToString());
                    if (move != PBEMove.None && move != PBEMove.MAX)
                    {
                        sb.Append($" ({pp}{(maxPP == 0 ? ")" : $"/{maxPP})")}");
                    }
                }
            }
 private void SetMaxHP(PBEPokemonData pData)
 {
     HP = PBEDataUtils.CalculateStat(pData, PBEStat.HP, Nature, EffortValues.HP, IndividualValues.HP, Level, PBESettings.DefaultSettings);
 }
        public void SetMaxHP()
        {
            var pData = PBEPokemonData.GetData(Species, Form);

            SetMaxHP(pData);
        }
Beispiel #25
0
        public static Color GetColor(PBESpecies species)
        {
            PBEPokemonData pData = PBEPokemonData.Data[species];

            return(GetColor(pData.Type1, pData.Type2));
        }
Beispiel #26
0
        public static string CustomPokemonToString(PBEBattlePokemon pkmn, bool useKnownInfo)
        {
            var sb = new StringBuilder();

            string GetTeamNickname(PBEBattlePokemon p)
            {
                return($"{p.Trainer.Name}'s {(useKnownInfo ? p.KnownNickname : p.Nickname)}");
            }

            void AddStatChanges()
            {
                PBEStat[] statChanges = pkmn.GetChangedStats();
                if (statChanges.Length > 0)
                {
                    var statStrs = new List <string>(7);
                    if (Array.IndexOf(statChanges, PBEStat.Attack) != -1)
                    {
                        statStrs.Add($"[A] x{PBEBattle.GetStatChangeModifier(pkmn.AttackChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Defense) != -1)
                    {
                        statStrs.Add($"[D] x{PBEBattle.GetStatChangeModifier(pkmn.DefenseChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.SpAttack) != -1)
                    {
                        statStrs.Add($"[SA] x{PBEBattle.GetStatChangeModifier(pkmn.SpAttackChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.SpDefense) != -1)
                    {
                        statStrs.Add($"[SD] x{PBEBattle.GetStatChangeModifier(pkmn.SpDefenseChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Speed) != -1)
                    {
                        statStrs.Add($"[S] x{PBEBattle.GetStatChangeModifier(pkmn.SpeedChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Accuracy) != -1)
                    {
                        statStrs.Add($"[AC] x{PBEBattle.GetStatChangeModifier(pkmn.AccuracyChange, true):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Evasion) != -1)
                    {
                        statStrs.Add($"[E] x{PBEBattle.GetStatChangeModifier(pkmn.EvasionChange, true):0.00}");
                    }
                    sb.AppendLine($"Stat changes: {string.Join(", ", statStrs)}");
                }
            }

            void AddStatus1()
            {
                if (pkmn.Status1 != PBEStatus1.None)
                {
                    sb.AppendLine($"Main status: {pkmn.Status1}");
                    if (pkmn.Status1 == PBEStatus1.Asleep)
                    {
                        sb.AppendLine($"Asleep turns: {pkmn.Status1Counter}");
                    }
                    else if (pkmn.Status1 == PBEStatus1.BadlyPoisoned)
                    {
                        sb.AppendLine($"Toxic counter: {pkmn.Status1Counter}");
                    }
                }
            }

            void AddStatus2(PBEStatus2 status2)
            {
                status2 &= ~PBEStatus2.Flinching; // Don't show flinching
                sb.AppendLine($"Volatile status: {status2}");
                if (status2.HasFlag(PBEStatus2.Disguised))
                {
                    sb.AppendLine($"Disguised as: {pkmn.DisguisedAsPokemon.Nickname}");
                }
                if (pkmn.Battle.BattleFormat != PBEBattleFormat.Single)
                {
                    if (status2.HasFlag(PBEStatus2.Infatuated))
                    {
                        sb.AppendLine($"Infatuated with: {GetTeamNickname(pkmn.InfatuatedWithPokemon)}");
                    }
                    if (status2.HasFlag(PBEStatus2.LeechSeed))
                    {
                        sb.AppendLine($"Seeded position: {pkmn.SeededTeam.CombinedName}'s {pkmn.SeededPosition}");
                    }
                    if (status2.HasFlag(PBEStatus2.LockOn))
                    {
                        sb.AppendLine($"Taking aim at: {GetTeamNickname(pkmn.LockOnPokemon)}");
                    }
                }
            }

            if (useKnownInfo)
            {
                var    pData   = PBEPokemonData.GetData(pkmn.KnownSpecies, pkmn.KnownForm);
                string formStr = PBEDataUtils.HasForms(pkmn.KnownSpecies, false) ? $" ({PBELocalizedString.GetFormName(pkmn.KnownSpecies, pkmn.KnownForm)})" : string.Empty;
                sb.AppendLine($"{pkmn.KnownNickname}/{pkmn.KnownSpecies}{formStr} {(pkmn.KnownStatus2.HasFlag(PBEStatus2.Transformed) ? pkmn.Gender.ToSymbol() : pkmn.KnownGender.ToSymbol())} Lv.{pkmn.Level}");
                sb.AppendLine($"HP: {pkmn.HPPercentage:P2}");
                sb.Append($"Known types: {PBELocalizedString.GetTypeName(pkmn.KnownType1)}");
                if (pkmn.KnownType2 != PBEType.None)
                {
                    sb.Append($"/{PBELocalizedString.GetTypeName(pkmn.KnownType2)}");
                }
                sb.AppendLine();
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    sb.AppendLine($"Position: {pkmn.Team.CombinedName}'s {pkmn.FieldPosition}");
                }
                AddStatus1();
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    if (pkmn.KnownStatus2 != PBEStatus2.None)
                    {
                        AddStatus2(pkmn.KnownStatus2);
                    }
                }
                PBEDataUtils.GetStatRange(pData, PBEStat.HP, pkmn.Level, pkmn.Battle.Settings, out ushort lowHP, out ushort highHP);
                PBEDataUtils.GetStatRange(pData, PBEStat.Attack, pkmn.Level, pkmn.Battle.Settings, out ushort lowAttack, out ushort highAttack);
                PBEDataUtils.GetStatRange(pData, PBEStat.Defense, pkmn.Level, pkmn.Battle.Settings, out ushort lowDefense, out ushort highDefense);
                PBEDataUtils.GetStatRange(pData, PBEStat.SpAttack, pkmn.Level, pkmn.Battle.Settings, out ushort lowSpAttack, out ushort highSpAttack);
                PBEDataUtils.GetStatRange(pData, PBEStat.SpDefense, pkmn.Level, pkmn.Battle.Settings, out ushort lowSpDefense, out ushort highSpDefense);
                PBEDataUtils.GetStatRange(pData, PBEStat.Speed, pkmn.Level, pkmn.Battle.Settings, out ushort lowSpeed, out ushort highSpeed);
                sb.AppendLine($"Stat range: [HP] {lowHP}-{highHP}, [A] {lowAttack}-{highAttack}, [D] {lowDefense}-{highDefense}, [SA] {lowSpAttack}-{highSpAttack}, [SD] {lowSpDefense}-{highSpDefense}, [S] {lowSpeed}-{highSpeed}, [W] {pkmn.KnownWeight:0.0}");
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    AddStatChanges();
                }
                if (pkmn.KnownAbility == PBEAbility.MAX)
                {
                    sb.AppendLine($"Possible abilities: {string.Join(", ", pData.Abilities.Select(a => PBELocalizedString.GetAbilityName(a).ToString()))}");
                }
                else
                {
                    sb.AppendLine($"Known ability: {PBELocalizedString.GetAbilityName(pkmn.KnownAbility)}");
                }
                sb.AppendLine($"Known item: {(pkmn.KnownItem == (PBEItem)ushort.MaxValue ? "???" : PBELocalizedString.GetItemName(pkmn.KnownItem).ToString())}");
                sb.Append("Known moves: ");
                for (int i = 0; i < pkmn.Battle.Settings.NumMoves; i++)
                {
                    PBEBattleMoveset.PBEBattleMovesetSlot slot = pkmn.KnownMoves[i];
                    PBEMove move  = slot.Move;
                    int     pp    = slot.PP;
                    int     maxPP = slot.MaxPP;
                    if (i > 0)
                    {
                        sb.Append(", ");
                    }
                    sb.Append(move == PBEMove.MAX ? "???" : PBELocalizedString.GetMoveName(move).ToString());
                    if (move != PBEMove.None && move != PBEMove.MAX)
                    {
                        sb.Append($" ({pp}{(maxPP == 0 ? ")" : $"/{maxPP})")}");
                    }
                }
            }
        public static string CustomPokemonToString(PBEPokemon pkmn, bool showRawValues0, bool showRawValues1)
        {
            var sb = new StringBuilder();

            void AddStatChanges()
            {
                PBEStat[] statChanges = pkmn.GetChangedStats();
                if (statChanges.Length > 0)
                {
                    var statStrs = new List <string>(7);
                    if (Array.IndexOf(statChanges, PBEStat.Attack) != -1)
                    {
                        statStrs.Add($"[A] x{PBEBattle.GetStatChangeModifier(pkmn.AttackChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Defense) != -1)
                    {
                        statStrs.Add($"[D] x{PBEBattle.GetStatChangeModifier(pkmn.DefenseChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.SpAttack) != -1)
                    {
                        statStrs.Add($"[SA] x{PBEBattle.GetStatChangeModifier(pkmn.SpAttackChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.SpDefense) != -1)
                    {
                        statStrs.Add($"[SD] x{PBEBattle.GetStatChangeModifier(pkmn.SpDefenseChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Speed) != -1)
                    {
                        statStrs.Add($"[S] x{PBEBattle.GetStatChangeModifier(pkmn.SpeedChange, false):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Accuracy) != -1)
                    {
                        statStrs.Add($"[AC] x{PBEBattle.GetStatChangeModifier(pkmn.AccuracyChange, true):0.00}");
                    }
                    if (Array.IndexOf(statChanges, PBEStat.Evasion) != -1)
                    {
                        statStrs.Add($"[E] x{PBEBattle.GetStatChangeModifier(pkmn.EvasionChange, true):0.00}");
                    }
                    sb.AppendLine($"Stat changes: {string.Join(", ", statStrs)}");
                }
            }

            if ((pkmn.Team.Id == 0 && !showRawValues0) || (pkmn.Team.Id == 1 && !showRawValues1))
            {
                sb.AppendLine($"{pkmn.KnownNickname}/{pkmn.KnownSpecies} {(pkmn.Status2.HasFlag(PBEStatus2.Transformed) ? pkmn.GenderSymbol : pkmn.KnownGenderSymbol)} Lv.{pkmn.Level}");
                sb.AppendLine($"HP: {pkmn.HPPercentage:P2}");
                sb.AppendLine($"Known types: {PBELocalizedString.GetTypeName(pkmn.KnownType1).FromUICultureInfo()}/{PBELocalizedString.GetTypeName(pkmn.KnownType2).FromUICultureInfo()}");
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    sb.AppendLine($"Position: {pkmn.Team.TrainerName}'s {pkmn.FieldPosition}");
                }
                if (pkmn.Status1 != PBEStatus1.None)
                {
                    sb.AppendLine($"Main status: {pkmn.Status1}");
                }
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    PBEStatus2 cleanStatus2 = pkmn.Status2;
                    cleanStatus2 &= ~PBEStatus2.Disguised;
                    if (cleanStatus2 != PBEStatus2.None)
                    {
                        sb.AppendLine($"Volatile status: {cleanStatus2}");
                        if (cleanStatus2.HasFlag(PBEStatus2.Infatuated))
                        {
                            sb.AppendLine($"Infatuated with: {((pkmn.InfatuatedWithPokemon.Team.Id == 0 && showRawValues0) || (pkmn.InfatuatedWithPokemon.Team.Id == 1 && showRawValues1) ? pkmn.InfatuatedWithPokemon.Nickname : pkmn.InfatuatedWithPokemon.KnownNickname)}");
                        }
                        if (cleanStatus2.HasFlag(PBEStatus2.LeechSeed))
                        {
                            sb.AppendLine($"Seeded position: {pkmn.SeededTeam.TrainerName}'s {pkmn.SeededPosition}");
                        }
                    }
                }
                PBEPokemonData.GetStatRange(PBEStat.HP, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowHP, out ushort highHP);
                PBEPokemonData.GetStatRange(PBEStat.Attack, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowAttack, out ushort highAttack);
                PBEPokemonData.GetStatRange(PBEStat.Defense, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowDefense, out ushort highDefense);
                PBEPokemonData.GetStatRange(PBEStat.SpAttack, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowSpAttack, out ushort highSpAttack);
                PBEPokemonData.GetStatRange(PBEStat.SpDefense, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowSpDefense, out ushort highSpDefense);
                PBEPokemonData.GetStatRange(PBEStat.Speed, pkmn.KnownSpecies, pkmn.Level, pkmn.Team.Battle.Settings, out ushort lowSpeed, out ushort highSpeed);
                sb.AppendLine($"Stat range: [HP] {lowHP}-{highHP}, [A] {lowAttack}-{highAttack}, [D] {lowDefense}-{highDefense}, [SA] {lowSpAttack}-{highSpAttack}, [SD] {lowSpDefense}-{highSpDefense}, [S] {lowSpeed}-{highSpeed}, [W] {pkmn.KnownWeight:0.0}");
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    AddStatChanges();
                }
                if (pkmn.KnownAbility == PBEAbility.MAX)
                {
                    sb.AppendLine($"Possible abilities: {string.Join(", ", PBEPokemonData.GetData(pkmn.KnownSpecies).Abilities.Select(a => PBELocalizedString.GetAbilityName(a).FromUICultureInfo()))}");
                }
                else
                {
                    sb.AppendLine($"Known ability: {PBELocalizedString.GetAbilityName(pkmn.KnownAbility).FromUICultureInfo()}");
                }
                sb.AppendLine($"Known item: {(pkmn.KnownItem == (PBEItem)ushort.MaxValue ? "???" : PBELocalizedString.GetItemName(pkmn.KnownItem).FromUICultureInfo())}");
                sb.Append($"Known moves: {string.Join(", ", pkmn.KnownMoves.Select(m => m == PBEMove.MAX ? "???" : PBELocalizedString.GetMoveName(m).FromUICultureInfo()))}");
            }
            else
            {
                sb.AppendLine($"{pkmn.Nickname}/{pkmn.Species} {pkmn.GenderSymbol} Lv.{pkmn.Level}");
                sb.AppendLine($"HP: {pkmn.HP}/{pkmn.MaxHP} ({pkmn.HPPercentage:P2})");
                sb.AppendLine($"Types: {PBELocalizedString.GetTypeName(pkmn.Type1).FromUICultureInfo()}/{PBELocalizedString.GetTypeName(pkmn.Type2).FromUICultureInfo()}");
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    sb.AppendLine($"Position: {pkmn.Team.TrainerName}'s {pkmn.FieldPosition}");
                }
                if (pkmn.Status1 != PBEStatus1.None)
                {
                    sb.AppendLine($"Main status: {pkmn.Status1}");
                }
                if (pkmn.FieldPosition != PBEFieldPosition.None && pkmn.Status2 != PBEStatus2.None)
                {
                    sb.AppendLine($"Volatile status: {pkmn.Status2}");
                    if (pkmn.Status2.HasFlag(PBEStatus2.Disguised))
                    {
                        sb.AppendLine($"Disguised as: {pkmn.DisguisedAsPokemon.Nickname}");
                    }
                    if (pkmn.Status2.HasFlag(PBEStatus2.Infatuated))
                    {
                        sb.AppendLine($"Infatuated with: {((pkmn.InfatuatedWithPokemon.Team.Id == 0 && showRawValues0) || (pkmn.InfatuatedWithPokemon.Team.Id == 1 && showRawValues1) ? pkmn.InfatuatedWithPokemon.Nickname : pkmn.InfatuatedWithPokemon.KnownNickname)}");
                    }
                    if (pkmn.Status2.HasFlag(PBEStatus2.LeechSeed))
                    {
                        sb.AppendLine($"Seeded position: {pkmn.SeededTeam.TrainerName}'s {pkmn.SeededPosition}");
                    }
                }
                sb.AppendLine($"Stats: [A] {pkmn.Attack}, [D] {pkmn.Defense}, [SA] {pkmn.SpAttack}, [SD] {pkmn.SpDefense}, [S] {pkmn.Speed}, [W] {pkmn.Weight:0.0}");
                if (pkmn.FieldPosition != PBEFieldPosition.None)
                {
                    AddStatChanges();
                }
                sb.AppendLine($"Ability: {PBELocalizedString.GetAbilityName(pkmn.Ability).FromUICultureInfo()}");
                sb.AppendLine($"Item: {PBELocalizedString.GetItemName(pkmn.Item).FromUICultureInfo()}");
                if (Array.IndexOf(pkmn.Moves, PBEMove.Frustration) != -1 || Array.IndexOf(pkmn.Moves, PBEMove.Return) != -1)
                {
                    sb.AppendLine($"Friendship: {pkmn.Friendship} ({pkmn.Friendship / (double)byte.MaxValue:P2})");
                }
                if (Array.IndexOf(pkmn.Moves, PBEMove.HiddenPower) != -1)
                {
                    sb.AppendLine($"{PBELocalizedString.GetMoveName(PBEMove.HiddenPower).FromUICultureInfo()}: {PBELocalizedString.GetTypeName(pkmn.IndividualValues.HiddenPowerType).FromUICultureInfo()}/{pkmn.IndividualValues.HiddenPowerBasePower}");
                }
                string[] moveStrs = new string[pkmn.Moves.Length];
                for (int i = 0; i < moveStrs.Length; i++)
                {
                    moveStrs[i] = $"{PBELocalizedString.GetMoveName(pkmn.Moves[i]).FromUICultureInfo()} {pkmn.PP[i]}/{pkmn.MaxPP[i]}";
                }
                sb.AppendLine($"Moves: {string.Join(", ", moveStrs)}");
                sb.Append($"Usable moves: {string.Join(", ", pkmn.GetUsableMoves().Select(m => PBELocalizedString.GetMoveName(m).FromUICultureInfo()))}");
            }
            return(sb.ToString());
        }