Ejemplo n.º 1
0
        private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed)
        {
            var rng            = RNG.LCRNG;
            var A              = rng.Next(seed);
            var B              = rng.Next(A);
            var skipBetweenPID = type is PIDType.Method_3 or PIDType.Method_3_Unown;

            if (skipBetweenPID) // VBlank skip between PID rand() [RARE]
            {
                B = rng.Next(B);
            }

            var swappedPIDHalves = type is >= PIDType.Method_1_Unown and <= PIDType.Method_4_Unown;

            if (swappedPIDHalves) // switched order of PID halves, "BA.."
            {
                pk.PID = (A & 0xFFFF0000) | B >> 16;
            }
            else
            {
                pk.PID = (B & 0xFFFF0000) | A >> 16;
            }

            var C            = rng.Next(B);
            var skipIV1Frame = type is PIDType.Method_2 or PIDType.Method_2_Unown;

            if (skipIV1Frame) // VBlank skip after PID
            {
                C = rng.Next(C);
            }

            var D            = rng.Next(C);
            var skipIV2Frame = type is PIDType.Method_4 or PIDType.Method_4_Unown;

            if (skipIV2Frame) // VBlank skip between IVs
            {
                D = rng.Next(D);
            }

            Span <int> IVs = stackalloc int[6];

            MethodFinder.GetIVsInt32(IVs, C >> 16, D >> 16);
            if (type == PIDType.Method_1_Roamer)
            {
                // Only store lowest 8 bits of IV data; zero out the other bits.
                IVs[1] &= 7;
                for (int i = 2; i < 6; i++)
                {
                    IVs[i] = 0;
                }
            }
            pk.SetIVs(IVs);
        }
Ejemplo n.º 2
0
        public static IEnumerable <IEncounterable> GetEncounters(PKM pkm, LegalInfo info)
        {
            info.PIDIV = MethodFinder.Analyze(pkm);
            var deferredPIDIV = new List <IEncounterable>();
            var deferredEType = new List <IEncounterable>();

            foreach (var z in GenerateRawEncounters4(pkm, info))
            {
                if (!info.PIDIV.Type.IsCompatible4(z, pkm))
                {
                    deferredPIDIV.Add(z);
                }
                else if (pkm is IGroundTile e && !(z is IGroundTypeTile t ? t.GroundTile.Contains(e.GroundTile) : e.GroundTile == 0))
                {
                    deferredEType.Add(z);
                }
Ejemplo n.º 3
0
        private string GetVerboseLegalityReport()
        {
            if (!Parsed)
                return V189;

            const string separator = "===";
            string[] br = {separator, ""};
            var lines = new List<string> {br[1]};
            lines.AddRange(br);
            int rl = lines.Count;

            var vMoves = Info.Moves;
            var vRelearn = Info.Relearn;
            for (int i = 0; i < 4; i++)
                if (vMoves[i].Valid)
                    lines.Add(string.Format(V191, vMoves[i].Judgement.Description(), i + 1, vMoves[i].Comment));

            if (pkm.Format >= 6)
            for (int i = 0; i < 4; i++)
                if (vRelearn[i].Valid)
                    lines.Add(string.Format(V192, vRelearn[i].Judgement.Description(), i + 1, vRelearn[i].Comment));

            if (rl != lines.Count) // move info added, break for next section
                lines.Add(br[1]);
            
            var outputLines = Parse.Where(chk => chk != null && chk.Valid && chk.Comment != V).OrderBy(chk => chk.Judgement); // Fishy sorted to top
            lines.AddRange(outputLines.Select(chk => string.Format(V196, chk.Judgement.Description(), chk.Comment)));

            lines.AddRange(br);
            lines.Add(string.Format(V195, EncounterName));
            var pidiv = Info.PIDIV ?? MethodFinder.Analyze(pkm);
            if (pidiv != null)
            {
                if (!pidiv.NoSeed)
                    lines.Add(string.Format(V248, pidiv.OriginSeed.ToString("X8")));
                lines.Add(string.Format(V249, pidiv.Type));
            }
            if (!Valid && Info.InvalidMatches != null)
            {
                lines.Add("Other match(es):");
                lines.AddRange(Info.InvalidMatches.Select(z => $"{z.Name}: {z.Reason}"));
            }
            
            return GetLegalityReport() + string.Join(Environment.NewLine, lines);
        }
Ejemplo n.º 4
0
        private static IEnumerable <IEncounterable> GetEncounters3(PKM pkm, LegalInfo info)
        {
            info.PIDIV = MethodFinder.Analyze(pkm);
            var deferred = new List <IEncounterable>();

            foreach (var z in GenerateRawEncounters3(pkm, info))
            {
                if (pkm.Version == (int)GameVersion.CXD) // C/XD
                {
                    if (z is EncounterSlot w)
                    {
                        var seeds = MethodFinder.GetPokeSpotSeeds(pkm, w.SlotNumber).FirstOrDefault();
                        info.PIDIV = seeds ?? info.PIDIV;
                    }
                    else if (z is EncounterStaticShadow s)
                    {
                        bool valid = GetIsShadowLockValid(pkm, info, s);
                        if (!valid)
                        {
                            deferred.Add(s);
                            continue;
                        }
                    }
                }
                if (info.PIDIV.Type.IsCompatible3(z, pkm))
                {
                    yield return(z);
                }
                else
                {
                    deferred.Add(z);
                }
            }
            if (deferred.Count == 0)
            {
                yield break;
            }

            info.PIDIVMatches = false;
            foreach (var z in deferred)
            {
                yield return(z);
            }
        }
Ejemplo n.º 5
0
        private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed)
        {
            var rng = RNG.LCRNG;
            var A   = rng.Next(seed);
            var B   = rng.Next(A);
            var pid = (B & 0xFFFF0000) | A >> 16;

            if (type == PIDType.Method_1_Unown || type == PIDType.Method_2_Unown || type == PIDType.Method_4_Unown)
            {
                pk.PID = (pid >> 16) | (pid << 16); // swap halves
            }
            else
            {
                pk.PID = pid;
            }

            var skipIV1Frame = type == PIDType.Method_2 || type == PIDType.Method_2_Unown;

            if (skipIV1Frame)
            {
                B = rng.Next(B);
            }
            var C = rng.Next(B);
            var D = rng.Next(C);

            var skipIV2Frame = type == PIDType.Method_4 || type == PIDType.Method_4_Unown;

            if (skipIV2Frame)
            {
                D = rng.Next(D);
            }

            var IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16);

            if (type == PIDType.Method_1_Roamer)
            {
                IVs[1] &= 7;
                for (int i = 2; i < 6; i++)
                {
                    IVs[i] = 0;
                }
            }
            pk.IVs = IVs;
        }
