private void CheckForLearnMoves()
 {
     if (_learningMoves.Count != 0)
     {
         int index = _pkmn.Moveset.GetFirstEmptySlot();
         if (index == -1)
         {
             SetWantsToLearnMove();
         }
         else
         {
             Moveset.MovesetSlot slot = _pkmn.Moveset[index];
             PBEMove             move = _learningMoves.Dequeue(); // Remove from queue
             string moveStr           = PBELocalizedString.GetMoveName(move).English;
             slot.Move = move;
             PBEMoveData mData = PBEMoveData.Data[move];
             slot.PP    = PBEDataUtils.CalcMaxPP(mData.PPTier, 0, PkmnConstants.PBESettings);
             slot.PPUps = 0;
             CreateMessage(string.Format("{0} learned {1}!", _pkmn.Nickname, moveStr));
             _state = State.LearnMove_ForgotMsg;
         }
     }
     else
     {
         SetFadeOut();
     }
 }
Beispiel #2
0
        private static void InitDBCurrentCulture(string databasePath)
        {
            InitDB(databasePath);
            var cultureInfo = CultureInfo.ReadOnly(CultureInfo.CurrentUICulture);

            PBECulture = PBELocalizedString.IsCultureValid(cultureInfo) ? cultureInfo : CultureInfo.GetCultureInfo("en-US");
        }
Beispiel #3
0
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is null)
            {
                return(AvaloniaProperty.UnsetValue);
            }
            PBELocalizedString localized = null;

            switch (value)
            {
            case PBEAbility ability: localized = PBELocalizedString.GetAbilityName(ability); break;

            case PBEGender gender: localized = PBELocalizedString.GetGenderName(gender); break;

            case PBEItem item: localized = PBELocalizedString.GetItemName(item); break;

            case PBELocalizedString l: localized = l; break;

            case PBEMove move: localized = PBELocalizedString.GetMoveName(move); break;

            case PBENature nature: localized = PBELocalizedString.GetNatureName(nature); break;

            case PBESpecies species: localized = PBELocalizedString.GetSpeciesName(species); break;

            case PBEStat stat: localized = PBELocalizedString.GetStatName(stat); break;

            case PBEType type: localized = PBELocalizedString.GetTypeName(type); break;
            }
            return(StringRenderer.Render(localized == null ? value.ToString() : localized.ToString(), parameter?.ToString()) ?? AvaloniaProperty.UnsetValue);
        }
            public async Task Info([Remainder] string itemName)
            {
                PBEItem?nItem = PBELocalizedString.GetItemByName(itemName);

                if (!nItem.HasValue || nItem.Value == PBEItem.None)
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} Invalid item!");
                }
                else
                {
                    PBEItem      item  = nItem.Value;
                    PBEItemData  iData = PBEItemData.Data[item];
                    EmbedBuilder embed = new EmbedBuilder()
                                         .WithAuthor(Context.User)
                                         .WithColor(iData.NaturalGiftType == PBEType.None ? Utils.RandomColor() : Utils.TypeToColor[iData.NaturalGiftType])
                                         .WithTitle(PBELocalizedString.GetItemName(item).English)
                                         .WithUrl(Utils.URL)
                                         .WithDescription(PBELocalizedString.GetItemDescription(item).English.Replace('\n', ' '));
                    if (iData.FlingPower > 0)
                    {
                        embed.AddField("Fling Power", iData.FlingPower, true);
                    }
                    if (iData.NaturalGiftPower > 0)
                    {
                        embed.AddField("Natural Gift Power", iData.NaturalGiftPower, true);
                    }
                    if (iData.NaturalGiftType != PBEType.None)
                    {
                        embed.AddField("Natural Gift Type", iData.NaturalGiftType, true);
                    }
                    await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());
                }
            }
Beispiel #5
0
        // Temp - start a test wild battle
        public void TempCreateWildBattle(Map map, Map.Layout.Block block, EncounterTable.Encounter encounter)
        {
            Save sav      = Save;
            var  me       = new PBETrainerInfo(sav.PlayerParty, sav.PlayerName);
            var  wildPkmn = PartyPokemon.GetTestWildPokemon(encounter);
            var  wild     = new PBETrainerInfo(new Party {
                wildPkmn
            }, "Wild " + PBELocalizedString.GetSpeciesName(wildPkmn.Species).English);

            void OnBattleEnded()
            {
                void FadeFromTransitionEnded()
                {
                    _fadeFromTransition = null;
                }

                _fadeFromTransition = new FadeFromColorTransition(20, 0, FadeFromTransitionEnded);
                _battleGUI          = null;
            }

            _battleGUI = new BattleGUI(new PBEBattle(PBEBattleFormat.Single, PBESettings.DefaultSettings, me, wild,
                                                     battleTerrain: Overworld.GetPBEBattleTerrainFromBlock(block.BlocksetBlock),
                                                     weather: Overworld.GetPBEWeatherFromMap(map)),
                                       OnBattleEnded);
            void OnBattleTransitionEnded()
            {
                _battleTransition = null;
            }

            _battleTransition = new SpiralTransition(OnBattleTransitionEnded);
        }
            public async Task Info([Remainder] string itemName)
            {
                PBEItem?nItem = PBELocalizedString.GetItemByName(itemName);

                if (!nItem.HasValue || nItem.Value == PBEItem.None)
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} ― Invalid item!");
                }
                else
                {
                    PBEItem     item  = nItem.Value;
                    PBEItemData iData = PBEItemData.Data[item];
                    Color       color;
                    if (PBEBerryData.Data.TryGetValue(item, out PBEBerryData bData))
                    {
                        color = Utils.TypeColors[bData.NaturalGiftType];
                    }
                    else
                    {
                        color = Utils.RandomColor();
                    }
                    EmbedBuilder embed = new EmbedBuilder()
                                         .WithAuthor(Context.User)
                                         .WithColor(color)
                                         .WithTitle(PBELocalizedString.GetItemName(item).English)
                                         .WithUrl(Utils.URL)
                                         .WithDescription(PBELocalizedString.GetItemDescription(item).English.Replace('\n', ' '));
                    if (iData.FlingPower > 0)
                    {
                        embed.AddField("Fling Power", iData.FlingPower, true);
                    }
                    if (bData != null)
                    {
                        embed.AddField("Natural Gift Power", bData.NaturalGiftPower, true);
                        embed.AddField("Natural Gift Type", Utils.TypeEmotes[bData.NaturalGiftType], true);
                        if (bData.Bitterness > 0)
                        {
                            embed.AddField("Bitterness", bData.Bitterness, true);
                        }
                        if (bData.Dryness > 0)
                        {
                            embed.AddField("Dryness", bData.Dryness, true);
                        }
                        if (bData.Sourness > 0)
                        {
                            embed.AddField("Sourness", bData.Sourness, true);
                        }
                        if (bData.Spicyness > 0)
                        {
                            embed.AddField("Spicyness", bData.Spicyness, true);
                        }
                        if (bData.Sweetness > 0)
                        {
                            embed.AddField("Sweetness", bData.Sweetness, true);
                        }
                    }
                    await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());
                }
            }
        private void SetWantsToLearnMove()
        {
            PBEMove move = _learningMoves.Peek();
            string  str  = PBELocalizedString.GetMoveName(move).English;

            CreateMessage(string.Format("{0} wants to learn {1},\nbut {0} already knows {2} moves.\fForget a move and learn {1}?", _pkmn.Nickname, str, PkmnConstants.NumMoves));
            _state = State.LearnMove_WantsToLearnMoveMsg;
        }
        private void SetGiveUpLearningMove()
        {
            PBEMove move = _learningMoves.Peek();
            string  str  = PBELocalizedString.GetMoveName(move).English;

            CreateMessage(string.Format("Give up on learning {0}?", str));
            _state = State.LearnMove_GiveUpLearningMsg;
        }
            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());
                }
            }
