예제 #1
0
        public List <DreamRadarFrame> Generate(ulong seed, Profile profile)
        {
            var frames = new List <DreamRadarFrame>();
            // Build the PIDRNG
            uint initialFrame = Functions.initialPIDRNG(seed, profile);
            var  pidrng       = new BWRng(seed);

            pidrng.Advance(initialFrame);

            // Build the MTRNG
            // todo: use fast MTRNG when available
            var ivrng = new MersenneTwister((uint)(seed >> 32));

            // advance 8 frames for BW2
            for (uint i = 0; i < 10; ++i)
            {
                ivrng.Next();
            }

            // one single advancement for entering the menu
            pidrng.GetNext64BitNumber();

            var spins = new List <DreamRadarFrame.Spin>();

            // initial advances
            for (uint i = 0; i < initialFrame; ++i)
            {
                Advance(pidrng, ivrng, spins);
            }

            // slot advances
            // we're always doing the slot 1 advance here
            pidrng.GetNext64BitNumber();

            for (uint i = 1; i < TargetSlot; ++i)
            {
                SlotAdvances(pidrng, ivrng);
            }

            for (uint i = initialFrame; i <= MaxFrame; ++i)
            {
                DreamRadarFrame frame = GeneratePokemon(pidrng, ivrng);

                var arrSpins = new DreamRadarFrame.Spin[spins.Count];
                spins.CopyTo(arrSpins);
                frame.Spins = arrSpins;

                // add checks/comparisons on the frame here
                // nature/IVs
                frames.Add(frame);
                Advance(pidrng, ivrng, spins);
            }

            return(frames);
        }
예제 #2
0
 private void Advance(BWRng pidrng, MersenneTwister ivrng, List <DreamRadarFrame.Spin> spins)
 {
     // first PIDRNG advance = spin
     spins.Add((DreamRadarFrame.Spin)pidrng.GetNext32BitNumber(8));
     pidrng.GetNext64BitNumber();
     ivrng.Next();
     ivrng.Next();
 }
예제 #3
0
 // todo: remove this
 private static void SlotAdvances(BWRng pidrng, MersenneTwister ivrng)
 {
     pidrng.GetNext64BitNumber();
     pidrng.GetNext64BitNumber();
     pidrng.GetNext64BitNumber();
     pidrng.GetNext64BitNumber();
     pidrng.GetNext64BitNumber();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
 }
