Exemplo n.º 1
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 PBEDataProvider.Instance.GetPokemonData(s, f).PreEvolutions)
                {
                    Add1(cs, cf);
                }
                list.Add((s, f));
            }

            Add1(species, form);
            return(list);
        }
        public static IReadOnlyCollection <PBEMove> GetLegalMoves(PBESpecies species, PBEForm form, byte level)
        {
            List <(PBESpecies, PBEForm)> speciesToStealFrom = GetSpecies(species, form);

            var moves = new List <PBEMove>();

            foreach ((PBESpecies spe, PBEForm fo) in speciesToStealFrom)
            {
                IPBEDDPokemonDataExtended pData = PBEDefaultDataProvider.Instance.GetPokemonDataExtended(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 != PBEDDMoveObtainMethod.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 (PBEDDEventPokemon.Events.TryGetValue(spe, out ReadOnlyCollection <PBEDDEventPokemon>?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.FindIndex(m => PBEDataProvider.Instance.GetMoveData(m, cache: false).Effect == PBEMoveEffect.Sketch) != -1)
                {
                    return(PBEDataUtils.SketchLegalMoves);
                }
            }
            return(moves.Distinct().Where(m => PBEDataUtils.IsMoveUsable(m)).ToArray());
        }
Exemplo n.º 3
0
 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();
     }
 }
Exemplo n.º 4
0
        public static Bitmap GetMinispriteBitmap(PBESpecies species, PBEForm form, PBEGender gender, bool shiny)
        {
            string speciesStr = PBEDataUtils.GetNameOfForm(species, form) ?? species.ToString();
            string genderStr  = gender == PBEGender.Female && HasFemaleSprite(species, true) ? "_F" : string.Empty;

            return(new Bitmap(GetResourceStream("PKMN.PKMN_" + speciesStr + (shiny ? "_S" : string.Empty) + genderStr + ".png")));
        }
Exemplo n.º 5
0
        public static Sprite GetMinisprite(PBESpecies species, PBEForm form, PBEGender gender, bool shiny)
        {
            string speciesStr = PBEDataUtils.GetNameOfForm(species, form) ?? species.ToString();
            string genderStr  = gender == PBEGender.Female && HasFemaleSprite(species, true) ? "_F" : string.Empty;

            return(Sprite.LoadOrGet("Pkmn.PKMN_" + speciesStr + (shiny ? "_S" : string.Empty) + genderStr + ".png"));
        }
Exemplo n.º 6
0
 internal static void ValidateSpecies(PBESpecies species, PBEForm form, bool requireUsableOutsideOfBattle)
 {
     if (!PBEDataUtils.IsValidForm(species, form, requireUsableOutsideOfBattle))
     {
         throw new ArgumentOutOfRangeException(nameof(form));
     }
 }
Exemplo n.º 7
0
 public Pokedex()
 {
     _data = new Dictionary <PBESpecies, Dictionary <PBEForm, Dictionary <PBEGender, Entry> > >((int)PBESpecies.MAX);
     for (var species = (PBESpecies)1; species < PBESpecies.MAX; species++)
     {
         PBEGender[]             genders = GetGenderKeys(species);
         IReadOnlyList <PBEForm> forms   = PBEDataUtils.GetForms(species, false);
         if (forms.Count == 0)
         {
             forms = new PBEForm[] { 0 };
         }
         var formDict = new Dictionary <PBEForm, Dictionary <PBEGender, Entry> >(forms.Count);
         for (int f = 0; f < forms.Count; f++)
         {
             PBEForm form       = forms[f];
             var     genderDict = new Dictionary <PBEGender, Entry>(genders.Length);
             for (int g = 0; g < genders.Length; g++)
             {
                 PBEGender gender = genders[g];
                 genderDict.Add(gender, new Entry(species, form, gender));
             }
             formDict.Add(form, genderDict);
         }
         _data.Add(species, formDict);
     }
 }
Exemplo n.º 8
0
        public static (PBESpecies, PBEForm) RandomSpecies(this IReadOnlyList <PBESpecies> eligible, bool requireUsableOutsideOfBattle)
        {
            PBESpecies species            = eligible.RandomElement();
            IReadOnlyList <PBEForm> forms = PBEDataUtils.GetForms(species, requireUsableOutsideOfBattle);
            PBEForm form = forms.Count > 0 ? forms.RandomElement() : 0;

            return(species, form);
        }
        public static PBEReadOnlyLocalizedString GetFormName(PBESpecies species, PBEForm form)
        {
            PBEDataUtils.ValidateSpecies(species, form, false);
            List <FormNameSearchResult> results = PBEDefaultDataProvider.Instance.QueryDatabase <FormNameSearchResult>(string.Format(QuerySpecies, "FormNames", species, PBEDataUtils.GetNameOfForm(species, form) ?? "0"));

            if (results.Count == 1)
            {
                return(new PBEReadOnlyLocalizedString(results[0]));
            }
            throw new InvalidDataException();
        }