Beispiel #10
0
        // temporary
        public static string GetItemName(ItemType item)
        {
            var pbe = (PBEItem)item;

            if (!Enum.IsDefined(typeof(PBEItem), pbe))
            {
                return(item.ToString());
            }
            return(PBELocalizedString.GetItemName(pbe).English);
        }
            public async Task Info([Remainder] string typeName)
            {
                PBEType?nType = PBELocalizedString.GetTypeByName(typeName);

                if (!nType.HasValue || nType.Value == PBEType.None)
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} ― Invalid type!");
                }
                else
                {
                    PBEType type        = nType.Value;
                    string  description = $"{_tableStart}{_tableStart}";
                    // Build columns
                    for (PBEType other = PBEType.None + 1; other < PBEType.MAX; other++)
                    {
                        description += $"|{Utils.TypeEmotes[other]}";
                    }
                    // Build rows
                    for (int i = 0; i < 2; i++)
                    {
                        bool doOffense = i == 0;
                        description += $"\n{(doOffense ? _offense : _defense)}{Utils.TypeEmotes[type]}";
                        for (PBEType other = PBEType.None + 1; other < PBEType.MAX; other++)
                        {
                            double d = PBETypeEffectiveness.GetEffectiveness(doOffense ? type : other, doOffense ? other : type);
                            string s;
                            if (d <= 0) // (-infinity, 0]
                            {
                                s = _ineffective;
                            }
                            else if (d < 1) // (0, 1)
                            {
                                s = _notVeryEffective;
                            }
                            else if (d == 1) // [1, 1]
                            {
                                s = _effective;
                            }
                            else // (1, infinity)
                            {
                                s = _superEffective;
                            }
                            description += $"|{s}";
                        }
                    }

                    EmbedBuilder embed = new EmbedBuilder()
                                         .WithAuthor(Context.User)
                                         .WithColor(Utils.TypeColors[type])
                                         .WithTitle(PBELocalizedString.GetTypeName(type).English)
                                         .WithUrl(Utils.URL)
                                         .WithDescription(description);
                    await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());
                }
            }
Beispiel #12
0
        public object Convert(IList <object> values, Type targetType, object parameter, CultureInfo culture)
        {
            var species = (PBESpecies)values[0];

            if (!PBEDataUtils.HasForms(species, true))
            {
                return(AvaloniaProperty.UnsetValue);
            }
            PBEForm form      = true ? 0 : (PBEForm)values[1]; // TODO
            var     localized = PBELocalizedString.GetFormName(species, form);

            return(StringRenderer.Render(localized.ToString(), parameter?.ToString()));
        }
Beispiel #13
0
 private static void InitDBCulture(string databasePath, CultureInfo cultureInfo)
 {
     InitDB(databasePath);
     if (cultureInfo == null)
     {
         throw new ArgumentNullException(nameof(cultureInfo));
     }
     cultureInfo = CultureInfo.ReadOnly(cultureInfo);
     if (!PBELocalizedString.IsCultureValid(cultureInfo))
     {
         throw new ArgumentOutOfRangeException(nameof(cultureInfo));
     }
     PBECulture = cultureInfo;
 }
Beispiel #14
0
        private void AddFieldMovesToActions(PartyPokemon pkmn, int index)
        {
            void Add(PBEMove move, Action command)
            {
                string str = PBELocalizedString.GetMoveName(move).English;

                _textChoices.Add(new TextGUIChoice(str, command, fontColors: Font.DefaultBlue_I));
            }

            Moveset moves = pkmn.Moveset;

            if (moves.Contains(PBEMove.Surf))
            {
                Add(PBEMove.Surf, () => Action_FieldSurf(index));
            }
        }
Beispiel #15
0
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            PBELocalizedString localized = null;

            switch (value)
            {
            case PBEAbility ability: localized = PBEAbilityLocalization.Names[ability]; break;

            case PBEItem item: localized = PBEItemLocalization.Names[item]; break;

            case PBEMove move: localized = PBEMoveLocalization.Names[move]; break;

            case PBESpecies species: localized = PBEPokemonLocalization.Names[species]; break;
            }
            Enum.TryParse(parameter?.ToString(), out Utils.StringRenderStyle style);
            return(Utils.RenderString(localized == null ? value?.ToString() : localized.FromUICultureInfo(), style));
        }
Beispiel #16
0
        private void FightChoice()
        {
            PBEBattlePokemon pkmn = _pkmn.Pkmn;
            // Check if there's a move we must use
            bool auto = false;

            if (pkmn.IsForcedToStruggle())
            {
                pkmn.TurnAction = new PBETurnAction(pkmn, PBEMove.Struggle, PBEBattleUtils.GetPossibleTargets(pkmn, pkmn.GetMoveTargets(PBEMove.Struggle))[0]);
                auto            = true;
            }
            else if (pkmn.TempLockedMove != PBEMove.None)
            {
                pkmn.TurnAction = new PBETurnAction(pkmn, pkmn.TempLockedMove, pkmn.TempLockedTargets);
                auto            = true;
            }
            if (auto)
            {
                _parent.ActionsLoop(false);
                return;
            }

            // Create move choices if it's not already created
            if (_moveChoices is null)
            {
                PBEBattleMoveset moves       = pkmn.Moves;
                PBEMove[]        usableMoves = pkmn.GetUsableMoves();
                _moveChoices = new GUIChoices(0.8f, 0.7f, 0.06f, backCommand: () => _isShowingMoves = false,
                                              font: Font.Default, fontColors: Font.DefaultWhite, selectedColors: Font.DefaultSelected, disabledColors: Font.DefaultDisabled);
                for (int i = 0; i < PBESettings.DefaultNumMoves; i++)
                {
                    PBEBattleMoveset.PBEBattleMovesetSlot slot = moves[i];
                    PBEMove m       = slot.Move;
                    string  text    = PBELocalizedString.GetMoveName(m).English;
                    bool    enabled = Array.IndexOf(usableMoves, m) != -1;
                    Action  command = enabled ? () => SelectMoveForTurn(m) : (Action)null;
                    _moveChoices.Add(new GUIChoice(text, command, isEnabled: enabled));
                }
            }

            // Show moves
            _isShowingMoves = true;
        }
