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)); }