Revise dmax adv shiny PID generating to match game

This commit is contained in:
Kurt
2025-06-28 12:32:45 -05:00
parent 1258d96883
commit 3b4661d40d
3 changed files with 52 additions and 7 deletions

View File

@@ -24,13 +24,13 @@ public sealed record EncounterStatic8N : EncounterStatic8Nest<EncounterStatic8N>
public override byte LevelMin => LevelCaps[MinRank * 2];
public override byte LevelMax => LevelCaps[(MaxRank * 2) + 1];
public EncounterStatic8N(byte nestIndex, byte minRank, byte maxRank, byte val, [ConstantExpected] GameVersion game) : base(game)
public EncounterStatic8N(byte nestIndex, byte minRank, byte maxRank, byte flawless, [ConstantExpected] GameVersion game) : base(game)
{
NestIndex = nestIndex;
MinRank = minRank;
MaxRank = maxRank;
DynamaxLevel = (byte)(MinRank + 1u);
FlawlessIVCount = val;
FlawlessIVCount = flawless;
}
public static EncounterStatic8N Read(ReadOnlySpan<byte> data, [ConstantExpected] GameVersion game) => new(data[6], data[7], data[8], data[9], game)

View File

@@ -92,7 +92,7 @@ public PK8 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
protected virtual ushort GetLocation() => Location;
private void SetPINGA(PK8 pk, in EncounterCriteria criteria, PersonalInfo8SWSH pi)
protected virtual void SetPINGA(PK8 pk, in EncounterCriteria criteria, PersonalInfo8SWSH pi)
{
bool requestShiny = criteria.Shiny.IsShiny();
bool checkShiny = requestShiny && Shiny != Shiny.Never;
@@ -115,7 +115,10 @@ private void SetPINGA(PK8 pk, in EncounterCriteria criteria, PersonalInfo8SWSH p
if (ctr == max) // fail
{
if (!TryApply(pk, seed = rand.Next(), iv, param, criteria.WithoutIVs()))
while (!TryApply(pk, seed = rand.Next(), iv, param, EncounterCriteria.Unrestricted)) { }
{
var tmp = EncounterCriteria.Unrestricted;
while (!TryApply(pk, seed = rand.Next(), iv, param, tmp)) { }
}
}
FinishCorrelation(pk, seed);
@@ -125,7 +128,7 @@ private void SetPINGA(PK8 pk, in EncounterCriteria criteria, PersonalInfo8SWSH p
protected GenerateParam8 GetParam() => GetParam(Info);
protected GenerateParam8 GetParam(PersonalInfo8SWSH pi)
private GenerateParam8 GetParam(PersonalInfo8SWSH pi)
{
var ratio = RemapGenderToParam(Gender, pi);
return new GenerateParam8(Species, ratio, FlawlessIVCount, Ability, Shiny, Nature.Random, IVs);
@@ -271,7 +274,7 @@ protected virtual bool TryApply(PK8 pk, ulong seed, Span<int> iv, in GeneratePar
return RaidRNG.TryApply(pk, seed, iv, param, criteria);
}
private static byte RemapGenderToParam(byte gender, PersonalInfo8SWSH pi) => gender switch
protected static byte RemapGenderToParam(byte gender, PersonalInfo8SWSH pi) => gender switch
{
0 => PersonalInfo.RatioMagicMale,
1 => PersonalInfo.RatioMagicFemale,

View File

@@ -48,11 +48,53 @@ protected override void SetTrainerName(ReadOnlySpan<char> name, PK8 pk)
base.SetTrainerName(name, pk);
}
// These raids are always generated as Never-Shiny, and only at the choice screen are they possibly set shiny.
private const Shiny ShinyMethod = Shiny.Never;
private const byte ShinyXor = 1; // If forced shiny, the XOR is always 1.
// Need to override to ensure the fallback also uses Never-Shiny.
protected override void SetPINGA(PK8 pk, in EncounterCriteria criteria, PersonalInfo8SWSH pi)
{
Span<int> iv = stackalloc int[6];
int ctr = 0;
var rand = new Xoroshiro128Plus(Util.Rand.Rand64());
var param = GetParam(pi);
ulong seed;
const int max = 100_000;
do
{
if (TryApply(pk, seed = rand.Next(), iv, param, criteria))
break;
} while (++ctr < max);
if (ctr == max) // fail
{
if (!TryApply(pk, seed = rand.Next(), iv, param, criteria.WithoutIVs()))
{
var tmp = EncounterCriteria.Unrestricted with { Shiny = ShinyMethod };
while (!TryApply(pk, seed = rand.Next(), iv, param, tmp)) { }
}
}
FinishCorrelation(pk, seed);
if (criteria.IsSpecifiedNature() && criteria.Nature != pk.Nature && criteria.Nature.IsMint())
pk.StatNature = criteria.Nature;
if (criteria.Shiny.IsShiny())
pk.PID = ShinyUtil.GetShinyPID(pk.TID16, pk.SID16, pk.PID, ShinyXor);
}
private GenerateParam8 GetParam(PersonalInfo8SWSH pi)
{
var ratio = RemapGenderToParam(Gender, pi);
return new GenerateParam8(Species, ratio, FlawlessIVCount, Ability, ShinyMethod, Nature.Random, IVs);
}
// no downleveling, unlike all other raids
protected override bool IsMatchLevel(PKM pk) => pk.MetLevel == Level;
protected override bool IsMatchLocation(PKM pk) => Location == pk.MetLocation;
public bool IsShinyXorValid(ushort pkShinyXor) => pkShinyXor is > 15 or 1;
public bool IsShinyXorValid(ushort pkShinyXor) => pkShinyXor is > 15 or ShinyXor; // not shiny, or shiny with XOR=1
public bool ShouldHaveScientistTrash => Level != 70; // Level 65, not legendary/sub-legendary/ultra beast