Beispiel #17
0
            public async Task Info([Remainder] string moveName)
            {
                PBEMove            move      = 0;
                PBELocalizedString localized = PBEMoveLocalization.Names.Values.FirstOrDefault(l => l.Contains(moveName));

                if (localized != null)
                {
                    move = PBEMoveLocalization.Names.First(p => p.Value == localized).Key;
                }
                else
                {
                    Enum.TryParse(moveName, true, out move);
                }
                if (move != 0)
                {
                    if (move == PBEMove.None)
                    {
                        goto invalid;
                    }
                    PBEMoveData mData = PBEMoveData.Data[move];
                    var         embed = new EmbedBuilder()
                                        .WithColor(Utils.TypeToColor[mData.Type])
                                        .WithUrl("https://github.com/Kermalis/PokemonBattleEngine")
                                        .WithTitle(PBEMoveLocalization.Names[move].English)
                                        .WithAuthor(Context.User)
                                        .AddField("Type", mData.Type, true)
                                        .AddField("Category", mData.Category, true)
                                        .AddField("Priority", mData.Priority, true)
                                        .AddField("PP", mData.PPTier * PBESettings.DefaultSettings.PPMultiplier, true)
                                        .AddField("Power", mData.Power == 0 ? "--" : mData.Power.ToString(), true)
                                        .AddField("Accuracy", mData.Accuracy == 0 ? "--" : mData.Accuracy.ToString(), true)
                                        .AddField("Effect", mData.Effect, true)
                                        .AddField("Effect Param", mData.EffectParam, true)
                                        .AddField("Targets", mData.Targets, true)
                                        .AddField("Flags", mData.Flags, true);
                    await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());

                    return;
                }
