mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-28 04:15:54 -05:00
Reduce allocation in methodfinder IV set
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
namespace PKHeX.Core
|
||||
using System;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public static class HiddenPowerApplicator
|
||||
{
|
||||
@@ -9,9 +11,10 @@ public static class HiddenPowerApplicator
|
||||
/// <param name="hiddenPowerType">Desired Hidden Power typing.</param>
|
||||
public static void SetHiddenPower(this PKM pk, int hiddenPowerType)
|
||||
{
|
||||
var IVs = pk.IVs;
|
||||
Span<int> IVs = stackalloc int[6];
|
||||
pk.GetIVs(IVs);
|
||||
HiddenPower.SetIVsForType(hiddenPowerType, IVs, pk.Format);
|
||||
pk.IVs = IVs;
|
||||
pk.SetIVs(IVs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -40,7 +40,9 @@ public static void SetMarkings(this PKM pk)
|
||||
if (pk.Format <= 3)
|
||||
return; // no markings (gen3 only has 4; can't mark stats intelligently
|
||||
|
||||
pk.SetMarkings(pk.IVs);
|
||||
Span<int> IVs = stackalloc int[6];
|
||||
pk.GetIVs(IVs);
|
||||
pk.SetMarkings(IVs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -174,7 +174,7 @@ public static void ApplySetDetails(this PKM pk, IBattleTemplate Set)
|
||||
pk.ApplyHeldItem(Set.HeldItem, Set.Format);
|
||||
pk.CurrentLevel = Set.Level;
|
||||
pk.CurrentFriendship = Set.Friendship;
|
||||
pk.IVs = Set.IVs;
|
||||
pk.SetIVs(Set.IVs);
|
||||
|
||||
if (pk is GBPKM gb)
|
||||
{
|
||||
|
||||
@@ -166,7 +166,7 @@ private void SetEncounterMoves(PKM pk, GameVersion version, int level)
|
||||
protected void SetIVs(PKM pk)
|
||||
{
|
||||
if (IVs.Count != 0)
|
||||
pk.SetRandomIVs(IVs, FlawlessIVCount);
|
||||
pk.SetRandomIVs((int[])IVs, FlawlessIVCount);
|
||||
else if (FlawlessIVCount > 0)
|
||||
pk.SetRandomIVs(flawless: FlawlessIVCount);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ protected virtual void SetPINGA(PKM pk, EncounterCriteria criteria)
|
||||
protected void SetIVs(PKM pk)
|
||||
{
|
||||
if (IVs.Count != 0)
|
||||
pk.SetRandomIVs(IVs, 0);
|
||||
pk.SetRandomIVs((int[])IVs, 0);
|
||||
else
|
||||
pk.SetRandomIVs(flawless: 3);
|
||||
}
|
||||
|
||||
@@ -722,33 +722,18 @@ private static bool IVsMatch(uint r1, uint r2, ReadOnlySpan<uint> IVs)
|
||||
/// <summary>
|
||||
/// Generates IVs from 2 RNG calls using 15 bits of each to generate 6 IVs (5bits each).
|
||||
/// </summary>
|
||||
/// <param name="result">Result storage</param>
|
||||
/// <param name="r1">First rand frame</param>
|
||||
/// <param name="r2">Second rand frame</param>
|
||||
/// <returns>Array of 6 IVs</returns>
|
||||
internal static uint[] GetIVs(uint r1, uint r2)
|
||||
internal static void GetIVsInt32(Span<int> result, uint r1, uint r2)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
r1 & 31,
|
||||
r1 >> 5 & 31,
|
||||
r1 >> 10 & 31,
|
||||
r2 & 31,
|
||||
r2 >> 5 & 31,
|
||||
r2 >> 10 & 31,
|
||||
};
|
||||
}
|
||||
|
||||
internal static int[] GetIVsInt32(uint r1, uint r2)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
(int)r1 & 31,
|
||||
(int)r1 >> 5 & 31,
|
||||
(int)r1 >> 10 & 31,
|
||||
(int)r2 & 31,
|
||||
(int)r2 >> 5 & 31,
|
||||
(int)r2 >> 10 & 31,
|
||||
};
|
||||
result[5] = (int)r2 >> 10 & 31;
|
||||
result[4] = (int)r2 >> 5 & 31;
|
||||
result[3] = (int)r2 & 31;
|
||||
result[2] = (int)r1 >> 10 & 31;
|
||||
result[1] = (int)r1 >> 5 & 31;
|
||||
result[0] = (int)r1 & 31;
|
||||
}
|
||||
|
||||
private static uint GetIVChunk(ReadOnlySpan<uint> IVs, int start)
|
||||
|
||||
@@ -32,7 +32,8 @@ private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed)
|
||||
if (skipIV2Frame) // VBlank skip between IVs
|
||||
D = rng.Next(D);
|
||||
|
||||
var IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16);
|
||||
Span<int> IVs = stackalloc int[6];
|
||||
MethodFinder.GetIVsInt32(IVs, C >> 16, D >> 16);
|
||||
if (type == PIDType.Method_1_Roamer)
|
||||
{
|
||||
// Only store lowest 8 bits of IV data; zero out the other bits.
|
||||
@@ -40,7 +41,7 @@ private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed)
|
||||
for (int i = 2; i < 6; i++)
|
||||
IVs[i] = 0;
|
||||
}
|
||||
pk.IVs = IVs;
|
||||
pk.SetIVs(IVs);
|
||||
}
|
||||
|
||||
private static void SetValuesFromSeedBACD(PKM pk, PIDType type, uint seed)
|
||||
@@ -71,7 +72,9 @@ private static void SetValuesFromSeedBACD(PKM pk, PIDType type, uint seed)
|
||||
pk.PID = (A & 0xFFFF0000) | B >> 16;
|
||||
}
|
||||
|
||||
pk.IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16);
|
||||
Span<int> IVs = stackalloc int[6];
|
||||
MethodFinder.GetIVsInt32(IVs, C >> 16, D >> 16);
|
||||
pk.SetIVs(IVs);
|
||||
|
||||
bool antishiny = type is PIDType.BACD_R_A or PIDType.BACD_U_A;
|
||||
while (antishiny && pk.IsShiny)
|
||||
@@ -101,7 +104,9 @@ private static void SetValuesFromSeedXDRNG(PKM pk, uint seed)
|
||||
var E = rng.Next(D); // PID
|
||||
|
||||
pk.PID = (D & 0xFFFF0000) | E >> 16;
|
||||
pk.IVs = MethodFinder.GetIVsInt32(A >> 16, B >> 16);
|
||||
Span<int> IVs = stackalloc int[6];
|
||||
MethodFinder.GetIVsInt32(IVs, A >> 16, B >> 16);
|
||||
pk.SetIVs(IVs);
|
||||
}
|
||||
|
||||
public static void SetValuesFromSeedXDRNG_EReader(PKM pk, uint seed)
|
||||
@@ -207,7 +212,9 @@ public static void SetRandomChainShinyPID(PKM pk, uint seed)
|
||||
|
||||
upper = ((uint)(lower ^ pk.TID ^ pk.SID) & 0xFFF8) | (upper & 0x7);
|
||||
pk.PID = upper << 16 | lower;
|
||||
pk.IVs = MethodFinder.GetIVsInt32(Next(), Next());
|
||||
Span<int> IVs = stackalloc int[6];
|
||||
MethodFinder.GetIVsInt32(IVs, Next(), Next());
|
||||
pk.SetIVs(IVs);
|
||||
}
|
||||
|
||||
public static void SetRandomPokeSpotPID(PKM pk, int nature, int gender, int ability, int slot)
|
||||
|
||||
@@ -972,7 +972,7 @@ public int[] SetRandomIVsGO(int minIV = 0, int maxIV = 15)
|
||||
/// <param name="template">IV template to generate from</param>
|
||||
/// <param name="flawless">Count of flawless IVs to set. If none provided, a count will be detected.</param>
|
||||
/// <returns>Randomized IVs if desired.</returns>
|
||||
public int[] SetRandomIVs(IReadOnlyList<int> template, int? flawless = null)
|
||||
public int[] SetRandomIVs(ReadOnlySpan<int> template, int? flawless = null)
|
||||
{
|
||||
int count = flawless ?? GetFlawlessIVCount();
|
||||
int[] ivs = new int[6];
|
||||
|
||||
Reference in New Issue
Block a user