Пример #1
0
    private static bool GetIsHeightWeightMatch(PKM pk, Xoroshiro128Plus8b xoro)
    {
        // Check height/weight
        if (pk is not IScaledSize s)
        {
            return(false);
        }

        var height = xoro.NextUInt(0x81) + xoro.NextUInt(0x80);
        var weight = xoro.NextUInt(0x81) + xoro.NextUInt(0x80);

        return(s.HeightScalar == height && s.WeightScalar == weight);
    }
Пример #2
0
    private static bool GetIsMatchEndWithCuteCharm(PKM pk, Xoroshiro128Plus8b xoro)
    {
        // Check that gender matches
        // Assume that the gender is a match due to cute charm.

        // Check that the nature matches
        if (pk.Nature != (int)xoro.NextUInt(25))
        {
            return(false);
        }

        return(GetIsHeightWeightMatch(pk, xoro));
    }
Пример #3
0
    private static int GetFramesForward(ulong s0, ulong s1, ulong n0, ulong n1, int loop)
    {
        var rand = new Xoroshiro128Plus8b(s0, s1);

        for (int i = 0; i < loop; i++)
        {
            _ = rand.Next();
            if (rand.GetState() == (n0, n1))
            {
                return(i);
            }
        }
        return(-1);
    }
Пример #4
0
    private static bool GetIsMatchEnd(PKM pk, Xoroshiro128Plus8b xoro)
    {
        // Check that gender matches
        var genderRatio = PersonalTable.BDSP.GetFormEntry(pk.Species, pk.Form).Gender;

        if (genderRatio == PersonalInfo.RatioMagicGenderless)
        {
            if (pk.Gender != (int)Gender.Genderless)
            {
                return(false);
            }
        }
        else if (genderRatio == PersonalInfo.RatioMagicMale)
        {
            if (pk.Gender != (int)Gender.Male)
            {
                return(false);
            }
        }
        else if (genderRatio == PersonalInfo.RatioMagicFemale)
        {
            if (pk.Gender != (int)Gender.Female)
            {
                return(false);
            }
        }
        else
        {
            if (pk.Gender != (((int)xoro.NextUInt(253) + 1 < genderRatio) ? 1 : 0))
            {
                return(false);
            }
        }

        // Check that the nature matches
        if (pk.Nature != (int)xoro.NextUInt(25))
        {
            return(false);
        }

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

        // Encryption Constant
        pk.EncryptionConstant = seed;

        // PID
        var fakeTID = xoro.NextUInt(); // fakeTID
        var pid     = xoro.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)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(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
        pk.SetAbilityIndex((int)xoro.NextUInt(2));

        // Remainder
        var scale = (IScaledSize)pk;

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

        return(true);
    }
Пример #6
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));
    }