invalid:
                await Context.Channel.SendMessageAsync($"{Context.User.Mention} Invalid move!");
            }
            public async Task Info([Remainder] string moveName)
            {
                PBEMove?nMove = PBELocalizedString.GetMoveByName(moveName);

                if (!nMove.HasValue || nMove.Value == PBEMove.None)
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} ― Invalid move!");
                }
                else
                {
                    PBEMove move = nMove.Value;
                    moveName = PBELocalizedString.GetMoveName(move).English;
                    PBEMoveData  mData = PBEMoveData.Data[move];
                    EmbedBuilder embed = new EmbedBuilder()
                                         .WithAuthor(Context.User)
                                         .WithColor(Utils.TypeColors[mData.Type])
                                         .WithTitle(moveName)
                                         .WithUrl(Utils.URL)
                                         .WithDescription(PBELocalizedString.GetMoveDescription(move).English.Replace('\n', ' '))
                                         .AddField("Type", Utils.TypeEmotes[mData.Type], true)
                                         .AddField("Category", mData.Category, true)
                                         .AddField("Priority", mData.Priority, true)
                                         .AddField("PP", Math.Max(1, mData.PPTier * PBESettings.DefaultPPMultiplier), true)
                                         .AddField("Power", mData.Power == 0 ? "―" : mData.Power.ToString(), true)
                                         .AddField("Accuracy", mData.Accuracy == 0 ? "―" : mData.Accuracy.ToString(), true)
                                         .AddField("Targets", mData.Targets, true)
                                         .AddField("Flags", mData.Flags, true);
                    switch (mData.Effect)
                    {
                    case PBEMoveEffect.Recoil: embed.AddField("Recoil", $"1/{mData.EffectParam} damage dealt"); break;

                    case PBEMoveEffect.Recoil__10PercentBurn: embed.AddField("Recoil", $"1/{mData.EffectParam} damage dealt"); break;     // TODO: Burn chance

                    case PBEMoveEffect.Recoil__10PercentParalyze: embed.AddField("Recoil", $"1/{mData.EffectParam} damage dealt"); break; // TODO: Paralyze chance

                    case PBEMoveEffect.Struggle: embed.AddField("Recoil", "1/4 user's max HP"); break;

                    case PBEMoveEffect.TODOMOVE: embed.AddField("**ATTENTION**", $"{moveName} is not yet implemented in Pokémon Battle Engine"); break;
                    }
                    await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());
                }
            }
 private void ShouldGiveUpMoveAction(bool value)
 {
     _textChoicesWindow.Close();
     _textChoicesWindow = null;
     _textChoices.Dispose();
     _textChoices = null;
     _stringPrinter.Close();
     _stringPrinter = null;
     if (value)
     {
         PBEMove move = _learningMoves.Dequeue(); // Remove from queue
         string  str  = PBELocalizedString.GetMoveName(move).English;
         CreateMessage(string.Format("{0} did not learn {1}.", _pkmn.Nickname, str));
         _state = State.LearnMove_DidNotLearnMsg;
     }
     else
     {
         SetWantsToLearnMove();
     }
 }
            public async Task Info([Remainder] string abilityName)
            {
                PBEAbility?nAbility = PBELocalizedString.GetAbilityByName(abilityName);

                if (!nAbility.HasValue || nAbility.Value == PBEAbility.None)
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} Invalid ability!");
                }
                else
                {
                    PBEAbility   ability = nAbility.Value;
                    EmbedBuilder embed   = new EmbedBuilder()
                                           .WithAuthor(Context.User)
                                           .WithColor(Utils.RandomColor())
                                           .WithTitle(PBELocalizedString.GetAbilityName(ability).English)
                                           .WithUrl(Utils.URL)
                                           .WithDescription(PBELocalizedString.GetAbilityDescription(ability).English.Replace('\n', ' '));
                    await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());
                }
            }
            public async Task Info([Remainder] string moveName)
            {
                PBEMove?nMove = PBELocalizedString.GetMoveByName(moveName);

                if (!nMove.HasValue || nMove.Value == PBEMove.None)
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} Invalid move!");
                }
                else
                {
                    PBEMove      move  = nMove.Value;
                    PBEMoveData  mData = PBEMoveData.Data[move];
                    EmbedBuilder embed = new EmbedBuilder()
                                         .WithAuthor(Context.User)
                                         .WithColor(Utils.TypeToColor[mData.Type])
                                         .WithTitle(PBELocalizedString.GetMoveName(move).English)
                                         .WithUrl(Utils.URL)
                                         .WithDescription(PBELocalizedString.GetMoveDescription(move).English.Replace('\n', ' '))
                                         .AddField("Type", mData.Type, true)
                                         .AddField("Category", mData.Category, true)
                                         .AddField("Priority", mData.Priority, true)
                                         .AddField("PP", Math.Max(1, mData.PPTier * PBESettings.DefaultSettings.PPMultiplier), true)
                                         .AddField("Power", mData.Power == 0 ? "--" : mData.Power.ToString(), true)
                                         .AddField("Accuracy", mData.Accuracy == 0 ? "--" : mData.Accuracy.ToString(), true);
                    switch (mData.Effect)
                    {
                    case PBEMoveEffect.FlareBlitz: embed.AddField("Recoil", "1/3 damage dealt", true); break;     // TODO: Burn chance

                    case PBEMoveEffect.Recoil: embed.AddField("Recoil", $"1/{mData.EffectParam} damage dealt", true); break;

                    case PBEMoveEffect.Struggle: embed.AddField("Recoil", "1/4 user's max HP", true); break;

                    case PBEMoveEffect.VoltTackle: embed.AddField("Recoil", "1/3 damage dealt", true); break;     // TODO: Paralyze chance
                    }
                    embed.AddField("Targets", mData.Targets, true)
                    .AddField("Flags", mData.Flags, true);
                    await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());
                }
            }
        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);
        }
        // Will only be accurate for the host
        public override string ToString()
        {
            var sb = new StringBuilder();

            sb.AppendLine($"{Nickname}/{Species} {GenderSymbol} Lv.{Level}");
            sb.AppendLine($"HP: {HP}/{MaxHP} ({HPPercentage:P2})");
            sb.Append($"Types: {PBELocalizedString.GetTypeName(Type1).English}");
            if (Type2 != PBEType.None)
            {
                sb.Append($"/{PBELocalizedString.GetTypeName(Type2).English}");
            }
            sb.AppendLine();
            sb.Append($"Known types: {PBELocalizedString.GetTypeName(KnownType1).English}");
            if (KnownType2 != PBEType.None)
            {
                sb.Append($"/{PBELocalizedString.GetTypeName(KnownType2).English}");
            }
            sb.AppendLine();
            sb.AppendLine($"Position: {Team.TrainerName}'s {FieldPosition}");
            sb.AppendLine($"Status1: {Status1}");
            if (Status1 == PBEStatus1.Asleep)
            {
                sb.AppendLine($"Sleep turns: {Status1Counter}/{SleepTurns}");
            }
            else if (Status1 == PBEStatus1.BadlyPoisoned)
            {
                sb.AppendLine($"Toxic Counter: {Status1Counter}");
            }
            sb.AppendLine($"Status2: {Status2}");
            if (Status2.HasFlag(PBEStatus2.Confused))
            {
                sb.AppendLine($"Confusion turns: {ConfusionCounter}/{ConfusionTurns}");
            }
            if (Status2.HasFlag(PBEStatus2.Disguised))
            {
                sb.AppendLine($"Disguised as: {DisguisedAsPokemon.Nickname}");
            }
            if (Status2.HasFlag(PBEStatus2.Infatuated))
            {
                sb.AppendLine($"Infatuated with: {InfatuatedWithPokemon.Nickname}");
            }
            if (Status2.HasFlag(PBEStatus2.LeechSeed))
            {
                sb.AppendLine($"Seeded position: {SeededTeam.TrainerName}'s {SeededPosition}");
            }
            if (Status2.HasFlag(PBEStatus2.Substitute))
            {
                sb.AppendLine($"Substitute HP: {SubstituteHP}");
            }
            sb.AppendLine($"Stats: [A] {Attack}, [D] {Defense}, [SA] {SpAttack}, [SD] {SpDefense}, [S] {Speed}, [W] {Weight:0.0}");
            PBEStat[] statChanges = GetChangedStats();
            if (statChanges.Length > 0)
            {
                var statStrs = new List <string>(7);
                if (Array.IndexOf(statChanges, PBEStat.Attack) != -1)
                {
                    statStrs.Add($"[A] x{PBEBattle.GetStatChangeModifier(AttackChange, false):0.00}");
                }
                if (Array.IndexOf(statChanges, PBEStat.Defense) != -1)
                {
                    statStrs.Add($"[D] x{PBEBattle.GetStatChangeModifier(DefenseChange, false):0.00}");
                }
                if (Array.IndexOf(statChanges, PBEStat.SpAttack) != -1)
                {
                    statStrs.Add($"[SA] x{PBEBattle.GetStatChangeModifier(SpAttackChange, false):0.00}");
                }
                if (Array.IndexOf(statChanges, PBEStat.SpDefense) != -1)
                {
                    statStrs.Add($"[SD] x{PBEBattle.GetStatChangeModifier(SpDefenseChange, false):0.00}");
                }
                if (Array.IndexOf(statChanges, PBEStat.Speed) != -1)
                {
                    statStrs.Add($"[S] x{PBEBattle.GetStatChangeModifier(SpeedChange, false):0.00}");
                }
                if (Array.IndexOf(statChanges, PBEStat.Accuracy) != -1)
                {
                    statStrs.Add($"[AC] x{PBEBattle.GetStatChangeModifier(AccuracyChange, true):0.00}");
                }
                if (Array.IndexOf(statChanges, PBEStat.Evasion) != -1)
                {
                    statStrs.Add($"[E] x{PBEBattle.GetStatChangeModifier(EvasionChange, true):0.00}");
                }
                sb.AppendLine($"Stat changes: {string.Join(", ", statStrs)}");
            }
            sb.AppendLine($"Ability: {PBELocalizedString.GetAbilityName(Ability).English}");
            sb.AppendLine($"Known ability: {(KnownAbility == PBEAbility.MAX ? "???" : PBELocalizedString.GetAbilityName(KnownAbility).English)}");
            sb.AppendLine($"Item: {PBELocalizedString.GetItemName(Item).English}");
            sb.AppendLine($"Known item: {(KnownItem == (PBEItem)ushort.MaxValue ? "???" : PBELocalizedString.GetItemName(KnownItem).English)}");
            if (Moves.Contains(PBEMove.Frustration) || Moves.Contains(PBEMove.Return))
            {
                sb.AppendLine($"Friendship: {Friendship} ({Friendship / byte.MaxValue:P2})");
            }
            if (Moves.Contains(PBEMove.HiddenPower))
            {
                sb.AppendLine($"{PBELocalizedString.GetMoveName(PBEMove.HiddenPower).English}: {PBELocalizedString.GetTypeName(IndividualValues.HiddenPowerType).English}:{IndividualValues.HiddenPowerBasePower}");
            }
            sb.Append("Moves: ");
            for (int i = 0; i < Team.Battle.Settings.NumMoves; i++)
            {
                PBEBattleMoveset.PBEBattleMovesetSlot slot = Moves[i];
                PBEMove move = slot.Move;
                if (i > 0)
                {
                    sb.Append(", ");
                }
                sb.Append(PBELocalizedString.GetMoveName(slot.Move).English);
                if (move != PBEMove.None)
                {
                    sb.Append($" ({slot.PP}/{slot.MaxPP})");
                }
            }
            sb.AppendLine();
            sb.Append("Known moves: ");
            for (int i = 0; i < Team.Battle.Settings.NumMoves; i++)
            {
                PBEBattleMoveset.PBEBattleMovesetSlot slot = 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).English);
                if (move != PBEMove.None && move != PBEMove.MAX)
                {
                    sb.Append($" ({pp}{(maxPP == 0 ? ")" : $"/{maxPP})")}");
                }
            }
