Пример #1
0
        public static bool ValidateOverworldEncounter(PKM pk, uint seed, Shiny shiny = Shiny.FixedValue, int flawless = -1)
        {
            // is the seed Xoroshiro determined, or just truncated state?
            if (seed == uint.MaxValue)
            {
                return(false);
            }

            var xoro = new Xoroshiro128Plus(seed);
            var ec   = (uint)xoro.NextInt(uint.MaxValue);

            if (ec != pk.EncryptionConstant)
            {
                return(false);
            }

            var pid = (uint)xoro.NextInt(uint.MaxValue);

            if (!IsPIDValid(pk, pid, shiny))
            {
                return(false);
            }

            var actualCount = flawless == -1 ? GetIsMatchEnd(pk, xoro) : GetIsMatchEnd(pk, xoro, flawless, flawless);

            return(actualCount != NoMatchIVs);
        }
Пример #2
0
        /// <summary>
        /// Obtains the original seed for the Generation 8 overworld wild encounter.
        /// </summary>
        /// <param name="pk">Entity to check for</param>
        /// <returns>Seed</returns>
        public static uint GetOriginalSeed(PKM pk)
        {
            var seed = pk.EncryptionConstant - unchecked ((uint)Xoroshiro128Plus.XOROSHIRO_CONST);

            if (seed == 0xD5B9C463) // Collision seed with the 0xFFFFFFFF re-roll.
            {
                var xoro = new Xoroshiro128Plus(seed);
                /*  ec */ xoro.NextInt(uint.MaxValue);
                var pid = xoro.NextInt(uint.MaxValue);
                if (pid != pk.PID)
                {
                    return(0xDD6295A4);
                }
            }

            return(seed);
        }
Пример #3
0
        private static bool TryApplyFromSeed(PKM pk, EncounterCriteria criteria, Shiny shiny, int flawless, uint seed)
        {
            var xoro = new Xoroshiro128Plus(seed);

            // Encryption Constant
            pk.EncryptionConstant = (uint)xoro.NextInt(uint.MaxValue);

            // PID
            var pid = (uint)xoro.NextInt(uint.MaxValue);

            if (shiny == Shiny.Never)
            {
                if (GetIsShiny(pk.TID, pk.SID, pid))
                {
                    pid ^= 0x1000_0000;
                }
            }
            else if (shiny != Shiny.Random)
            {
                if (!GetIsShiny(pk.TID, pk.SID, pid))
                {
                    pid = GetShinyPID(pk.TID, pk.SID, pid, 0);
                }

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

            pk.PID = pid;

            // IVs
            Span <int> ivs = stackalloc[] { UNSET, UNSET, UNSET, UNSET, UNSET, UNSET };
            const int  MAX = 31;

            for (int i = 0; i < flawless; i++)
            {
                int index;
                do
                {
                    index = (int)xoro.NextInt(6);
                }while (ivs[index] != UNSET);

                ivs[index] = MAX;
            }

            for (int i = 0; i < ivs.Length; i++)
            {
                if (ivs[i] == UNSET)
                {
                    ivs[i] = (int)xoro.NextInt(32);
                }
            }

            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];

            // Remainder
            var scale = (IScaledSize)pk;

            scale.HeightScalar = (byte)((int)xoro.NextInt(0x81) + (int)xoro.NextInt(0x80));
            scale.WeightScalar = (byte)((int)xoro.NextInt(0x81) + (int)xoro.NextInt(0x80));

            return(true);
        }
Пример #4
0
        private static int GetIsMatchEnd(PKM pk, Xoroshiro128Plus xoro, int start = 0, int end = 3)
        {
            bool skip1 = start == 0 && end == 3;

            for (int iv_count = start; iv_count <= end; iv_count++)
            {
                if (skip1 && iv_count == 1)
                {
                    continue;
                }

                var        copy = xoro;
                Span <int> ivs  = stackalloc [] { UNSET, UNSET, UNSET, UNSET, UNSET, UNSET };
                const int  MAX  = 31;
                for (int i = 0; i < iv_count; i++)
                {
                    int index;
                    do
                    {
                        index = (int)copy.NextInt(6);
                    } while (ivs[index] != UNSET);
                    ivs[index] = MAX;
                }

                for (var i = 0; i < ivs.Length; i++)
                {
                    if (ivs[i] == UNSET)
                    {
                        ivs[i] = (int)copy.NextInt(31 + 1);
                    }
                }

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

                if (pk is not IScaledSize s)
                {
                    continue;
                }
                var height = (int)copy.NextInt(0x81) + (int)copy.NextInt(0x80);
                if (s.HeightScalar != height)
                {
                    continue;
                }
                var weight = (int)copy.NextInt(0x81) + (int)copy.NextInt(0x80);
                if (s.WeightScalar != weight)
                {
                    continue;
                }

                return(iv_count);
            }
            return(NoMatchIVs);
        }
Пример #5
0
 public bool Equals(Xoroshiro128Plus obj) => obj.s0 == s0 && obj.s1 == s1;