Exemplo n.º 1
0
        private CheckResult VerifyAbility(LegalityAnalysis data)
        {
            var pkm = data.pkm;
            var pi  = data.PersonalInfo;

            // Check ability is possible (within bounds)
            int ability = pkm.Ability;
            int abilval = pi.GetAbilityIndex(ability);

            if (abilval < 0)
            {
                return(GetInvalid(LAbilityUnexpected));
            }

            var abilities = pi.Abilities;
            int format    = pkm.Format;

            if (format >= 6)
            {
                // Check AbilityNumber is a single set bit
                var num = pkm.AbilityNumber;
                if (!(num != 0 && (num & (num - 1)) == 0)) // not [!zero, and power of 2]
                {
                    return(GetInvalid(LAbilityMismatchFlag));
                }

                // Check AbilityNumber points to ability
                int an = num >> 1;
                if (an >= abilities.Count || abilities[an] != ability)
                {
                    return(GetInvalid(LAbilityMismatchFlag));
                }

                // Check AbilityNumber for transfers without unique abilities
                int gen = data.Info.Generation;
                if (gen is 3 or 4 or 5 && num != 4)
                {
                    // To determine AbilityNumber [PK5->PK6], check if the first ability in Personal matches the ability.
                    // It is not possible to flip it to the other index as capsule requires unique abilities.
                    if (abilities[0] == abilities[1] && num != 1)
                    {
                        // Check if any pre-evolution could have it flipped.
                        var evos = data.Info.EvoChainsAllGens[6];
                        var pt   = GameData.GetPersonal(GameUtil.GetVersion(pkm.Format));
                        if (!GetWasDual(evos, pt, pkm))
                        {
                            return(GetInvalid(LAbilityMismatchFlag));
                        }
                    }
                }
            }

            if (format >= 8) // Ability Patch
            {
                if (pkm.AbilityNumber == 4)
                {
                    if (CanAbilityPatch(format, abilities, pkm.Species))
                    {
                        return(GetValid(LAbilityPatchUsed));
                    }

                    var e = data.EncounterOriginal;

                    if (e.Species != pkm.Species && CanAbilityPatch(format, PKX.Personal.GetFormEntry(e.Species, e.Form).Abilities, e.Species))
                    {
                        return(GetValid(LAbilityPatchUsed));
                    }
                }
            }

            var enc = data.EncounterMatch;

            if (enc is MysteryGift {
                Generation : >= 4
            } g)
            {
                return(VerifyAbilityMG(data, g, abilities));
            }

            if (format < 6)
            {
                return(VerifyAbility345(data, enc, abilities, abilval));
            }

            return(VerifyAbility(data, abilities, abilval));
        }