Ejemplo n.º 6
0
        private static IEnumerable <IEncounterable> GetEncounters3CXD(PKM pkm, LegalInfo info)
        {
            info.PIDIV = MethodFinder.Analyze(pkm);
            IEncounterable?Partial = null;

            foreach (var z in GenerateRawEncounters3CXD(pkm))
            {
                if (z is EncounterSlot3PokeSpot w)
                {
                    var seeds = MethodFinder.GetPokeSpotSeeds(pkm, w.SlotNumber);
                    foreach (var s in seeds)
                    {
                        info.PIDIV = s;
                        break;
                    }
                }
                else if (z is EncounterStaticShadow s)
                {
                    bool valid = GetIsShadowLockValid(pkm, info, s);
                    if (!valid)
                    {
                        Partial ??= s;
                        continue;
                    }
                }

                if (info.PIDIV.Type.IsCompatible3(z, pkm))
                {
                    yield return(z);
                }
                else
                {
                    Partial ??= z;
                }
            }
            if (Partial == null)
            {
                yield break;
            }

            info.PIDIVMatches = false;
            yield return(Partial);
        }
Ejemplo n.º 7
0
        private static void VerifyFatefulMysteryGift(LegalityAnalysis data, MysteryGift g)
        {
            var pkm = data.pkm;

            if (g is PGF p && p.IsShiny)
            {
                var Info = data.Info;
                Info.PIDIV = MethodFinder.Analyze(pkm);
                if (Info.PIDIV.Type != PIDType.G5MGShiny && pkm.Egg_Location != 30003)
                {
                    data.AddLine(GetInvalid(LPIDTypeMismatch, CheckIdentifier.PID));
                }
            }

            var result = pkm.FatefulEncounter
                ? GetValid(LFatefulMystery, CheckIdentifier.Fateful)
                : GetInvalid(LFatefulMysteryMissing, CheckIdentifier.Fateful);

            data.AddLine(result);
        }
