Make PIDIV a readonly struct

Add tests to ensure the optimization remains in effect later
This commit is contained in:
Kurt 2021-08-21 18:24:38 -07:00
parent 65c5890e1f
commit 92d1666970
5 changed files with 48 additions and 20 deletions

View File

@ -46,8 +46,12 @@ private static IEnumerable<IEncounterable> GetEncounters3CXD(PKM pkm, LegalInfo
{
if (z is EncounterSlot3PokeSpot w)
{
var seeds = MethodFinder.GetPokeSpotSeeds(pkm, w.SlotNumber).FirstOrDefault();
info.PIDIV = seeds ?? info.PIDIV;
var seeds = MethodFinder.GetPokeSpotSeeds(pkm, w.SlotNumber);
foreach (var s in seeds)
{
info.PIDIV = s;
break;
}
}
else if (z is EncounterStaticShadow s)
{

View File

@ -5,14 +5,15 @@ namespace PKHeX.Core
/// </summary>
public readonly struct NPCLock
{
public readonly short Species;
public readonly byte Nature;
public readonly byte Gender;
public readonly byte Ratio;
public readonly bool Shadow;
public readonly bool Seen;
private readonly int Species;
private readonly byte Nature;
private readonly byte Gender;
private readonly byte Ratio;
private readonly byte State;
public int FramesConsumed => Seen ? 5 : 7;
public bool Seen => State > 1;
public bool Shadow => State != 0;
// Not-Shadow
public NPCLock(short s, byte n, byte g, byte r)
@ -21,8 +22,7 @@ public NPCLock(short s, byte n, byte g, byte r)
Nature = n;
Gender = g;
Ratio = r;
Shadow = false;
Seen = false;
State = 0;
}
// Shadow
@ -32,13 +32,12 @@ public NPCLock(short s, bool seen = false)
Nature = 0;
Gender = 0;
Ratio = 0;
Shadow = true;
Seen = seen;
State = seen ? (byte)2 : (byte)1;
}
public bool MatchesLock(uint PID)
{
if (Shadow)
if (Shadow && Nature == 0) // Non-locked shadow
return true;
if (Gender != 2 && Gender != ((PID & 0xFF) < Ratio ? 1 : 0))
return false;
@ -57,7 +56,7 @@ public override string ToString()
{
var sb = new System.Text.StringBuilder(64);
sb.Append((Species)Species);
if (Shadow)
if (State != 0)
sb.Append(" (Shadow)");
if (Seen)
sb.Append(" [Seen]");

View File

@ -352,7 +352,14 @@ private static PIDType GetPIDType(PKM pk, PIDType specific)
if (pk.Version == 15)
return PIDType.CXD;
if (pk.Gen3 && pk.Species == (int)Species.Unown)
return PIDType.Method_1_Unown + Util.Rand.Next(3);
{
return Util.Rand.Next(3) switch
{
1 => PIDType.Method_2_Unown,
2 => PIDType.Method_4_Unown,
_ => PIDType.Method_1_Unown,
};
}
return PIDType.Method_1;
}

View File

@ -3,7 +3,7 @@
/// <summary>
/// Stores details about a <see cref="PKM.EncryptionConstant"/> (PID) and any associated details being traced to a known correlation.
/// </summary>
public sealed record PIDIV
public readonly struct PIDIV
{
internal static readonly PIDIV None = new();
internal static readonly PIDIV CuteCharm = new(PIDType.CuteCharm);
@ -15,14 +15,14 @@ public sealed record PIDIV
/// <summary> Indicates that there is no <see cref="OriginSeed"/> to refer to. </summary>
/// <remarks> Some PIDIVs may be generated without a single seed, but may follow a traceable pattern. </remarks>
public readonly bool NoSeed;
public bool NoSeed => Type is PIDType.None or PIDType.CuteCharm or PIDType.Pokewalker or PIDType.G5MGShiny;
/// <summary> Type of PIDIV correlation </summary>
public readonly PIDType Type;
private PIDIV(PIDType type = PIDType.None)
private PIDIV(PIDType type)
{
NoSeed = true;
OriginSeed = 0;
Type = type;
}
@ -31,5 +31,15 @@ public PIDIV(PIDType type, uint seed)
OriginSeed = seed;
Type = type;
}
public bool Equals(PIDIV pid) => pid.Type == Type && pid.OriginSeed == OriginSeed;
public override bool Equals(object pid) => pid is PIDIV p && Equals(p);
public override int GetHashCode() => 0;
public static bool operator ==(PIDIV left, PIDIV right) => left.Equals(right);
public static bool operator !=(PIDIV left, PIDIV right) => !(left == right);
#if DEBUG
public override string ToString() => NoSeed ? Type.ToString() : $"{Type} - 0x{OriginSeed:X8}";
#endif
}
}

View File

@ -1,4 +1,5 @@
using FluentAssertions;
using System.Runtime.InteropServices;
using FluentAssertions;
using PKHeX.Core;
using Xunit;
@ -17,5 +18,12 @@ public void MarshalClass()
{
new Swarm3().ToBytesClass().Length.Should().Be(Swarm3.SIZE);
}
[Fact]
public void MarshalSize()
{
Marshal.SizeOf(typeof(NPCLock)).Should().Be(8);
Marshal.SizeOf(typeof(PIDIV)).Should().Be(8);
}
}
}