Exemplo n.º 10
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
            IPBELocalizedString localized = PBEDataProvider.Instance.GetFormName(species, form);

            return(StringRenderer.Render(localized.FromPBECultureInfo(), parameter?.ToString()));
        }
Exemplo n.º 11
0
        public static IEnumerable <PBEMove> GetEggMoves(PBESpecies species, PBEForm form)
        {
            PBEMove[] arr;

            string resource = "Pokedata." + Utils.GetPkmnDirectoryName(species, form) + ".EggMoves.bin";

            using (var r = new EndianBinaryReader(Utils.GetResourceStream(resource)))
            {
                arr = r.ReadEnums <PBEMove>(r.ReadByte());
            }

            return(arr.Where(m => PBEDataUtils.IsMoveUsable(m)).Distinct()); // For now
        }
Exemplo n.º 12
0
        public static string GetPkmnDirectoryName(PBESpecies species, PBEForm form)
        {
            string dir;

            if (form == 0)
            {
                dir = species.ToString();
            }
            else
            {
                dir = PBEDataUtils.GetNameOfForm(species, form);
            }
            return(dir);
        }
Exemplo n.º 13
0
 public static Sprite GetPokemonSprite(PBESpecies species, PBEForm form, PBEGender gender, bool shiny, bool backSprite, bool behindSubstitute)
 {
     if (behindSubstitute)
     {
         return(backSprite ? _substituteBackSprite : _substituteFrontSprite);
     }
     else
     {
         string speciesStr  = PBEDataUtils.GetNameOfForm(species, form) ?? species.ToString();
         string orientation = backSprite ? "_B" : "_F";
         string genderStr   = gender == PBEGender.Female && HasFemaleSprite(species, false) ? "_F" : string.Empty;
         return(Sprite.LoadOrGet("Pkmn.PKMN_" + speciesStr + orientation + (shiny ? "_S" : string.Empty) + genderStr + ".gif"));
     }
 }
Exemplo n.º 14
0
 public TestPartyPokemon(PBESettings settings, PBESpecies species, PBEForm form, byte level, params PBEMove[] moves)
 {
     Species          = species;
     Form             = form;
     Level            = level;
     EXP              = PBEDataProvider.Instance.GetEXPRequired(PBEDataProvider.Instance.GetPokemonData(species, form).GrowthRate, level);
     Nickname         = species.ToString();
     Gender           = PBEDataProvider.GlobalRandom.RandomGender(PBEDataProvider.Instance.GetPokemonData(species, form).GenderRatio);
     CaughtBall       = PBEItem.PokeBall;
     EffortValues     = new PBEStatCollection(0, 0, 0, 0, 0, 0);
     IndividualValues = new PBEStatCollection(0, 0, 0, 0, 0, 0);
     Moveset          = new TestPartyMoveset(settings, moves);
     HP = PBEDataUtils.CalculateStat(species, form, PBEStat.HP, Nature, EffortValues.GetStat(PBEStat.HP), IndividualValues.GetStat(PBEStat.HP), level, settings);
 }
Exemplo n.º 15
0
 public void Write(JsonTextWriter w)
 {
     w.WriteStartObject();
     w.WritePropertyName(nameof(Chance));
     w.WriteValue(Chance);
     w.WritePropertyName(nameof(MinLevel));
     w.WriteValue(MinLevel);
     w.WritePropertyName(nameof(MaxLevel));
     w.WriteValue(MaxLevel);
     w.WritePropertyName(nameof(Species));
     w.WriteEnum(Species);
     w.WritePropertyName(nameof(Form));
     w.WriteValue(PBEDataUtils.GetNameOfForm(Species, Form));
     w.WriteEndObject();
 }
Exemplo n.º 16
0
 public void Write(JsonTextWriter w)
 {
     w.WriteStartObject();
     w.WritePropertyName(nameof(Flags));
     w.WriteFlagsEnum(Flags);
     w.WritePropertyName(nameof(Section));
     w.WriteEnum(Section);
     w.WritePropertyName(nameof(Weather));
     w.WriteEnum(Weather);
     w.WritePropertyName(nameof(Music));
     w.WriteEnum(Music);
     w.WritePropertyName(nameof(BurmyForm));
     w.WriteValue(PBEDataUtils.GetNameOfForm(PBESpecies.Burmy, BurmyForm));
     w.WriteEndObject();
 }