Beispiel #24
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());
        }
        private void CB_Evolution()
        {
            switch (_state)
            {
            case State.FadeIn:
            {
                if (_fadeTransition.IsDone)
                {
                    _fadeTransition = null;
                    _stringWindow   = new Window(0, 0.79f, 1, 0.16f, RenderUtils.Color(255, 255, 255, 255));
                    CreateMessage(string.Format("{0} is evolving!", _oldNickname));
                    _state = State.IsEvolvingMsg;
                }
                return;
            }

            case State.IsEvolvingMsg:
            {
                if (ReadMessage())
                {
                    _stringPrinter.Close();
                    _stringPrinter  = null;
                    _fadeTransition = new FadeToColorTransition(1_000, RenderUtils.ColorNoA(200, 200, 200));
                    _state          = State.FadeToWhite;
                }
                return;
            }

            case State.FadeToWhite:
            {
                if (TryCancelEvolution())
                {
                    _fadeTransition = null;
                    CreateMessage(string.Format("{0} stopped evolving!", _oldNickname));
                    _state = State.CancelledMsg;
                    return;
                }
                if (_fadeTransition.IsDone)
                {
                    _fadeTransition = null;
                    if (_evo.Method == EvoMethod.Ninjask_LevelUp)
                    {
                        Evolution.TryCreateShedinja(_pkmn);
                    }
                    _pkmn.Evolve(_evo);
                    LoadPkmnImage();
                    _fadeTransition = new FadeFromColorTransition(1_000, RenderUtils.ColorNoA(200, 200, 200));
                    _state          = State.FadeToEvo;
                }
                return;
            }

            case State.FadeToEvo:
            {
                if (_fadeTransition.IsDone)
                {
                    _fadeTransition = null;
                    SoundControl.PlayCry(_pkmn.Species, _pkmn.Form);
                    CreateMessage(string.Format("{0} evolved into {1}!", _oldNickname, PBELocalizedString.GetSpeciesName(_pkmn.Species).English));
                    _state = State.EvolvedIntoMsg;
                }
                return;
            }

            case State.EvolvedIntoMsg:
            {
                if (ReadMessage())
                {
                    _stringPrinter.Close();
                    _stringPrinter = null;
                    // Check for moves to learn
                    _learningMoves = new Queue <PBEMove>(new LevelUpData(_pkmn.Species, _pkmn.Form).GetNewMoves(_pkmn.Level));
                    CheckForLearnMoves();
                }
                return;
            }

            case State.FadeOut:
            {
                if (_fadeTransition.IsDone)
                {
                    _fadeTransition = null;
                    OverworldGUI.Instance.ReturnToFieldWithFadeInAfterEvolutionCheck();
                }
                return;
            }

            case State.CancelledMsg:
            {
                if (ReadMessage())
                {
                    _stringPrinter.Close();
                    _stringPrinter = null;
                    SetFadeOut();
                }
                return;
            }

            // Learning moves
            case State.LearnMove_WantsToLearnMoveMsg:
            {
                if (ReadMessageEnded())
                {
                    TextGUIChoices.CreateStandardYesNoChoices(ShouldLearnMoveAction, out _textChoices, out _textChoicesWindow);
                    _state = State.LearnMove_WantsToLearnMoveChoice;
                }
                return;
            }

            case State.LearnMove_WantsToLearnMoveChoice:
            case State.LearnMove_GiveUpLearningChoice:
            {
                HandleMultichoice();
                return;
            }

            case State.LearnMove_FadeToSummary:
            {
                if (_fadeTransition.IsDone)
                {
                    _fadeTransition           = null;
                    _stringWindow.IsInvisible = true;
                    _textChoicesWindow.Close();
                    _textChoicesWindow = null;
                    _textChoices.Dispose();
                    _textChoices = null;
                    _stringPrinter.Close();
                    _stringPrinter = null;
                    _ = new SummaryGUI(_pkmn, SummaryGUI.Mode.LearnMove, OnSummaryClosed, learningMove: _learningMoves.Peek());
                }
                return;
            }

            case State.LearnMove_FadeFromSummary:
            {
                if (_fadeTransition.IsDone)
                {
                    // Give up on learning
                    if (_forgetMove == -1 || _forgetMove == PkmnConstants.NumMoves)
                    {
                        SetGiveUpLearningMove();
                    }
                    else
                    {
                        Moveset.MovesetSlot slot    = _pkmn.Moveset[_forgetMove];
                        PBEMove             oldMove = slot.Move;
                        string  oldMoveStr          = PBELocalizedString.GetMoveName(oldMove).English;
                        PBEMove move    = _learningMoves.Dequeue();  // Remove from queue
                        string  moveStr = PBELocalizedString.GetMoveName(move).English;
                        slot.Move = move;
                        PBEMoveData mData = PBEMoveData.Data[move];
                        slot.PP    = PBEDataUtils.CalcMaxPP(mData.PPTier, 0, PkmnConstants.PBESettings);
                        slot.PPUps = 0;
                        CreateMessage(string.Format("{0} forgot {1}\nand learned {2}!", _pkmn.Nickname, oldMoveStr, moveStr));
                        _state = State.LearnMove_ForgotMsg;
                    }
                }
                return;
            }

            case State.LearnMove_GiveUpLearningMsg:
            {
                if (ReadMessageEnded())
                {
                    TextGUIChoices.CreateStandardYesNoChoices(ShouldGiveUpMoveAction, out _textChoices, out _textChoicesWindow);
                    _state = State.LearnMove_GiveUpLearningChoice;
                }
                return;
            }

            case State.LearnMove_DidNotLearnMsg:
            case State.LearnMove_ForgotMsg:
            {
                if (ReadMessage())
                {
                    _stringPrinter.Close();
                    _stringPrinter = null;
                    CheckForLearnMoves();
                }
                return;
            }
            }
        }