예제 #4
0
        private DreamRadarFrame GeneratePokemon(BWRng pidrng2, MersenneTwister ivrng2)
        {
            var pidrng = new BWRng(pidrng2.Seed);
            var ivrng  = new MersenneTwister(ivrng2);
            var frame  = new DreamRadarFrame();

            frame.Pid = GeneratePID(pidrng);
            // two unknown advances
            pidrng.GetNext64BitNumber();
            pidrng.GetNext64BitNumber();
            frame.Nature = pidrng.GetNext32BitNumber(25);
            // IVs
            frame.Hp  = ivrng.Next() >> 27;
            frame.Atk = ivrng.Next() >> 27;
            frame.Def = ivrng.Next() >> 27;
            frame.Spa = ivrng.Next() >> 27;
            frame.Spd = ivrng.Next() >> 27;
            frame.Spe = ivrng.Next() >> 27;

            return(frame);
        }
        private uint[] FillRNGArray(uint startingFrame, ulong seed)
        {
            var rng = new BWRng(seed);

            for (uint i = 1; i < startingFrame; ++i)
            {
                rng.GetNext64BitNumber();
            }
            // max of 4 calls per hollow
            var rngArray = new uint[MaxAdvances + OpenHollows * 4];

            for (int i = 0; i < rngArray.Length; ++i)
            {
                rngArray[i] = rng.GetNext32BitNumber();
            }
            return(rngArray);
        }
        private void Search(DateTime date, uint vcountMin, uint vcountMax,
                            uint timer0Min, uint timer0Max, uint vframeMin, uint vframeMax, uint gxstatMin,
                            uint gxstatMax, bool minmaxgxstat, int secondsMin, int secondsMax, bool softreset,
                            Version version, Language language,
                            DSType dstype, bool memorylink, ulong macaddress, uint buttons, uint[] pattern)
        {
            var array = new uint[80];

            array[6] = (uint)(macaddress & 0xFFFF);
            if (softreset)
            {
                array[6] = array[6] ^ 0x01000000;
            }
            Array.Copy(Nazos.Nazo(version, language, dstype), array, 5);

            array[10] = 0x00000000;
            array[11] = 0x00000000;
            array[13] = 0x80000000;
            array[14] = 0x00000000;
            array[15] = 0x000001A0;

            array[12] = buttons;

            string yearMonth  = String.Format("{0:00}", date.Year % 2000) + String.Format("{0:00}", date.Month);
            string dateString = String.Format("{0:00}", (int)date.DayOfWeek);

            dateString = String.Format("{0:00}", date.Day) + dateString;
            dateString = yearMonth + dateString;
            array[8]   = uint.Parse(dateString, NumberStyles.HexNumber);
            array[9]   = 0x0;
            //uint[] alpha = Functions.alphaSHA1(array, 8);

            var upperMAC = (uint)(macaddress >> 16);

            for (uint vcount = vcountMin; vcount <= vcountMax; ++vcount)
            {
                for (uint timer0 = timer0Min; timer0 <= timer0Max; ++timer0)
                {
                    array[5] = (vcount << 16) + timer0;
                    array[5] = Functions.Reorder(array[5]);

                    for (uint vframe = vframeMin; vframe <= vframeMax; ++vframe)
                    {
                        for (uint gxstat = gxstatMin; gxstat <= gxstatMax; ++gxstat)
                        {
                            array[7] = (upperMAC ^ (vframe * 0x1000000) ^ gxstat);
                            uint[] alpha = Functions.alphaSHA1(array);

                            array[16] = Functions.RotateLeft(array[13] ^ array[8] ^ array[2] ^ array[0], 1);
                            array[18] = Functions.RotateLeft(array[15] ^ array[10] ^ array[4] ^ array[2], 1);
                            array[19] = Functions.RotateLeft(array[16] ^ array[11] ^ array[5] ^ array[3], 1);
                            array[21] = Functions.RotateLeft(array[18] ^ array[13] ^ array[7] ^ array[5], 1);
                            array[22] = Functions.RotateLeft(array[19] ^ array[14] ^ array[8] ^ array[6], 1);
                            array[24] = Functions.RotateLeft(array[21] ^ array[16] ^ array[10] ^ array[8], 1);
                            array[27] = Functions.RotateLeft(array[24] ^ array[19] ^ array[13] ^ array[11], 1);

                            for (int second = secondsMin; second <= secondsMax; ++second)
                            {
                                array[9] = Functions.seedSecond(second) | Functions.seedMinute(date.Minute) |
                                           Functions.seedHour(date.Hour, dstype);
                                ulong seed = Functions.EncryptSeed(array, alpha, 9);
                                // it appears to have the same initial seed as in the main game
                                // pressing Unova link does the same probability table calls
                                uint initial = Functions.initialPIDRNG(seed, version, memorylink);
                                var  rng     = new BWRng(seed);
                                for (uint i = 0; i < initial; ++i)
                                {
                                    rng.GetNext64BitNumber();
                                }
                                bool found = true;
                                for (uint i = 0; i < pattern.Length; ++i)
                                {
                                    if (pattern[i] != rng.GetNext32BitNumber(8))
                                    {
                                        found = false;
                                        break;
                                    }
                                    // there's another RNG call here unreleated to the spinner
                                    rng.GetNext64BitNumber();
                                }
                                progressSearched++;
                                if (found)
                                {
                                    var parameter = new DSParameterCapture
                                    {
                                        ActualSeconds = second,
                                        GxStat        = gxstat,
                                        Seed          = seed,
                                        Timer0        = timer0,
                                        VCount        = vcount,
                                        VFrame        = vframe
                                    };
                                    dsParameters.Add(parameter);
                                    refreshQueue = true;
                                    progressFound++;
                                }
                            }


                            if (minmaxgxstat && gxstatMax > gxstatMin)
                            {
                                gxstat = gxstatMax - 1;
                            }
                        }
                    }
                }
            }
        }
 private uint[] FillRNGArray(uint startingFrame, ulong seed)
 {
     var rng = new BWRng(seed);
     for (uint i = 1; i < startingFrame; ++i)
     {
         rng.GetNext64BitNumber();
     }
     // max of 4 calls per hollow
     var rngArray = new uint[MaxAdvances + OpenHollows*4];
     for (int i = 0; i < rngArray.Length; ++i)
     {
         rngArray[i] = rng.GetNext32BitNumber();
     }
     return rngArray;
 }
        private DreamRadarFrame GeneratePokemon(BWRng pidrng2, MersenneTwister ivrng2)
        {
            var pidrng = new BWRng(pidrng2.Seed);
            var ivrng = new MersenneTwister(ivrng2);
            var frame = new DreamRadarFrame();

            frame.Pid = GeneratePID(pidrng);
            // two unknown advances
            pidrng.GetNext64BitNumber();
            pidrng.GetNext64BitNumber();
            frame.Nature = pidrng.GetNext32BitNumber(25);
            // IVs
            frame.Hp = ivrng.Next() >> 27;
            frame.Atk = ivrng.Next() >> 27;
            frame.Def = ivrng.Next() >> 27;
            frame.Spa = ivrng.Next() >> 27;
            frame.Spd = ivrng.Next() >> 27;
            frame.Spe = ivrng.Next() >> 27;

            return frame;
        }
 private void Advance(BWRng pidrng, MersenneTwister ivrng, List<DreamRadarFrame.Spin> spins)
 {
     // first PIDRNG advance = spin
     spins.Add((DreamRadarFrame.Spin) pidrng.GetNext32BitNumber(8));
     pidrng.GetNext64BitNumber();
     ivrng.Next();
     ivrng.Next();
 }
