mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-22 03:53:08 +00:00
Fix gen3 reversal exploration for 50% of seeds
line 340 - variable reuse!
In looking at the emerald disassembly, when Pressure/Hustle/Vital Spirit fails, it reduces the max level of the slot by 1 so that the max level doesn't randomly appear. Essentially 50% flat for the max to appear, for varied slots, not 50% + (1/range). Thus we require a separate branch of logic to check for this scenario.
f8119bedd4/src/wild_encounter.c (L298)
DPPt (and assumedly HGSS) do not decrease the random range on failure.
ty TFS for bringing this to my attention on discord
This commit is contained in:
parent
d1a51797c7
commit
de57e197ad
1 changed files with 36 additions and 3 deletions
|
@ -337,9 +337,9 @@ public static class MethodH
|
|||
if (syncProc)
|
||||
{
|
||||
var ctx = new FrameCheckDetails<T>(enc, seed, levelMin, levelMax, format);
|
||||
if (IsSlotValidRegular(ctx, out seed))
|
||||
if (IsSlotValidRegular(ctx, out var regular))
|
||||
{
|
||||
result = new(seed, Synchronize);
|
||||
result = new(regular, Synchronize);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +421,9 @@ public static class MethodH
|
|||
if (IsHustleVitalPass(ctx.Prev1)) // should have triggered
|
||||
{ result = default; return false; }
|
||||
|
||||
return IsSlotValidFrom1Skip(ctx, out result);
|
||||
// When it fails, level range is reduced by 1 so that it is not the maximum level, if possible.
|
||||
|
||||
return IsSlotValidFrom1SkipMinus1(ctx, out result);
|
||||
}
|
||||
|
||||
private static bool TryGetMatchNoSync<T>(in FrameCheckDetails<T> ctx, out LeadSeed result)
|
||||
|
@ -467,6 +469,21 @@ public static class MethodH
|
|||
result = default; return false;
|
||||
}
|
||||
|
||||
private static bool IsSlotValidFrom1SkipMinus1<T>(FrameCheckDetails<T> ctx, out uint result)
|
||||
where T : IEncounterSlot3
|
||||
{
|
||||
// -3 ESV
|
||||
// -2 Level (range biased down by 1)
|
||||
// -1 (Proc Already Checked)
|
||||
// 0 Nature
|
||||
if (IsLevelValidMinus1(ctx.Encounter, ctx.LevelMin, ctx.LevelMax, ctx.Format, ctx.Prev2))
|
||||
{
|
||||
if (IsSlotValid(ctx.Encounter, ctx.Prev3))
|
||||
{ result = ctx.Seed4; return true; }
|
||||
}
|
||||
result = default; return false;
|
||||
}
|
||||
|
||||
private static bool IsSlotValidRegular<T>(in FrameCheckDetails<T> ctx, out uint result)
|
||||
where T : IEncounterSlot3
|
||||
{
|
||||
|
@ -571,6 +588,22 @@ public static class MethodH
|
|||
return (u16LevelRand % mod) + min;
|
||||
}
|
||||
|
||||
private static bool IsLevelValidMinus1<T>(T enc, byte min, byte max, byte format, uint u16LevelRand) where T : ILevelRange
|
||||
{
|
||||
var level = GetExpectedLevelMinus1(enc, u16LevelRand);
|
||||
return IsOriginalLevelValid(min, max, format, level);
|
||||
}
|
||||
|
||||
private static uint GetExpectedLevelMinus1<T>(T enc, uint u16LevelRand) where T : ILevelRange
|
||||
{
|
||||
var min = enc.LevelMin;
|
||||
uint mod = 1u + enc.LevelMax - min;
|
||||
var bias = (u16LevelRand % mod);
|
||||
if (bias != 0)
|
||||
bias--;
|
||||
return min + bias;
|
||||
}
|
||||
|
||||
private static bool IsRockSmashPossible(byte areaRate, ref uint seed)
|
||||
{
|
||||
if (IsRatePass(seed, areaRate, None)) // Lead doesn't matter, doesn't influence.
|
||||
|
|
Loading…
Reference in a new issue