Beispiel #27
0
        private unsafe void DrawInfoPage(uint *bmpAddress, int bmpWidth, int bmpHeight)
        {
            const float winX            = 0.03f;
            const float winY            = 0.15f;
            const float winW            = 0.97f - winX;
            const float winH            = 0.85f - winY;
            const float leftColX        = winX + 0.02f;
            const float rightColX       = winX + 0.52f;
            const float rightColY       = winY + 0.03f;
            const float rightColW       = 0.95f - rightColX;
            const float rightColH       = 0.82f - rightColY;
            const float rightColCenterX = rightColX + (rightColW / 2f);
            const float textStartY      = rightColY + 0.02f;
            const float textSpacingY    = 0.1f;
            int         xpW             = (int)(bmpWidth * 0.3f);
            int         xpX             = RenderUtils.GetCoordinatesForCentering(bmpWidth, xpW, rightColCenterX);
            int         xpY             = (int)(bmpHeight * (rightColY + 0.61f));

            RenderUtils.FillRoundedRectangle(bmpAddress, bmpWidth, bmpHeight, winX, winY, winX + winW, winY + winH, 15, RenderUtils.Color(128, 215, 135, 255));
            RenderUtils.FillRoundedRectangle(bmpAddress, bmpWidth, bmpHeight, rightColX, rightColY, rightColX + rightColW, rightColY + rightColH, 8, RenderUtils.Color(210, 210, 210, 255));

            Font leftColFont = Font.Default;

            uint[] leftColColors = Font.DefaultWhite_DarkerOutline_I;
            Font   rightColFont  = Font.Default;

            uint[] rightColColors = Font.DefaultBlack_I;

            void PlaceLeftCol(int i, string leftColStr)
            {
                float y = textStartY + (i * textSpacingY);

                leftColFont.DrawString(bmpAddress, bmpWidth, bmpHeight, leftColX, y, leftColStr, leftColColors);
            }

            void PlaceRightCol(int i, string rightColStr, uint[] colors)
            {
                float y = textStartY + (i * textSpacingY);

                rightColFont.MeasureString(rightColStr, out int strW, out _);
                rightColFont.DrawString(bmpAddress, bmpWidth, bmpHeight,
                                        RenderUtils.GetCoordinatesForCentering(bmpWidth, strW, rightColCenterX), (int)(bmpHeight * y), rightColStr, colors);
            }

            PlaceLeftCol(0, "Species");
            PlaceLeftCol(1, "Type(s)");
            PlaceLeftCol(2, "OT");
            PlaceLeftCol(3, "OT ID");
            PlaceLeftCol(4, "Exp. Points");
            PlaceLeftCol(5, "Exp. To Next Level");

            PBESpecies species;
            PBEForm    form;
            OTInfo     ot;
            byte       level;
            uint       exp;

            if (_pPkmn is not null)
            {
                species = _pPkmn.Species;
                form    = _pPkmn.Form;
                ot      = _pPkmn.OT;
                level   = _pPkmn.Level;
                exp     = _pPkmn.EXP;
            }
            else if (_pcPkmn is not null)
            {
                species = _pcPkmn.Species;
                form    = _pcPkmn.Form;
                ot      = _pcPkmn.OT;
                level   = _pcPkmn.Level;
                exp     = _pcPkmn.EXP;
            }
            else
            {
                PartyPokemon     pPkmn = _bPkmn.PartyPkmn;
                PBEBattlePokemon bPkmn = _bPkmn.Pkmn;
                species = pPkmn.Species;
                form    = bPkmn.RevertForm;
                ot      = pPkmn.OT;
                level   = bPkmn.Level;
                exp     = bPkmn.EXP;
            }

            var  bs = BaseStats.Get(species, form, true);
            uint toNextLvl;

            if (level >= PkmnConstants.MaxLevel)
            {
                toNextLvl = 0;
                RenderUtils.EXP_SingleLine(bmpAddress, bmpWidth, bmpHeight, xpX, xpY, xpW, 0);
            }
            else
            {
                PBEGrowthRate gr = bs.GrowthRate;
                toNextLvl = PBEEXPTables.GetEXPRequired(gr, (byte)(level + 1)) - exp;
                RenderUtils.EXP_SingleLine(bmpAddress, bmpWidth, bmpHeight, xpX, xpY, xpW, exp, level, gr);
            }

            // Species
            string str = PBELocalizedString.GetSpeciesName(species).English;

            PlaceRightCol(0, str, rightColColors);
            // Types
            str = PBELocalizedString.GetTypeName(bs.Type1).English;
            if (bs.Type2 != PBEType.None)
            {
                str += ' ' + PBELocalizedString.GetTypeName(bs.Type2).English;
            }
            PlaceRightCol(1, str, rightColColors);
            // OT
            str = ot.TrainerName;
            PlaceRightCol(2, str, ot.TrainerIsFemale ? Font.DefaultRed_I : Font.DefaultBlue_I);
            // OT ID
            str = ot.TrainerID.ToString();
            PlaceRightCol(3, str, rightColColors);
            // Exp
            str = exp.ToString();
            PlaceRightCol(4, str, rightColColors);
            // To next level
            str = toNextLvl.ToString();
            PlaceRightCol(5, str, rightColColors);
        }
Beispiel #28
0
        private unsafe void DrawPersonalPage(uint *bmpAddress, int bmpWidth, int bmpHeight)
        {
            const float winX         = 0.08f;
            const float winY         = 0.15f;
            const float winW         = 0.75f - winX;
            const float winH         = 0.93f - winY;
            const float leftColX     = winX + 0.03f;
            const float textStartY   = winY + 0.05f;
            const float textSpacingY = 0.1f;

            RenderUtils.FillRoundedRectangle(bmpAddress, bmpWidth, bmpHeight, winX, winY, winX + winW, winY + winH, 15, RenderUtils.Color(145, 225, 225, 255));

            Font leftColFont = Font.Default;

            uint[] leftColColors   = Font.DefaultBlack_I;
            uint[] highlightColors = Font.DefaultRed_I;

            void Place(int i, int xOff, string leftColStr, uint[] colors)
            {
                float y = textStartY + (i * textSpacingY);

                leftColFont.DrawString(bmpAddress, bmpWidth, bmpHeight, (int)(bmpWidth * leftColX) + xOff, (int)(bmpHeight * y), leftColStr, colors);
            }

            PBENature  nature;
            DateTime   met;
            MapSection loc;
            byte       metLvl;
            uint       pid;
            IVs        ivs;

            if (_pPkmn is not null)
            {
                nature = _pPkmn.Nature;
                met    = _pPkmn.MetDate;
                loc    = _pPkmn.MetLocation;
                metLvl = _pPkmn.MetLevel;
                pid    = _pPkmn.PID;
                ivs    = _pPkmn.IndividualValues;
            }
            else if (_pcPkmn is not null)
            {
                nature = _pcPkmn.Nature;
                met    = _pcPkmn.MetDate;
                loc    = _pcPkmn.MetLocation;
                metLvl = _pcPkmn.MetLevel;
                pid    = _pcPkmn.PID;
                ivs    = _pcPkmn.IndividualValues;
            }
            else
            {
                PartyPokemon pPkmn = _bPkmn.PartyPkmn;
                nature = pPkmn.Nature;
                met    = pPkmn.MetDate;
                loc    = pPkmn.MetLocation;
                metLvl = pPkmn.MetLevel;
                pid    = pPkmn.PID;
                ivs    = pPkmn.IndividualValues;
            }

            string    characteristic = Characteristic.GetCharacteristic(pid, ivs) + '.';
            PBEFlavor?flavor         = PBEDataUtils.GetLikedFlavor(nature);

            // Nature
            string str = PBELocalizedString.GetNatureName(nature).English + ' ';

            Place(0, 0, str, highlightColors);
            leftColFont.MeasureString(str, out int strW, out _);
            str = "nature.";
            Place(0, strW, str, leftColColors);
            // Met date
            str = met.ToString("MMMM dd, yyyy");
            Place(1, 0, str, leftColColors);
            // Met location
            str = loc.ToString();
            Place(2, 0, str, highlightColors);
            // Met level
            str = string.Format("Met at Level {0}.", metLvl);
            Place(3, 0, str, leftColColors);
            // Characteristic
            str = characteristic;
            Place(5, 0, str, leftColColors);
            // Flavor
            if (flavor.HasValue)
            {
                str = "Likes ";
                Place(6, 0, str, leftColColors);
                leftColFont.MeasureString(str, out strW, out _);
                str = flavor.Value.ToString() + ' ';
                Place(6, strW, str, highlightColors);
                leftColFont.MeasureString(str, out int strW2, out _);
                str = "food.";
                Place(6, strW + strW2, str, leftColColors);
            }
            else
            {
                str = "Likes all food.";
                Place(6, 0, str, leftColColors);
            }
        }