Ejemplo n.º 8
0
        public static void SetRandomChainShinyPID(PKM pk, uint seed)
        {
            // 13 rand bits
            // 1 3-bit for upper
            // 1 3-bit for lower

            uint Next() => (seed = RNG.LCRNG.Next(seed)) >> 16;

            uint lower = Next() & 7;
            uint upper = Next() & 7;

            for (int i = 0; i < 13; i++)
            {
                lower |= (Next() & 1) << (3 + i);
            }

            upper  = ((uint)(lower ^ pk.TID ^ pk.SID) & 0xFFF8) | (upper & 0x7);
            pk.PID = upper << 16 | lower;
            pk.IVs = MethodFinder.GetIVsInt32(Next(), Next());
        }
Ejemplo n.º 9
0
        private static IEnumerable <IEncounterable> GetEncounters3(PKM pkm, LegalInfo info)
        {
            info.PIDIV = MethodFinder.Analyze(pkm);
            var deferred = new List <IEncounterable>();

            foreach (var z in GenerateRawEncounters3(pkm, info))
            {
                if (pkm.Version == 15)
                {
                    if (z is EncounterSlot w)
                    {
                        var seeds = MethodFinder.GetPokeSpotSeeds(pkm, w.SlotNumber).FirstOrDefault();
                        info.PIDIV = seeds ?? info.PIDIV;
                    }
                    else if (ParseSettings.FlagCXDShadowFirstLockMismatch &&
                             z is EncounterStaticShadow s && !LockFinder.IsFirstShadowLockValid(s, info.PIDIV))
                    {
                        deferred.Add(s);
                        continue;
                    }
                }
                if (info.PIDIV.Type.IsCompatible3(z, pkm))
                {
                    yield return(z);
                }
                else
                {
                    deferred.Add(z);
                }
            }
            if (deferred.Count == 0)
            {
                yield break;
            }

            info.PIDIVMatches = false;
            foreach (var z in deferred)
            {
                yield return(z);
            }
        }
Ejemplo n.º 10
0
        private static bool GetIsShadowLockValid(PKM pkm, LegalInfo info, EncounterStaticShadow s)
        {
            if (s.IVs.Count == 0) // not E-Reader
            {
                return(LockFinder.IsAllShadowLockValid(s, info.PIDIV, pkm));
            }

            // E-Reader have fixed IVs, and aren't recognized as CXD (no PID-IV correlation).
            var possible = MethodFinder.GetColoEReaderMatches(pkm.EncryptionConstant);

            foreach (var poss in possible)
            {
                if (!LockFinder.IsAllShadowLockValid(s, poss, pkm))
                {
                    continue;
                }
                info.PIDIV = poss;
                return(true);
            }

            return(false);
        }
Ejemplo n.º 11
0
        private static IEnumerable <IEncounterable> GetEncounters4(PKM pkm, LegalInfo info)
        {
            info.PIDIV = MethodFinder.Analyze(pkm);
            var deferredPIDIV = new List <IEncounterable>();
            var deferredEType = new List <IEncounterable>();

            foreach (var z in GenerateRawEncounters4(pkm, info))
            {
                if (!info.PIDIV.Type.IsCompatible4(z, pkm))
                {
                    deferredPIDIV.Add(z);
                }
                else if (pkm.Format <= 6 && !IsEncounterTypeMatch(z, pkm.EncounterType))
                {
                    deferredEType.Add(z);
                }
                else
                {
                    yield return(z);
                }
            }

            foreach (var z in deferredEType)
            {
                yield return(z);
            }

            if (deferredPIDIV.Count == 0)
            {
                yield break;
            }

            info.PIDIVMatches = false;
            foreach (var z in deferredPIDIV)
            {
                yield return(z);
            }
        }
Ejemplo n.º 12
0
        private void VerifyFatefulMysteryGift(LegalityAnalysis data, MysteryGift g)
        {
            var pkm = data.pkm;

            if (g is PGF p && p.IsShiny)
            {
                var Info = data.Info;
                Info.PIDIV = MethodFinder.Analyze(pkm);
                if (Info.PIDIV.Type != PIDType.G5MGShiny && pkm.Egg_Location != 30003)
                {
                    data.AddLine(GetInvalid(V411, CheckIdentifier.PID));
                }
            }

            if (pkm.FatefulEncounter)
            {
                data.AddLine(GetValid(V321, CheckIdentifier.Fateful));
            }
            else
            {
                data.AddLine(GetInvalid(V322, CheckIdentifier.Fateful));
            }
        }
