Esempio n. 1
0
        public static bool ValidateRoamingEncounter(PKM pk, Shiny shiny = Shiny.Random, int flawless = 0)
        {
            var seed = pk.EncryptionConstant;

            if (seed == int.MaxValue)
            {
                return(false); // Unity's Rand is [int.MinValue, int.MaxValue)
            }
            var xoro = new Xoroshiro128Plus8b(seed);

            // Check PID
            var fakeTID = xoro.NextUInt(); // fakeTID
            var pid     = xoro.NextUInt();

            pid = GetRevisedPID(fakeTID, pid, pk);
            if (pk.PID != pid)
            {
                return(false);
            }

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

            var determined = 0;

            while (determined < flawless)
            {
                var idx = (int)xoro.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] = (int)xoro.NextUInt(31 + 1);
                }
            }

            if (ivs[0] != pk.IV_HP)
            {
                return(false);
            }
            if (ivs[1] != pk.IV_ATK)
            {
                return(false);
            }
            if (ivs[2] != pk.IV_DEF)
            {
                return(false);
            }
            if (ivs[3] != pk.IV_SPA)
            {
                return(false);
            }
            if (ivs[4] != pk.IV_SPD)
            {
                return(false);
            }
            if (ivs[5] != pk.IV_SPE)
            {
                return(false);
            }

            // Don't check Hidden ability, as roaming encounters are 1/2 only.
            if (pk.AbilityNumber != (1 << (int)xoro.NextUInt(2)))
            {
                return(false);
            }

            return(GetIsMatchEnd(pk, xoro) || GetIsMatchEndWithCuteCharm(pk, xoro) || GetIsMatchEndWithSynchronize(pk, xoro));
        }