Beispiel #29
0
        private unsafe void DrawStatsPage(uint *bmpAddress, int bmpWidth, int bmpHeight)
        {
            const float winX            = 0.03f;
            const float winY            = 0.15f;
            const float winW            = 0.97f - winX;
            const float winH            = 0.995f - winY;
            const float leftColX        = winX + 0.02f;
            const float rightColX       = winX + 0.52f;
            const float rightColY       = winY + 0.02f;
            const float rightColW       = 0.95f - rightColX;
            const float rightColH       = 0.535f;
            const float rightColCenterX = rightColX + (rightColW / 2f);
            const float textStartY      = rightColY + 0.01f;
            const float textStart2Y     = rightColY + 0.13f;
            const float textSpacingY    = 0.08f;
            const float abilTextY       = textStart2Y + (5.5f * textSpacingY);
            const float abilDescX       = leftColX + 0.03f;
            const float abilDescY       = textStart2Y + (6.6f * textSpacingY);
            const float abilX           = winX + 0.18f;
            const float abilTextX       = abilX + 0.03f;
            const float abilY           = abilTextY;
            const float abilW           = 0.95f - abilX;
            const float abilH           = 0.075f;
            int         hpW             = (int)(bmpWidth * 0.3f);
            int         hpX             = RenderUtils.GetCoordinatesForCentering(bmpWidth, hpW, rightColCenterX);
            int         hpY             = (int)(bmpHeight * (rightColY + 0.09f));

            RenderUtils.FillRoundedRectangle(bmpAddress, bmpWidth, bmpHeight, winX, winY, winX + winW, winY + winH, 12, RenderUtils.Color(135, 145, 250, 255));
            // Stats
            RenderUtils.FillRoundedRectangle(bmpAddress, bmpWidth, bmpHeight, rightColX, rightColY, rightColX + rightColW, rightColY + rightColH, 8, RenderUtils.Color(210, 210, 210, 255));
            // Abil
            RenderUtils.FillRoundedRectangle(bmpAddress, bmpWidth, bmpHeight, abilX, abilY, abilX + abilW, abilY + abilH, 5, RenderUtils.Color(210, 210, 210, 255));
            // Abil desc
            RenderUtils.FillRoundedRectangle(bmpAddress, bmpWidth, bmpHeight, leftColX, abilDescY, 0.95f, 0.98f, 5, RenderUtils.Color(210, 210, 210, 255));

            Font leftColFont = Font.Default;

            uint[] leftColColors = Font.DefaultWhite_DarkerOutline_I;
            Font   rightColFont  = Font.Default;

            uint[] rightColColors = Font.DefaultBlack_I;
            uint[] boostedColors  = Font.DefaultRed_Lighter_O;
            uint[] dislikedColors = Font.DefaultCyan_O;

            void PlaceLeftCol(int i, string leftColStr, bool boosted, bool disliked)
            {
                float y;

                if (i == -1)
                {
                    y = abilTextY;
                }
                else if (i == -2)
                {
                    y = textStartY;
                }
                else
                {
                    y = textStart2Y + (i * textSpacingY);
                }
                uint[] colors;
                if (boosted)
                {
                    colors = boostedColors;
                }
                else if (disliked)
                {
                    colors = dislikedColors;
                }
                else
                {
                    colors = leftColColors;
                }
                leftColFont.DrawString(bmpAddress, bmpWidth, bmpHeight, leftColX, y, leftColStr, colors);
            }

            void PlaceRightCol(int i, string rightColStr, uint[] colors)
            {
                float y = i == -2 ? textStartY : textStart2Y + (i * textSpacingY);

                rightColFont.MeasureString(rightColStr, out int strW, out _);
                rightColFont.DrawString(bmpAddress, bmpWidth, bmpHeight,
                                        RenderUtils.GetCoordinatesForCentering(bmpWidth, strW, rightColCenterX), (int)(bmpHeight * y), rightColStr, colors);
            }

            BaseStats          bs;
            PBEAbility         abil;
            PBENature          nature;
            IPBEStatCollection evs;
            IVs    ivs;
            byte   level;
            ushort hp;
            ushort maxHP;

            if (_pPkmn is not null)
            {
                bs     = BaseStats.Get(_pPkmn.Species, _pPkmn.Form, true);
                abil   = _pPkmn.Ability;
                nature = _pPkmn.Nature;
                evs    = _pPkmn.EffortValues;
                ivs    = _pPkmn.IndividualValues;
                level  = _pPkmn.Level;
                hp     = _pPkmn.HP;
                maxHP  = _pPkmn.MaxHP;
            }
            else if (_pcPkmn is not null)
            {
                bs     = BaseStats.Get(_pcPkmn.Species, _pcPkmn.Form, true);
                abil   = _pcPkmn.Ability;
                nature = _pcPkmn.Nature;
                evs    = _pcPkmn.EffortValues;
                ivs    = _pcPkmn.IndividualValues;
                level  = _pcPkmn.Level;
                hp     = maxHP = PBEDataUtils.CalculateStat(bs, PBEStat.HP, nature, evs.GetStat(PBEStat.HP), ivs.HP, level, PkmnConstants.PBESettings);
            }
            else
            {
                PartyPokemon     pPkmn = _bPkmn.PartyPkmn;
                PBEBattlePokemon bPkmn = _bPkmn.Pkmn;
                bs     = BaseStats.Get(pPkmn.Species, bPkmn.RevertForm, true);
                abil   = pPkmn.Ability;
                nature = pPkmn.Nature;
                evs    = bPkmn.EffortValues;
                ivs    = pPkmn.IndividualValues;
                level  = bPkmn.Level;
                hp     = bPkmn.HP;
                maxHP  = bPkmn.MaxHP;
            }
            ushort  atk      = PBEDataUtils.CalculateStat(bs, PBEStat.Attack, nature, evs.GetStat(PBEStat.Attack), ivs.Attack, level, PkmnConstants.PBESettings);
            ushort  def      = PBEDataUtils.CalculateStat(bs, PBEStat.Defense, nature, evs.GetStat(PBEStat.Defense), ivs.Defense, level, PkmnConstants.PBESettings);
            ushort  spAtk    = PBEDataUtils.CalculateStat(bs, PBEStat.SpAttack, nature, evs.GetStat(PBEStat.SpAttack), ivs.SpAttack, level, PkmnConstants.PBESettings);
            ushort  spDef    = PBEDataUtils.CalculateStat(bs, PBEStat.SpDefense, nature, evs.GetStat(PBEStat.SpDefense), ivs.SpDefense, level, PkmnConstants.PBESettings);
            ushort  speed    = PBEDataUtils.CalculateStat(bs, PBEStat.Speed, nature, evs.GetStat(PBEStat.Speed), ivs.Speed, level, PkmnConstants.PBESettings);
            PBEStat?favored  = nature.GetLikedStat();
            PBEStat?disliked = nature.GetDislikedStat();

            PlaceLeftCol(-2, "HP", false, false);
            PlaceLeftCol(0, "Attack", favored == PBEStat.Attack, disliked == PBEStat.Attack);
            PlaceLeftCol(1, "Defense", favored == PBEStat.Defense, disliked == PBEStat.Defense);
            PlaceLeftCol(2, "Special Attack", favored == PBEStat.SpAttack, disliked == PBEStat.SpAttack);
            PlaceLeftCol(3, "Special Defense", favored == PBEStat.SpDefense, disliked == PBEStat.SpDefense);
            PlaceLeftCol(4, "Speed", favored == PBEStat.Speed, disliked == PBEStat.Speed);
            PlaceLeftCol(-1, "Ability", false, false);

            // HP
            string str = string.Format("{0}/{1}", hp, maxHP);

            PlaceRightCol(-2, str, rightColColors);
            double percent = (double)hp / maxHP;

            RenderUtils.HP_TripleLine(bmpAddress, bmpWidth, bmpHeight, hpX, hpY, hpW, percent);
            // Attack
            str = atk.ToString();
            PlaceRightCol(0, str, rightColColors);
            // Defense
            str = def.ToString();
            PlaceRightCol(1, str, rightColColors);
            // Sp. Attack
            str = spAtk.ToString();
            PlaceRightCol(2, str, rightColColors);
            // Sp. Defense
            str = spDef.ToString();
            PlaceRightCol(3, str, rightColColors);
            // Speed
            str = speed.ToString();
            PlaceRightCol(4, str, rightColColors);
            // Ability
            str = PBELocalizedString.GetAbilityName(abil).English;
            rightColFont.DrawString(bmpAddress, bmpWidth, bmpHeight, abilTextX, abilTextY, str, rightColColors);
            // Ability desc
            str = PBELocalizedString.GetAbilityDescription(abil).English;
            leftColFont.DrawString(bmpAddress, bmpWidth, bmpHeight, abilDescX, abilDescY, str, rightColColors);
        }