Exemplo n.º 17
0
        public static string GetPokemonSprite(PBESpecies species, PBEForm form, bool shiny, PBEGender gender, bool behindSubstitute, bool backSprite)
        {
            string orientation = backSprite ? "_B" : "_F";

            if (behindSubstitute)
            {
                return(ImageURL + "STATUS2_Substitute" + orientation + ".gif");
            }
            else
            {
                string speciesStr = PBEDataUtils.GetNameOfForm(species, form) ?? species.ToString();
                string genderStr  = gender == PBEGender.Female && HasFemaleSprite(species) ? "_F" : string.Empty;
                return(ImageURL + "PKMN_" + speciesStr + orientation + (shiny ? "_S" : string.Empty) + genderStr + ".gif");
            }
        }
Exemplo n.º 18
0
        private void Debug_GiveRandomPokemon(bool egg)
        {
            (PBESpecies species, PBEForm form) = PBEDataProvider.GlobalRandom.RandomSpecies(true);
            PartyPokemon pkmn;

            if (egg)
            {
                pkmn = PartyPokemon.CreateDefaultEgg(species, form);
            }
            else
            {
                byte level = (byte)PBEDataProvider.GlobalRandom.RandomInt(PkmnConstants.MinLevel, PkmnConstants.MaxLevel);
                pkmn      = PartyPokemon.CreatePlayerOwnedMon(species, form, level);
                pkmn.Item = (ItemType)PBEDataProvider.GlobalRandom.RandomElement(PBEDataUtils.GetValidItems(pkmn.Species, pkmn.Form));
                pkmn.Debug_RandomizeMoves();
            }
            GivePokemon(pkmn);
        }
Exemplo n.º 19
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)
            {
                IPBEPokemonData pData = PBEDataProvider.Instance.GetPokemonData(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 => PBEDataProvider.Instance.GetMoveData(m, cache: false).Effect == PBEMoveEffect.Sketch))
                {
                    return(PBEDataUtils.SketchLegalMoves);
                }
            }
            return(moves.Distinct().Where(m => PBEDataUtils.IsMoveUsable(m)).ToArray());
        }
Exemplo n.º 20
0
        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);
        }
Exemplo n.º 21
0
        private PBETurnAction DecideAction(PBEBattlePokemon user, List <PBETurnAction> actions, List <PBEBattlePokemon> standBy)
        {
            // Gather all options of switching and moves
            PBEMove[] usableMoves     = user.GetUsableMoves();
            var       possibleActions = new List <(PBETurnAction Action, float Score)>();

            for (int m = 0; m < usableMoves.Length; m++) // Score moves
            {
                PBEMove         move            = usableMoves[m];
                PBEType         moveType        = user.GetMoveType(move);
                PBEMoveTarget   moveTargets     = user.GetMoveTargets(move);
                PBETurnTarget[] possibleTargets = PBEDataUtils.IsSpreadMove(moveTargets)
                            ? new PBETurnTarget[] { PBEBattleUtils.GetSpreadMoveTargets(user, moveTargets) }
                            : PBEBattleUtils.GetPossibleTargets(user, moveTargets);
                foreach (PBETurnTarget possibleTarget in possibleTargets)
                {
                    // TODO: RandomFoeSurrounding (probably just account for the specific effects that use this target type)
                    // TODO: Don't queue up to do the same thing (two trying to afflict the same target when there are multiple targets)
                    var targets = new List <PBEBattlePokemon>();
                    if (possibleTarget.HasFlag(PBETurnTarget.AllyLeft))
                    {
                        Trainer.Team.TryAddPokemonToCollection(PBEFieldPosition.Left, targets);
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.AllyCenter))
                    {
                        Trainer.Team.TryAddPokemonToCollection(PBEFieldPosition.Center, targets);
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.AllyRight))
                    {
                        Trainer.Team.TryAddPokemonToCollection(PBEFieldPosition.Right, targets);
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.FoeLeft))
                    {
                        Trainer.Team.OpposingTeam.TryAddPokemonToCollection(PBEFieldPosition.Left, targets);
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.FoeCenter))
                    {
                        Trainer.Team.OpposingTeam.TryAddPokemonToCollection(PBEFieldPosition.Center, targets);
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.FoeRight))
                    {
                        Trainer.Team.OpposingTeam.TryAddPokemonToCollection(PBEFieldPosition.Right, targets);
                    }
                    float score = ScoreMove(targets, user, move, moveType, actions);
                    possibleActions.Add((new PBETurnAction(user, move, possibleTarget), score));
                }
            }
            if (user.CanSwitchOut())
            {
                PBEBattlePokemon[] availableForSwitch = Trainer.Party.Except(standBy).Where(p => p.FieldPosition == PBEFieldPosition.None && p.CanBattle).ToArray();
                for (int s = 0; s < availableForSwitch.Length; s++) // Score switches
                {
                    PBEBattlePokemon switchPkmn = availableForSwitch[s];
                    // TODO: Entry hazards
                    // TODO: Known moves of active battlers
                    // TODO: Type effectiveness
                    float score = -10;
                    possibleActions.Add((new PBETurnAction(user, switchPkmn), score));
                }
            }

            IOrderedEnumerable <(PBETurnAction Action, float Score)> byScore = possibleActions.OrderByDescending(t => t.Score);

            Debug_LogGeneratedActions(user, byScore);
            float bestScore = byScore.First().Score;

            return(PBEDataProvider.GlobalRandom.RandomElement(byScore.Where(t => t.Score == bestScore).ToArray()).Action); // Pick random action of the ones that tied for best score
        }