Ejemplo n.º 13
0
        private static void SetValuesFromSeedBACD(PKM pk, PIDType type, uint seed)
        {
            var  rng   = RNG.LCRNG;
            bool shiny = type == PIDType.BACD_R_S || type == PIDType.BACD_U_S;
            uint X     = shiny ? rng.Next(seed) : seed;
            var  A     = rng.Next(X);
            var  B     = rng.Next(A);
            var  C     = rng.Next(B);
            var  D     = rng.Next(C);

            if (shiny)
            {
                uint PID = (X & 0xFFFF0000) | ((uint)pk.SID ^ (uint)pk.TID ^ X >> 16);
                PID &= 0xFFFFFFF8;
                PID |= B >> 16 & 0x7; // lowest 3 bits

                pk.PID = PID;
            }
            else if (type == PIDType.BACD_R_AX || type == PIDType.BACD_U_AX)
            {
                uint low = B >> 16;
                pk.PID = ((A & 0xFFFF0000) ^ (((uint)pk.TID ^ (uint)pk.SID ^ low) << 16)) | low;
            }
            else
            {
                pk.PID = (A & 0xFFFF0000) | B >> 16;
            }

            pk.IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16);

            bool antishiny = type == PIDType.BACD_R_A || type == PIDType.BACD_U_A;

            while (antishiny && pk.IsShiny)
            {
                pk.PID = unchecked (pk.PID + 1);
            }
        }
Ejemplo n.º 14
0
        public static void SetRandomPokeSpotPID(PKM pk, int nature, int gender, int ability, int slot)
        {
            while (true)
            {
                var seed = Util.Rand32();
                if (!MethodFinder.IsPokeSpotActivation(slot, seed, out var _))
                {
                    continue;
                }

                var rng = RNG.XDRNG;
                var D   = rng.Next(seed); // PID
                var E   = rng.Next(D);    // PID

                pk.PID = (D & 0xFFFF0000) | E >> 16;
                if (!IsValidCriteria4(pk, nature, ability, gender))
                {
                    continue;
                }

                pk.SetRandomIVs();
                return;
            }
        }
Ejemplo n.º 15
0
        private static IEnumerable <IEncounterable> GetEncounters3(PKM pkm, LegalInfo info)
        {
            info.PIDIV = MethodFinder.Analyze(pkm);
            IEncounterable?Partial = null;

            foreach (var z in GenerateRawEncounters3(pkm, info))
            {
                if (info.PIDIV.Type.IsCompatible3(z, pkm))
                {
                    yield return(z);
                }
                else
                {
                    Partial ??= z;
                }
            }
            if (Partial == null)
            {
                yield break;
            }

            info.PIDIVMatches = false;
            yield return(Partial);
        }
Ejemplo n.º 16
0
        private string GetVerboseLegalityReport()
        {
            if (!Parsed || Info == null)
            {
                return(L_AnalysisUnavailable);
            }

            const string separator = "===";

            string[] br    = { separator, string.Empty };
            var      lines = new List <string> {
                br[1]
            };

            lines.AddRange(br);
            int rl = lines.Count;

            var vMoves   = Info.Moves;
            var vRelearn = Info.Relearn;

            for (int i = 0; i < 4; i++)
            {
                var move = vMoves[i];
                if (!move.Valid)
                {
                    continue;
                }
                var msg = string.Format(L_F0_M_1_2, move.Rating, i + 1, move.Comment);
                if (pkm.Format != move.Generation)
                {
                    msg += $" [Gen{move.Generation}]";
                }
                lines.Add(msg);
            }

            if (pkm.Format >= 6)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (vRelearn[i].Valid)
                    {
                        lines.Add(string.Format(L_F0_RM_1_2, vRelearn[i].Rating, i + 1, vRelearn[i].Comment));
                    }
                }
            }

            if (rl != lines.Count) // move info added, break for next section
            {
                lines.Add(br[1]);
            }

            var outputLines = Parse.Where(chk => chk?.Valid == true && chk.Comment != L_AValid).OrderBy(chk => chk.Judgement); // Fishy sorted to top

            lines.AddRange(outputLines.Select(chk => string.Format(L_F0_1, chk.Rating, chk.Comment)));

            lines.AddRange(br);
            lines.Add(string.Format(L_FEncounterType_0, EncounterName));
            var loc = EncounterLocation;

            if (!string.IsNullOrEmpty(loc))
            {
                lines.Add(string.Format(L_F0_1, "Location", loc));
            }
            if (pkm.VC)
            {
                lines.Add(string.Format(L_F0_1, nameof(GameVersion), Info.Game));
            }
            var pidiv = Info.PIDIV ?? MethodFinder.Analyze(pkm);

            if (pidiv != null)
            {
                if (!pidiv.NoSeed)
                {
                    lines.Add(string.Format(L_FOriginSeed_0, pidiv.OriginSeed.ToString("X8")));
                }
                lines.Add(string.Format(L_FPIDType_0, pidiv.Type));
            }
            if (!Valid && Info.InvalidMatches != null)
            {
                lines.Add("Other match(es):");
                lines.AddRange(Info.InvalidMatches.Select(z => $"{z.LongName}: {z.Reason}"));
            }

            return(GetLegalityReport() + string.Join(Environment.NewLine, lines));
        }