Beispiel #30
0
        private unsafe void DrawMovesPage(uint *bmpAddress, int bmpWidth, int bmpHeight)
        {
            const float winX         = 0.08f;
            const float winY         = 0.15f;
            const float winW         = 0.75f - winX;
            const float winH         = 0.9f - winY;
            const float moveColX     = winX + 0.03f;
            const float moveTextX    = moveColX + 0.02f;
            const float moveColW     = 0.69f - winX;
            const float itemSpacingY = winH / (PkmnConstants.NumMoves + 0.75f);
            const float moveX        = 0.21f;
            const float moveY        = 0.03f;
            const float ppX          = 0.12f;
            const float ppNumX       = 0.35f;
            const float ppY          = itemSpacingY / 2;
            const float cancelY      = winY + moveY + (PkmnConstants.NumMoves * itemSpacingY);

            RenderUtils.FillRoundedRectangle(bmpAddress, bmpWidth, bmpHeight, winX, winY, winX + winW, winY + winH, 15, RenderUtils.Color(250, 128, 120, 255));

            Font moveFont = Font.Default;

            uint[] moveColors = Font.DefaultWhite_DarkerOutline_I;
            uint[] ppColors   = Font.DefaultBlack_I;

            void Place(int i, PBEMove move, int pp, int maxPP)
            {
                PBEMoveData mData = PBEMoveData.Data[move];
                float       x     = moveTextX;
                float       y     = winY + moveY + (i * itemSpacingY);
                string      str   = PBELocalizedString.GetTypeName(mData.Type).English;

                moveFont.DrawString(bmpAddress, bmpWidth, bmpHeight, x, y, str, moveColors);
                x  += moveX;
                str = PBELocalizedString.GetMoveName(move).English;
                moveFont.DrawString(bmpAddress, bmpWidth, bmpHeight, x, y, str, moveColors);
                x   = moveTextX + ppX;
                y  += ppY;
                str = "PP";
                moveFont.DrawString(bmpAddress, bmpWidth, bmpHeight, x, y, str, ppColors);
                x   = moveTextX + ppNumX;
                str = string.Format("{0}/{1}", pp, maxPP);
                moveFont.MeasureString(str, out int strW, out _);
                moveFont.DrawString(bmpAddress, bmpWidth, bmpHeight, RenderUtils.GetCoordinatesForCentering(bmpWidth, strW, x), (int)(bmpHeight * y), str, ppColors);

                DrawSelection(i);
            }

            void DrawSelection(int i)
            {
                if (_selectingMove != i)
                {
                    return;
                }
                float x = moveColX;
                float y = winY + moveY + (i * itemSpacingY);
                float w = moveColW;
                float h = i == PkmnConstants.NumMoves ? itemSpacingY / 2 : itemSpacingY;

                RenderUtils.DrawRoundedRectangle(bmpAddress, bmpWidth, bmpHeight, x, y, x + w, y + h, 5, RenderUtils.Color(48, 180, 255, 200));
            }

            // Moves
            if (_pPkmn is not null)
            {
                Moveset moves = _pPkmn.Moveset;
                for (int m = 0; m < PkmnConstants.NumMoves; m++)
                {
                    Moveset.MovesetSlot slot = moves[m];
                    PBEMove             move = slot.Move;
                    if (move == PBEMove.None)
                    {
                        continue;
                    }
                    int pp    = slot.PP;
                    int maxPP = PBEDataUtils.CalcMaxPP(move, slot.PPUps, PkmnConstants.PBESettings);
                    Place(m, move, pp, maxPP);
                }
            }
            else if (_pcPkmn is not null)
            {
                BoxMoveset moves = _pcPkmn.Moveset;
                for (int m = 0; m < PkmnConstants.NumMoves; m++)
                {
                    BoxMoveset.BoxMovesetSlot slot = moves[m];
                    PBEMove move = slot.Move;
                    if (move == PBEMove.None)
                    {
                        continue;
                    }
                    int maxPP = PBEDataUtils.CalcMaxPP(move, slot.PPUps, PkmnConstants.PBESettings);
                    Place(m, move, maxPP, maxPP);
                }
            }
            else
            {
                PBEBattlePokemon bPkmn = _bPkmn.Pkmn;
                PBEBattleMoveset moves = bPkmn.Status2.HasFlag(PBEStatus2.Transformed) ? bPkmn.TransformBackupMoves : bPkmn.Moves;
                for (int m = 0; m < PkmnConstants.NumMoves; m++)
                {
                    PBEBattleMoveset.PBEBattleMovesetSlot slot = moves[m];
                    PBEMove move = slot.Move;
                    if (move == PBEMove.None)
                    {
                        continue;
                    }
                    int pp    = slot.PP;
                    int maxPP = slot.MaxPP;
                    Place(m, move, pp, maxPP);
                }
            }

            // Cancel or new move
            if (_learningMove != PBEMove.None)
            {
                uint[]      learnColors = Font.DefaultBlue_I;
                PBEMoveData mData       = PBEMoveData.Data[_learningMove];
                float       x           = moveTextX;
                string      str         = PBELocalizedString.GetTypeName(mData.Type).English;
                moveFont.DrawString(bmpAddress, bmpWidth, bmpHeight, x, cancelY, str, learnColors);
                x  += moveX;
                str = PBELocalizedString.GetMoveName(_learningMove).English;
                moveFont.DrawString(bmpAddress, bmpWidth, bmpHeight, x, cancelY, str, learnColors);
                DrawSelection(PkmnConstants.NumMoves);
            }
            else
            {
                if (_selectingMove != -1)
                {
                    string str = "Cancel";
                    moveFont.DrawString(bmpAddress, bmpWidth, bmpHeight, moveTextX, cancelY, str, moveColors);
                    DrawSelection(PkmnConstants.NumMoves);
                }
            }
        }