예제 #10
0
 // todo: remove this
 private static void SlotAdvances(BWRng pidrng, MersenneTwister ivrng)
 {
     pidrng.GetNext64BitNumber();
     pidrng.GetNext64BitNumber();
     pidrng.GetNext64BitNumber();
     pidrng.GetNext64BitNumber();
     pidrng.GetNext64BitNumber();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
     ivrng.Next();
 }
예제 #11
0
        public List<DreamRadarFrame> Generate(ulong seed, Profile profile)
        {
            var frames = new List<DreamRadarFrame>();
            // Build the PIDRNG
            uint initialFrame = Functions.initialPIDRNG(seed, profile);
            var pidrng = new BWRng(seed);
            pidrng.Advance(initialFrame);

            // Build the MTRNG
            // todo: use fast MTRNG when available
            var ivrng = new MersenneTwister((uint) (seed >> 32));
            // advance 8 frames for BW2
            for (uint i = 0; i < 10; ++i) ivrng.Next();

            // one single advancement for entering the menu
            pidrng.GetNext64BitNumber();

            var spins = new List<DreamRadarFrame.Spin>();
            // initial advances
            for (uint i = 0; i < initialFrame; ++i) Advance(pidrng, ivrng, spins);

            // slot advances
            // we're always doing the slot 1 advance here
            pidrng.GetNext64BitNumber();

            for (uint i = 1; i < TargetSlot; ++i) SlotAdvances(pidrng, ivrng);

            for (uint i = initialFrame; i <= MaxFrame; ++i)
            {
                DreamRadarFrame frame = GeneratePokemon(pidrng, ivrng);

                var arrSpins = new DreamRadarFrame.Spin[spins.Count];
                spins.CopyTo(arrSpins);
                frame.Spins = arrSpins;

                // add checks/comparisons on the frame here
                // nature/IVs
                frames.Add(frame);
                Advance(pidrng, ivrng, spins);
            }

            return frames;
        }