Exemplo n.º 22
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);
            }
        }
Exemplo n.º 23
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})")}");
                    }
                }
            }
Exemplo n.º 24
0
 public void SetMaxPP()
 {
     PP = PBEDataUtils.CalcMaxPP(Move, PPUps, PkmnConstants.PBESettings);
 }
Exemplo n.º 25
0
 public TestPartyMovesetSlot(PBEMove move, byte ppUps, PBESettings settings)
 {
     Move  = move;
     PPUps = ppUps;
     PP    = PBEDataUtils.CalcMaxPP(move, ppUps, settings);
 }
Exemplo n.º 26
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);
        }
Exemplo n.º 27
0
        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;
            }
            }
        }
Exemplo n.º 28
0
        private static PBETurnAction DecideAction(PBETrainer trainer, PBEBattlePokemon user, IEnumerable <PBETurnAction> actions, IEnumerable <PBEBattlePokemon> standBy)
        {
            // Gather all options of switching and moves
            PBEMove[] usableMoves     = user.GetUsableMoves();
            var       possibleActions = new List <(PBETurnAction Action, double Score)>();

            for (int m = 0; m < usableMoves.Length; m++) // Score moves
            {
                PBEMove         move            = usableMoves[m];
                PBEType         moveType        = user.GetMoveType(move);
                PBEMoveTarget   moveTargets     = user.GetMoveTargets(move);
                PBETurnTarget[] possibleTargets = PBEDataUtils.IsSpreadMove(moveTargets)
                            ? new PBETurnTarget[] { PBEBattleUtils.GetSpreadMoveTargets(user, moveTargets) }
                            : PBEBattleUtils.GetPossibleTargets(user, moveTargets);
                foreach (PBETurnTarget possibleTarget in possibleTargets)
                {
                    // TODO: RandomFoeSurrounding (probably just account for the specific effects that use this target type)
                    // TODO: Don't queue up to do the same thing (two trying to afflict the same target when there are multiple targets)
                    var targets = new List <PBEBattlePokemon>();
                    if (possibleTarget.HasFlag(PBETurnTarget.AllyLeft))
                    {
                        targets.Add(trainer.TryGetPokemon(PBEFieldPosition.Left));
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.AllyCenter))
                    {
                        targets.Add(trainer.TryGetPokemon(PBEFieldPosition.Center));
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.AllyRight))
                    {
                        targets.Add(trainer.TryGetPokemon(PBEFieldPosition.Right));
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.FoeLeft))
                    {
                        targets.Add(trainer.Team.OpposingTeam.TryGetPokemon(PBEFieldPosition.Left));
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.FoeCenter))
                    {
                        targets.Add(trainer.Team.OpposingTeam.TryGetPokemon(PBEFieldPosition.Center));
                    }
                    if (possibleTarget.HasFlag(PBETurnTarget.FoeRight))
                    {
                        targets.Add(trainer.Team.OpposingTeam.TryGetPokemon(PBEFieldPosition.Right));
                    }
                    double score;
                    if (targets.All(p => p == null))
                    {
                        score = -100;
                    }
                    else
                    {
                        score = 0;
                        targets.RemoveAll(p => p == null);
                        IPBEMoveData mData = PBEDataProvider.Instance.GetMoveData(move);
                        if (!mData.IsMoveUsable())
                        {
                            throw new ArgumentOutOfRangeException(nameof(trainer), $"{move} is not yet implemented in Pokémon Battle Engine.");
                        }
                        switch (mData.Effect)
                        {
                        case PBEMoveEffect.Acrobatics:
                        case PBEMoveEffect.Bounce:
                        case PBEMoveEffect.BrickBreak:
                        case PBEMoveEffect.Brine:
                        case PBEMoveEffect.ChipAway:
                        case PBEMoveEffect.CrushGrip:
                        case PBEMoveEffect.Dig:
                        case PBEMoveEffect.Dive:
                        case PBEMoveEffect.Eruption:
                        case PBEMoveEffect.Facade:
                        case PBEMoveEffect.Feint:
                        case PBEMoveEffect.Flail:
                        case PBEMoveEffect.Fly:
                        case PBEMoveEffect.FoulPlay:
                        case PBEMoveEffect.Frustration:
                        case PBEMoveEffect.GrassKnot:
                        case PBEMoveEffect.HeatCrash:
                        case PBEMoveEffect.Hex:
                        case PBEMoveEffect.HiddenPower:
                        case PBEMoveEffect.Hit:
                        case PBEMoveEffect.Hit__2Times:
                        case PBEMoveEffect.Hit__2Times__MaybePoison:
                        case PBEMoveEffect.Hit__2To5Times:
                        case PBEMoveEffect.Hit__MaybeBurn:
                        case PBEMoveEffect.Hit__MaybeBurn__10PercentFlinch:
                        case PBEMoveEffect.Hit__MaybeBurnFreezeParalyze:
                        case PBEMoveEffect.Hit__MaybeConfuse:
                        case PBEMoveEffect.Hit__MaybeFlinch:
                        case PBEMoveEffect.Hit__MaybeFreeze:
                        case PBEMoveEffect.Hit__MaybeFreeze__10PercentFlinch:
                        case PBEMoveEffect.Hit__MaybeLowerTarget_ACC_By1:
                        case PBEMoveEffect.Hit__MaybeLowerTarget_ATK_By1:
                        case PBEMoveEffect.Hit__MaybeLowerTarget_DEF_By1:
                        case PBEMoveEffect.Hit__MaybeLowerTarget_SPATK_By1:
                        case PBEMoveEffect.Hit__MaybeLowerTarget_SPDEF_By1:
                        case PBEMoveEffect.Hit__MaybeLowerTarget_SPDEF_By2:
                        case PBEMoveEffect.Hit__MaybeLowerTarget_SPE_By1:
                        case PBEMoveEffect.Hit__MaybeLowerUser_ATK_DEF_By1:
                        case PBEMoveEffect.Hit__MaybeLowerUser_DEF_SPDEF_By1:
                        case PBEMoveEffect.Hit__MaybeLowerUser_SPATK_By2:
                        case PBEMoveEffect.Hit__MaybeLowerUser_SPE_By1:
                        case PBEMoveEffect.Hit__MaybeLowerUser_SPE_DEF_SPDEF_By1:
                        case PBEMoveEffect.Hit__MaybeParalyze:
                        case PBEMoveEffect.Hit__MaybeParalyze__10PercentFlinch:
                        case PBEMoveEffect.Hit__MaybePoison:
                        case PBEMoveEffect.Hit__MaybeRaiseUser_ATK_By1:
                        case PBEMoveEffect.Hit__MaybeRaiseUser_ATK_DEF_SPATK_SPDEF_SPE_By1:
                        case PBEMoveEffect.Hit__MaybeRaiseUser_DEF_By1:
                        case PBEMoveEffect.Hit__MaybeRaiseUser_SPATK_By1:
                        case PBEMoveEffect.Hit__MaybeRaiseUser_SPE_By1:
                        case PBEMoveEffect.Hit__MaybeToxic:
                        case PBEMoveEffect.HPDrain:
                        case PBEMoveEffect.Judgment:
                        case PBEMoveEffect.Magnitude:
                        case PBEMoveEffect.Payback:
                        case PBEMoveEffect.PayDay:
                        case PBEMoveEffect.Psyshock:
                        case PBEMoveEffect.Punishment:
                        case PBEMoveEffect.Recoil:
                        case PBEMoveEffect.Recoil__10PercentBurn:
                        case PBEMoveEffect.Recoil__10PercentParalyze:
                        case PBEMoveEffect.Retaliate:
                        case PBEMoveEffect.Return:
                        case PBEMoveEffect.SecretPower:
                        case PBEMoveEffect.ShadowForce:
                        case PBEMoveEffect.SmellingSalt:
                        case PBEMoveEffect.StoredPower:
                        case PBEMoveEffect.TechnoBlast:
                        case PBEMoveEffect.Venoshock:
                        case PBEMoveEffect.WakeUpSlap:
                        case PBEMoveEffect.WeatherBall:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                // TODO: Favor hitting ally with move if waterabsorb/voltabsorb etc
                                // TODO: Liquid ooze
                                // TODO: Check items
                                // TODO: Stat changes and accuracy (even thunder/guillotine accuracy)
                                // TODO: Check base power specifically against hp remaining (include spread move damage reduction)
                                PBETypeEffectiveness.IsAffectedByAttack(user, target, moveType, out double damageMultiplier, useKnownInfo: true);
                                if (damageMultiplier <= 0)     // (-infinity, 0.0] Ineffective
                                {
                                    score += target.Team == trainer.Team ? 0 : -60;
                                }
                                else if (damageMultiplier <= 0.25)     // (0.0, 0.25] NotVeryEffective
                                {
                                    score += target.Team == trainer.Team ? -5 : -30;
                                }
                                else if (damageMultiplier < 1)     // (0.25, 1.0) NotVeryEffective
                                {
                                    score += target.Team == trainer.Team ? -10 : -10;
                                }
                                else if (damageMultiplier == 1)     // [1.0, 1.0] Normal
                                {
                                    score += target.Team == trainer.Team ? -15 : +10;
                                }
                                else if (damageMultiplier < 4)     // (1.0, 4.0) SuperEffective
                                {
                                    score += target.Team == trainer.Team ? -20 : +25;
                                }
                                else     // [4.0, infinity) SuperEffective
                                {
                                    score += target.Team == trainer.Team ? -30 : +40;
                                }
                                if (user.ReceivesSTAB(moveType) && damageMultiplier > 0)
                                {
                                    score += (user.Ability == PBEAbility.Adaptability ? 7 : 5) * (target.Team == trainer.Team ? -1 : +1);
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.Attract:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                // TODO: Destiny knot
                                if (target.IsAttractionPossible(user, useKnownInfo: true) == PBEResult.Success)
                                {
                                    score += target.Team == trainer.Team ? -20 : +40;
                                }
                                else
                                {
                                    score += target.Team == trainer.Team ? 0 : -60;
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.Burn:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                // TODO: Heatproof, physical attacker
                                if (target.IsBurnPossible(user, useKnownInfo: true) == PBEResult.Success)
                                {
                                    score += target.Team == trainer.Team ? -20 : +40;
                                }
                                else
                                {
                                    score += target.Team == trainer.Team ? 0 : -60;
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.ChangeTarget_ACC:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Accuracy, mData.EffectParam, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.ChangeTarget_ATK:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Attack, mData.EffectParam, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.ChangeTarget_DEF:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Defense, mData.EffectParam, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.ChangeTarget_EVA:
                        case PBEMoveEffect.Minimize:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Evasion, mData.EffectParam, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.ChangeTarget_SPATK:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.SpAttack, mData.EffectParam, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.ChangeTarget_SPDEF:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.SpDefense, mData.EffectParam, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.ChangeTarget_SPE:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Speed, mData.EffectParam, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.Confuse:
                        case PBEMoveEffect.Flatter:
                        case PBEMoveEffect.Swagger:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                // TODO: Only swagger/flatter if the opponent most likely won't use it against you
                                if (target.IsConfusionPossible(user, useKnownInfo: true) == PBEResult.Success)
                                {
                                    score += target.Team == trainer.Team ? -20 : +40;
                                }
                                else
                                {
                                    score += target.Team == trainer.Team ? 0 : -60;
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.Growth:
                        {
                            int change = trainer.Battle.WillLeafGuardActivate() ? +2 : +1;
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Attack, change, ref score);
                                ScoreStatChange(user, target, PBEStat.SpAttack, change, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.LeechSeed:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                if (target.IsLeechSeedPossible(useKnownInfo: true) == PBEResult.Success)
                                {
                                    score += target.Team == trainer.Team ? -20 : +40;
                                }
                                else
                                {
                                    score += target.Team == trainer.Team ? 0 : -60;
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.LightScreen:
                        {
                            score += trainer.Team.TeamStatus.HasFlag(PBETeamStatus.LightScreen) || IsTeammateUsingEffect(actions, PBEMoveEffect.LightScreen) ? -100 : +40;
                            break;
                        }

                        case PBEMoveEffect.LowerTarget_ATK_DEF_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Attack, -1, ref score);
                                ScoreStatChange(user, target, PBEStat.Defense, -1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.LowerTarget_DEF_SPDEF_By1_Raise_ATK_SPATK_SPE_By2:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Defense, -1, ref score);
                                ScoreStatChange(user, target, PBEStat.SpDefense, -1, ref score);
                                ScoreStatChange(user, target, PBEStat.Attack, +2, ref score);
                                ScoreStatChange(user, target, PBEStat.SpAttack, +2, ref score);
                                ScoreStatChange(user, target, PBEStat.Speed, +2, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.LuckyChant:
                        {
                            score += trainer.Team.TeamStatus.HasFlag(PBETeamStatus.LuckyChant) || IsTeammateUsingEffect(actions, PBEMoveEffect.LuckyChant) ? -100 : +40;
                            break;
                        }

                        case PBEMoveEffect.Moonlight:
                        case PBEMoveEffect.Rest:
                        case PBEMoveEffect.RestoreTargetHP:
                        case PBEMoveEffect.Roost:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                if (target.Team == trainer.Team)
                                {
                                    score += HPAware(target.HPPercentage, +45, -15);
                                }
                                else
                                {
                                    score -= 100;
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.Nothing:
                        case PBEMoveEffect.Teleport:
                        {
                            score -= 100;
                            break;
                        }

                        case PBEMoveEffect.Paralyze:
                        case PBEMoveEffect.ThunderWave:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                bool tw = mData.Effect != PBEMoveEffect.ThunderWave || PBETypeEffectiveness.ThunderWaveTypeCheck(user, target, move, useKnownInfo: true) == PBEResult.Success;
                                if (tw && target.IsParalysisPossible(user, useKnownInfo: true) == PBEResult.Success)
                                {
                                    score += target.Team == trainer.Team ? -20 : +40;
                                }
                                else
                                {
                                    score += target.Team == trainer.Team ? 0 : -60;
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.Poison:
                        case PBEMoveEffect.Toxic:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                // TODO: Poison Heal
                                if (target.IsPoisonPossible(user, useKnownInfo: true) == PBEResult.Success)
                                {
                                    score += target.Team == trainer.Team ? -20 : +40;
                                }
                                else
                                {
                                    score += target.Team == trainer.Team ? 0 : -60;
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.RaiseTarget_ATK_ACC_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Attack, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.Accuracy, +1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.RaiseTarget_ATK_DEF_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Attack, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.Defense, +1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.RaiseTarget_ATK_DEF_ACC_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Attack, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.Defense, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.Accuracy, +1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.RaiseTarget_ATK_SPATK_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Attack, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.SpAttack, +1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.RaiseTarget_ATK_SPE_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Attack, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.Speed, +1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.RaiseTarget_DEF_SPDEF_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Defense, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.SpDefense, +1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.RaiseTarget_SPATK_SPDEF_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.SpAttack, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.SpDefense, +1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.RaiseTarget_SPATK_SPDEF_SPE_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.SpAttack, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.SpDefense, +1, ref score);
                                ScoreStatChange(user, target, PBEStat.Speed, +1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.RaiseTarget_SPE_By2_ATK_By1:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                ScoreStatChange(user, target, PBEStat.Speed, +2, ref score);
                                ScoreStatChange(user, target, PBEStat.Attack, +1, ref score);
                            }
                            break;
                        }

                        case PBEMoveEffect.Reflect:
                        {
                            score += trainer.Team.TeamStatus.HasFlag(PBETeamStatus.Reflect) || IsTeammateUsingEffect(actions, PBEMoveEffect.Reflect) ? -100 : +40;
                            break;
                        }

                        case PBEMoveEffect.Safeguard:
                        {
                            score += trainer.Team.TeamStatus.HasFlag(PBETeamStatus.Safeguard) || IsTeammateUsingEffect(actions, PBEMoveEffect.Safeguard) ? -100 : +40;
                            break;
                        }

                        case PBEMoveEffect.Sleep:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                // TODO: Bad Dreams
                                if (target.IsSleepPossible(user, useKnownInfo: true) == PBEResult.Success)
                                {
                                    score += target.Team == trainer.Team ? -20 : +40;
                                }
                                else
                                {
                                    score += target.Team == trainer.Team ? 0 : -60;
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.Substitute:
                        {
                            foreach (PBEBattlePokemon target in targets)
                            {
                                if (target.IsSubstitutePossible() == PBEResult.Success)
                                {
                                    score += target.Team == trainer.Team ? HPAware(target.HPPercentage, -30, +50) : -60;
                                }
                                else
                                {
                                    score += target.Team == trainer.Team ? 0 : -20;
                                }
                            }
                            break;
                        }

                        case PBEMoveEffect.BellyDrum:
                        case PBEMoveEffect.Camouflage:
                        case PBEMoveEffect.ChangeTarget_SPATK__IfAttractionPossible:
                        case PBEMoveEffect.Conversion:
                        case PBEMoveEffect.Curse:
                        case PBEMoveEffect.Endeavor:
                        case PBEMoveEffect.Entrainment:
                        case PBEMoveEffect.FinalGambit:
                        case PBEMoveEffect.FocusEnergy:
                        case PBEMoveEffect.Foresight:
                        case PBEMoveEffect.GastroAcid:
                        case PBEMoveEffect.Hail:
                        case PBEMoveEffect.Haze:
                        case PBEMoveEffect.HelpingHand:
                        case PBEMoveEffect.HPDrain__RequireSleep:
                        case PBEMoveEffect.LockOn:
                        case PBEMoveEffect.MagnetRise:
                        case PBEMoveEffect.Metronome:
                        case PBEMoveEffect.MiracleEye:
                        case PBEMoveEffect.Nightmare:
                        case PBEMoveEffect.OneHitKnockout:
                        case PBEMoveEffect.PainSplit:
                        case PBEMoveEffect.PowerTrick:
                        case PBEMoveEffect.Protect:
                        case PBEMoveEffect.PsychUp:
                        case PBEMoveEffect.Psywave:
                        case PBEMoveEffect.QuickGuard:
                        case PBEMoveEffect.RainDance:
                        case PBEMoveEffect.ReflectType:
                        case PBEMoveEffect.Refresh:
                        case PBEMoveEffect.RolePlay:
                        case PBEMoveEffect.Sandstorm:
                        case PBEMoveEffect.SeismicToss:
                        case PBEMoveEffect.Selfdestruct:
                        case PBEMoveEffect.SetDamage:
                        case PBEMoveEffect.SimpleBeam:
                        case PBEMoveEffect.Sketch:
                        case PBEMoveEffect.Snore:
                        case PBEMoveEffect.Soak:
                        case PBEMoveEffect.Spikes:
                        case PBEMoveEffect.StealthRock:
                        case PBEMoveEffect.SuckerPunch:
                        case PBEMoveEffect.SunnyDay:
                        case PBEMoveEffect.SuperFang:
                        case PBEMoveEffect.Tailwind:
                        case PBEMoveEffect.ToxicSpikes:
                        case PBEMoveEffect.Transform:
                        case PBEMoveEffect.TrickRoom:
                        case PBEMoveEffect.Whirlwind:
                        case PBEMoveEffect.WideGuard:
                        case PBEMoveEffect.WorrySeed:
                        {
                            // TODO
                            break;
                        }

                        default: throw new ArgumentOutOfRangeException(nameof(IPBEMoveData.Effect));
                        }
                    }
                    possibleActions.Add((new PBETurnAction(user, move, possibleTarget), score));
                }
            }
            if (user.CanSwitchOut())
            {
                PBEBattlePokemon[] availableForSwitch = trainer.Party.Except(standBy).Where(p => p.FieldPosition == PBEFieldPosition.None && p.HP > 0).ToArray();
                for (int s = 0; s < availableForSwitch.Length; s++) // Score switches
                {
                    PBEBattlePokemon switchPkmn = availableForSwitch[s];
                    // TODO: Entry hazards
                    // TODO: Known moves of active battlers
                    // TODO: Type effectiveness
                    double score = -10d;
                    possibleActions.Add((new PBETurnAction(user, switchPkmn), score));
                }
            }

            string ToDebugString((PBETurnAction Action, double Score) t)
            {
                string str = "{";

                if (t.Action.Decision == PBETurnDecision.Fight)
                {
                    str += string.Format("Fight {0} {1}", t.Action.FightMove, t.Action.FightTargets);
                }
                else
                {
                    str += string.Format("Switch {0}", trainer.TryGetPokemon(t.Action.SwitchPokemonId).Nickname);
                }
                str += " [" + t.Score + "]}";
                return(str);
            }

            IOrderedEnumerable <(PBETurnAction Action, double Score)> byScore = possibleActions.OrderByDescending(t => t.Score);

            Debug.WriteLine("{0}'s possible actions: {1}", user.Nickname, byScore.Select(t => ToDebugString(t)).Print());
            double bestScore = byScore.First().Score;

            return(PBEDataProvider.GlobalRandom.RandomElement(byScore.Where(t => t.Score == bestScore).ToArray()).Action); // Pick random action of the ones that tied for best score
        }
Exemplo n.º 29
0
            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;
                }
                if (!PBEDataProvider.Instance.GetSpeciesByName(speciesName, out PBESpecies? nSpecies))
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Mention} ― Invalid species!");

                    return;
                }
                PBESpecies species = nSpecies.Value;

                speciesName = PBEDataProvider.Instance.GetSpeciesName(species).English;
                PBEForm form;

                if (formName is null)
                {
                    form = 0;
                }
                else
                {
                    if (!PBEDataProvider.Instance.GetFormByName(species, formName, out PBEForm? nForm))
                    {
                        IReadOnlyList <PBEForm> forms = PBEDataUtils.GetForms(species, false);
                        string str = $"{Context.User.Mention} ― Invalid form for {speciesName}";
                        if (forms.Count > 0)
                        {
                            str += ", valid forms are:\n**" + string.Join("\n", forms.Select(f => PBEDataProvider.Instance.GetFormName(species, f).English)) + "**";
                        }
                        else
                        {
                            str += "! It has no forms!";
                        }
                        await Context.Channel.SendMessageAsync(str);

                        return;
                    }
                    form = nForm.Value;
                }
                formName = PBEDataUtils.HasForms(species, false) ? $" ({PBEDataProvider.Instance.GetFormName(species, form).English})" : string.Empty;
                IPBEPokemonData pData = PBEDataProvider.Instance.GetPokemonData(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 InvalidDataException(nameof(pData.GenderRatio));
                }
                string weaknesses  = string.Empty,
                       resistances = string.Empty,
                       immunities  = string.Empty;

                for (PBEType atk = PBEType.None + 1; atk < PBEType.MAX; atk++)
                {
                    float 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} ― {PBEDefaultDataProvider.Instance.GetSpeciesCategory(species).English}")
                                     .WithUrl(Utils.URL)
                                     .WithDescription(PBEDefaultDataProvider.Instance.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 => PBEDataProvider.Instance.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, PBEDataProvider.GlobalRandom.RandomShiny(), PBEDataProvider.GlobalRandom.RandomGender(pData.GenderRatio), false, false));
                await Context.Channel.SendMessageAsync(string.Empty, embed : embed.Build());
            }
Exemplo n.º 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);
                }
            }
        }