Пример #1
0
        private static void SetAbility(PKM pk, IBattleTemplate set, AbilityPermission preference)
        {
            if (pk.Ability != set.Ability && set.Ability != -1)
            {
                pk.SetAbility(set.Ability);
            }

            if (preference > 0)
            {
                var abilities = pk.PersonalInfo.Abilities;
                // Set unspecified abilities
                if (set.Ability == -1)
                {
                    pk.RefreshAbility(preference.GetSingleValue());
                    if (pk is PK5 pk5 && preference == AbilityPermission.OnlyHidden)
                    {
                        pk5.HiddenAbility = true;
                    }
                }
                // Set preferred ability number if applicable
                if (abilities[preference.GetSingleValue()] == set.Ability)
                {
                    pk.AbilityNumber = (int)preference;
                }
                // 3/4/5 transferred to 6+ will have ability 1 if both abilitynum 1 and 2 are the same. Capsule cant convert 1 -> 2 if the abilities arnt unique
                if (pk.Format >= 6 && pk.Generation is 3 or 4 or 5 && pk.AbilityNumber != 4 && abilities[0] == abilities[1])
                {
                    pk.AbilityNumber = 1;
                }
                if (pk is G3PKM && abilities[0] == abilities[1])
                {
                    pk.AbilityNumber = 1;
                }
            }
        }
Пример #2
0
    public static void IsFixedAbility(AbilityPermission value, bool expect, int zeroIndex)
    {
        var result = value.IsSingleValue(out var index);

        result.Should().Be(expect);
        if (result)
        {
            index.Should().Be(zeroIndex);
        }
    }
Пример #3
0
        public static void ApplyDetails(PKM pk, EncounterCriteria criteria,
                                        Shiny shiny  = Shiny.FixedValue,
                                        int flawless = -1,
                                        AbilityPermission ability = AbilityPermission.Any12)
        {
            if (shiny == Shiny.FixedValue)
            {
                shiny = criteria.Shiny is Shiny.Random or Shiny.Never ? Shiny.Never : Shiny.Always;
            }
            if (flawless == -1)
            {
                flawless = 0;
            }

            int       ctr         = 0;
            const int maxAttempts = 50_000;
            var       rnd         = Util.Rand;

            do
            {
                ulong s0   = rnd.Rand64();
                ulong s1   = rnd.Rand64();
                var   xors = new XorShift128(s0, s1);
                if (TryApplyFromSeed(pk, criteria, shiny, flawless, xors, ability))
                {
                    return;
                }
            } while (++ctr != maxAttempts);

            {
                ulong s0   = rnd.Rand64();
                ulong s1   = rnd.Rand64();
                var   xors = new XorShift128(s0, s1);
                TryApplyFromSeed(pk, EncounterCriteria.Unrestricted, shiny, flawless, xors, ability);
            }
        }
Пример #4
0
 private static int RemapAbilityToParam(AbilityPermission a) => a switch
 {
Пример #5
0
        public static bool TryApplyFromSeed(PKM pk, EncounterCriteria criteria, Shiny shiny, int flawless, XorShift128 xors, AbilityPermission ability)
        {
            // Encryption Constant
            pk.EncryptionConstant = xors.NextUInt();

            // PID
            var fakeTID = xors.NextUInt(); // fakeTID
            var pid     = xors.NextUInt();

            pid = GetRevisedPID(fakeTID, pid, pk);
            if (shiny == Shiny.Never)
            {
                if (GetIsShiny(pk.TID, pk.SID, pid))
                {
                    return(false);
                }
            }
            else if (shiny != Shiny.Random)
            {
                if (!GetIsShiny(pk.TID, pk.SID, pid))
                {
                    return(false);
                }

                if (shiny == Shiny.AlwaysSquare && pk.ShinyXor != 0)
                {
                    return(false);
                }
                if (shiny == Shiny.AlwaysStar && pk.ShinyXor == 0)
                {
                    return(false);
                }
            }
            pk.PID = pid;

            // Check IVs: Create flawless IVs at random indexes, then the random IVs for not flawless.
            Span <int> ivs        = stackalloc[] { UNSET, UNSET, UNSET, UNSET, UNSET, UNSET };
            const int  MAX        = 31;
            var        determined = 0;

            while (determined < flawless)
            {
                var idx = (int)xors.NextUInt(6);
                if (ivs[idx] != UNSET)
                {
                    continue;
                }
                ivs[idx] = 31;
                determined++;
            }

            for (var i = 0; i < ivs.Length; i++)
            {
                if (ivs[i] == UNSET)
                {
                    ivs[i] = xors.NextInt(0, MAX + 1);
                }
            }

            if (!criteria.IsIVsCompatible(ivs, 8))
            {
                return(false);
            }

            pk.IV_HP  = ivs[0];
            pk.IV_ATK = ivs[1];
            pk.IV_DEF = ivs[2];
            pk.IV_SPA = ivs[3];
            pk.IV_SPD = ivs[4];
            pk.IV_SPE = ivs[5];

            // Ability
            var n = ability switch
            {
                AbilityPermission.Any12 => (int)xors.NextUInt(2),
                AbilityPermission.Any12H => (int)xors.NextUInt(3),
                _ => (int)ability >> 1,
            };

            pk.SetAbilityIndex(n);

            // Gender (skip this if gender is fixed)
            var genderRatio = PersonalTable.BDSP.GetFormEntry(pk.Species, pk.Form).Gender;

            if (genderRatio == PersonalInfo.RatioMagicGenderless)
            {
                pk.Gender = 2;
            }
            else if (genderRatio == PersonalInfo.RatioMagicMale)
            {
                pk.Gender = 0;
            }
            else if (genderRatio == PersonalInfo.RatioMagicFemale)
            {
                pk.Gender = 1;
            }
            else
            {
                var next = (((int)xors.NextUInt(253) + 1 < genderRatio) ? 1 : 0);
                if (criteria.Gender is 0 or 1 && next != criteria.Gender)
                {
                    return(false);
                }
                pk.Gender = next;
            }

            if (criteria.Nature is Nature.Random)
            {
                pk.Nature = (int)xors.NextUInt(25);
            }
            else // Skip nature, assuming Synchronize
            {
                pk.Nature = (int)criteria.Nature;
            }
            pk.StatNature = pk.Nature;

            // Remainder
            var scale = (IScaledSize)pk;

            scale.HeightScalar = (byte)((int)xors.NextUInt(0x81) + (int)xors.NextUInt(0x80));
            scale.WeightScalar = (byte)((int)xors.NextUInt(0x81) + (int)xors.NextUInt(0x80));

            // Item, don't care
            return(true);
        }
Пример #6
0
 public static int GetSingleValue(this AbilityPermission value) => value switch
 {
Пример #7
0
 /// <summary>
 /// Set Nature and Ability of the pokemon
 /// </summary>
 /// <param name="pk">PKM to modify</param>
 /// <param name="set">Showdown Set to refer</param>
 /// <param name="enc">Encounter to reference</param>
 /// <param name="preference">Ability index (1/2/4) preferred; &lt;= 0 for any</param>
 public static void SetNatureAbility(this PKM pk, IBattleTemplate set, IEncounterable enc, AbilityPermission preference = AbilityPermission.Any12H)
 {
     SetNature(pk, set, enc);
     SetAbility(pk, set, preference);
 }
Пример #8
0
 public static void IsHiddenPossible(AbilityPermission value, bool expect) => value.CanBeHidden().Should().Be(expect);