Ejemplo n.º 17
0
        private static IEnumerable <IEncounterable> GetEncounters3(PKM pkm, LegalInfo info)
        {
            info.PIDIV = MethodFinder.Analyze(pkm);
            var deferred = new List <IEncounterable>();

            foreach (var z in GenerateRawEncounters3(pkm, info))
            {
                if (pkm.Version == (int)GameVersion.CXD) // C/XD
                {
                    if (z is EncounterSlot w)
                    {
                        var seeds = MethodFinder.GetPokeSpotSeeds(pkm, w.SlotNumber).FirstOrDefault();
                        info.PIDIV = seeds ?? info.PIDIV;
                    }
                    else if (z is EncounterStaticShadow s)
                    {
                        bool valid = false;
                        if (s.IVs == null) // not ereader
                        {
                            valid = LockFinder.IsAllShadowLockValid(s, info.PIDIV, pkm);
                        }
                        else
                        {
                            var possible = MethodFinder.GetColoEReaderMatches(pkm.EncryptionConstant);
                            foreach (var poss in possible)
                            {
                                if (!LockFinder.IsAllShadowLockValid(s, poss, pkm))
                                {
                                    continue;
                                }
                                valid      = true;
                                info.PIDIV = poss;
                                break;
                            }
                        }

                        if (!valid)
                        {
                            deferred.Add(s);
                            continue;
                        }
                    }
                }
                if (info.PIDIV.Type.IsCompatible3(z, pkm))
                {
                    yield return(z);
                }
                else
                {
                    deferred.Add(z);
                }
            }
            if (deferred.Count == 0)
            {
                yield break;
            }

            info.PIDIVMatches = false;
            foreach (var z in deferred)
            {
                yield return(z);
            }
        }
Ejemplo n.º 18
0
        private string GetVerboseLegalityReport()
        {
            if (!Parsed || Info == null)
            {
                return(V189);
            }

            const string separator = "===";

            string[] br    = { separator, "" };
            var      lines = new List <string> {
                br[1]
            };

            lines.AddRange(br);
            int rl = lines.Count;

            var vMoves   = Info.Moves;
            var vRelearn = Info.Relearn;

            for (int i = 0; i < 4; i++)
            {
                if (vMoves[i].Valid)
                {
                    lines.Add(string.Format(V191, vMoves[i].Rating, i + 1, vMoves[i].Comment));
                }
            }

            if (pkm.Format >= 6)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (vRelearn[i].Valid)
                    {
                        lines.Add(string.Format(V192, vRelearn[i].Rating, i + 1, vRelearn[i].Comment));
                    }
                }
            }

            if (rl != lines.Count) // move info added, break for next section
            {
                lines.Add(br[1]);
            }

            var outputLines = Parse.Where(chk => chk?.Valid == true && chk.Comment != V).OrderBy(chk => chk.Judgement); // Fishy sorted to top

            lines.AddRange(outputLines.Select(chk => string.Format(V196, chk.Rating, chk.Comment)));

            lines.AddRange(br);
            lines.Add(string.Format(V195, EncounterName));
            var loc = EncounterLocation;

            if (!string.IsNullOrEmpty(loc))
            {
                lines.Add(string.Format(V196, "Location", loc));
            }
            if (pkm.VC)
            {
                lines.Add(string.Format(V196, nameof(GameVersion), Info.Game));
            }
            var pidiv = Info.PIDIV ?? MethodFinder.Analyze(pkm);

            if (pidiv != null)
            {
                if (!pidiv.NoSeed)
                {
                    lines.Add(string.Format(V248, pidiv.OriginSeed.ToString("X8")));
                }
                lines.Add(string.Format(V249, pidiv.Type));
            }
            if (!Valid && Info.InvalidMatches != null)
            {
                lines.Add("Other match(es):");
                lines.AddRange(Info.InvalidMatches.Select(z => $"{z.Name}: {z.Reason}"));
            }

            return(GetLegalityReport() + string.Join(Environment.NewLine, lines));
        }