mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-03-21 17:48:28 -05:00
Gen4: Add Mic Test possible IV seeds
This commit is contained in:
parent
a437fecab8
commit
85cf53fe8e
|
|
@ -117,8 +117,10 @@ private static uint GetIV32(in EncounterCriteria criteria)
|
|||
if (criteria.IsSpecifiedIVsAll()) // Don't trust that the requirements are valid
|
||||
{
|
||||
criteria.GetCombinedIVs(out var iv1, out var iv2);
|
||||
var seed = PokewalkerRNG.GetLeastEffortSeed(iv1, iv2);
|
||||
if (seed.Type != PokewalkerSeedType.None)
|
||||
|
||||
// With Mic Test, any seed can be the seed that immediately generates the IVs.
|
||||
var ctr = LCRNGReversal.GetSeedsIVs(stackalloc uint[LCRNG.MaxCountSeedsIV], iv1, iv2);
|
||||
if (ctr != 0)
|
||||
return criteria.GetCombinedIVs();
|
||||
}
|
||||
PokewalkerRNG.GetRandomIVs(criteria, out var iv32);
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ private static string GetLinePokewalkerSeed(LegalInfo info, LegalityLocalization
|
|||
var pk = info.Entity;
|
||||
var result = PokewalkerRNG.GetLeastEffortSeed((uint)pk.IV_HP, (uint)pk.IV_ATK, (uint)pk.IV_DEF, (uint)pk.IV_SPA, (uint)pk.IV_SPD, (uint)pk.IV_SPE);
|
||||
var line = string.Format(strings.Encounter.Format, strings.Encounter.OriginSeed, result.Seed.ToString("X8"));
|
||||
line += $" [{result.Type} @ {result.PriorPoke}]";
|
||||
line += $" [{result.Type} @ {result.Count}]";
|
||||
return line;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,28 @@ public static PokewalkerSeedResult GetLeastEffortSeed(Span<uint> result, uint fi
|
|||
if (IsSeedFormatStroll(s)) // don't check species; can be disassociated from slots.
|
||||
return new(s, MaxPriorPokes, PokewalkerSeedType.Stroll); // decrement priorPoke back to 0-indexed
|
||||
}
|
||||
return default;
|
||||
|
||||
// Reset the seeds; recomputing doesn't take too much time since this is incredibly rare for a passing case.
|
||||
LCRNGReversal.GetSeedsIVs(result, first, second); // could just reverse all seeds n steps with a single *a+b, but this is clearer.
|
||||
return GetMicTest(result);
|
||||
}
|
||||
|
||||
private static PokewalkerSeedResult GetMicTest(Span<uint> result)
|
||||
{
|
||||
// Initiating a mic test can advance the seed from the initial NoStroll seed to any "initial" seed. Reverse to find a possible starting initial seed.
|
||||
uint ctr = 0;
|
||||
while (true)
|
||||
{
|
||||
foreach (ref var seed in result)
|
||||
{
|
||||
if (IsSeedFormatNoStroll(seed))
|
||||
return new(seed, ctr, PokewalkerSeedType.MicTestNoStroll);
|
||||
if (ctr != 0 && IsSeedFormatStroll(seed))
|
||||
return new(seed, (ctr - 1), PokewalkerSeedType.MicTestStroll);
|
||||
seed = LCRNG.Prev(seed);
|
||||
}
|
||||
ctr++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -341,10 +362,36 @@ private static bool TryApply(ref uint seed, out uint iv32, in EncounterCriteria
|
|||
/// <summary>
|
||||
/// Wrapper for Pokewalker Seed Results
|
||||
/// </summary>
|
||||
/// <param name="Seed">32-bit seed</param>
|
||||
/// <param name="PriorPoke">Count of Pokémon generated prior to the checked Pokémon. Maximum value: <see cref="PokewalkerRNG.MaxPriorPokes"/> (539)</param>
|
||||
/// <param name="Type">Type of seed</param>
|
||||
public readonly record struct PokewalkerSeedResult(uint Seed, ushort PriorPoke, PokewalkerSeedType Type);
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public readonly record struct PokewalkerSeedResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper for Pokewalker Seed Results
|
||||
/// </summary>
|
||||
public PokewalkerSeedResult(uint seed, uint value, PokewalkerSeedType type)
|
||||
{
|
||||
Seed = seed;
|
||||
Value = value;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
/// <summary>32-bit seed</summary>
|
||||
[field: FieldOffset(0)] public uint Seed { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Only the lower 24-bits are used.
|
||||
/// </summary>
|
||||
[field: FieldOffset(4)] private uint Value { get; }
|
||||
|
||||
/// <summary>Type of seed</summary>
|
||||
[field: FieldOffset(7)] public PokewalkerSeedType Type { get; }
|
||||
|
||||
/// <remarks>
|
||||
/// Mic Test: frames advanced from initial seed to the checked seed.
|
||||
/// Not Mic Test: Count of Pokémon generated prior to the checked Pokémon. Maximum value: <see cref="PokewalkerRNG.MaxPriorPokes"/> (539)
|
||||
/// </remarks>
|
||||
public uint Count => Value & 0x00_FFFFFF;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type of Pokewalker Seed
|
||||
|
|
@ -357,4 +404,8 @@ public enum PokewalkerSeedType : byte
|
|||
Stroll = 1,
|
||||
/// <summary> No Stroll Seed </summary>
|
||||
NoStroll = 2,
|
||||
/// <summary> Mic Test Stroll Seed </summary>
|
||||
MicTestStroll = 3,
|
||||
/// <summary> Mic Test No Stroll Seed </summary>
|
||||
MicTestNoStroll = 4,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ public void PokewalkerIVTest(uint hp, uint atk, uint def, uint spA, uint spD, ui
|
|||
{
|
||||
var result = PokewalkerRNG.GetLeastEffortSeed(hp, atk, def, spA, spD, spE);
|
||||
result.Type.Should().Be(type);
|
||||
result.PriorPoke.Should().Be(expect);
|
||||
result.Count.Should().Be(expect);
|
||||
result.Seed.Should().Be(seed);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user