mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 14:44:24 +00:00
Stackalloc IVs for template->pkm fill
This commit is contained in:
parent
8f8726ac5e
commit
d5ae6764aa
18 changed files with 204 additions and 43 deletions
|
@ -248,7 +248,7 @@ namespace PKHeX.Core
|
|||
_ => generation >= 6 ? 12 : 10,
|
||||
};
|
||||
|
||||
public static bool GetIsFixedIVSequenceValidSkipRand(IReadOnlyList<int> IVs, PKM pkm, int max = 31)
|
||||
public static bool GetIsFixedIVSequenceValidSkipRand(ReadOnlySpan<int> IVs, PKM pkm, int max = 31)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
|
@ -260,7 +260,7 @@ namespace PKHeX.Core
|
|||
return true;
|
||||
}
|
||||
|
||||
public static bool GetIsFixedIVSequenceValidNoRand(IReadOnlyList<int> IVs, PKM pkm)
|
||||
public static bool GetIsFixedIVSequenceValidNoRand(ReadOnlySpan<int> IVs, PKM pkm)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
|
|
|
@ -253,7 +253,7 @@ namespace PKHeX.Core
|
|||
if (Generation <= 2 && pkm.Format > 2)
|
||||
return true; // IVs are regenerated on VC transfer upward
|
||||
|
||||
return Legal.GetIsFixedIVSequenceValidSkipRand(IVs, pkm);
|
||||
return Legal.GetIsFixedIVSequenceValidSkipRand((int[])IVs, pkm);
|
||||
}
|
||||
|
||||
protected virtual bool IsMatchForm(PKM pkm, DexLevel evo)
|
||||
|
|
|
@ -182,7 +182,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
if (IVs.Count != 0)
|
||||
{
|
||||
if (!Legal.GetIsFixedIVSequenceValidSkipRand(IVs, pkm))
|
||||
if (!Legal.GetIsFixedIVSequenceValidSkipRand((int[])IVs, pkm))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
if (Gender >= 0 && Gender != pkm.Gender)
|
||||
return false;
|
||||
if (IVs.Count != 0 && !Legal.GetIsFixedIVSequenceValidNoRand(IVs, pkm))
|
||||
if (IVs.Count != 0 && !Legal.GetIsFixedIVSequenceValidNoRand((int[])IVs, pkm))
|
||||
return false;
|
||||
if (pkm.Format == 2 && pkm.Met_Location is not (0 or 126))
|
||||
return false;
|
||||
|
|
|
@ -42,11 +42,12 @@ namespace PKHeX.Core
|
|||
|
||||
private void VerifyIVsMystery(LegalityAnalysis data, MysteryGift g)
|
||||
{
|
||||
var IVs = g.IVs;
|
||||
if (IVs.Length == 0)
|
||||
return;
|
||||
if (!g.HasFixedIVs)
|
||||
return; // PID/IV style instead of fixed IVs.
|
||||
|
||||
var ivflag = Array.Find(IVs, iv => (byte)(iv - 0xFC) < 3);
|
||||
Span<int> IVs = stackalloc int[6];
|
||||
g.GetIVs(IVs);
|
||||
var ivflag = IVs.Find(iv => (byte)(iv - 0xFC) < 3);
|
||||
if (ivflag == 0) // Random IVs
|
||||
{
|
||||
bool valid = Legal.GetIsFixedIVSequenceValidSkipRand(IVs, data.pkm);
|
||||
|
|
|
@ -134,6 +134,8 @@ namespace PKHeX.Core
|
|||
public virtual IReadOnlyList<int> Moves { get => Array.Empty<int>(); set { } }
|
||||
public virtual IReadOnlyList<int> Relearn { get => Array.Empty<int>(); set { } }
|
||||
public virtual int[] IVs { get => Array.Empty<int>(); set { } }
|
||||
public virtual bool HasFixedIVs => true;
|
||||
public virtual void GetIVs(Span<int> value) { }
|
||||
public virtual bool IsShiny => false;
|
||||
|
||||
public virtual Shiny Shiny
|
||||
|
|
|
@ -88,6 +88,8 @@ namespace PKHeX.Core
|
|||
public override int SID { get => Gift.SID; set => Gift.SID = value; }
|
||||
public override string OT_Name { get => Gift.OT_Name; set => Gift.OT_Name = value; }
|
||||
public override AbilityPermission Ability => Gift.Ability;
|
||||
public override bool HasFixedIVs => Gift.HasFixedIVs;
|
||||
public override void GetIVs(Span<int> value) => Gift.GetIVs(value);
|
||||
|
||||
// ILocation overrides
|
||||
public override int Location { get => IsEgg ? 0 : Gift.EggLocation + 3000; set { } }
|
||||
|
|
|
@ -155,6 +155,18 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
public override void GetIVs(Span<int> value)
|
||||
{
|
||||
if (value.Length != 6)
|
||||
return;
|
||||
value[0] = IV_HP;
|
||||
value[1] = IV_ATK;
|
||||
value[2] = IV_DEF;
|
||||
value[3] = IV_SPE;
|
||||
value[4] = IV_SPA;
|
||||
value[5] = IV_SPD;
|
||||
}
|
||||
|
||||
public bool IsNicknamed => Nickname.Length > 0;
|
||||
public override bool IsShiny => PIDType == 2;
|
||||
public override int Location { get => MetLocation; set => MetLocation = (ushort)value; }
|
||||
|
@ -339,9 +351,10 @@ namespace PKHeX.Core
|
|||
private void SetIVs(PKM pk)
|
||||
{
|
||||
Span<int> finalIVs = stackalloc int[6];
|
||||
GetIVs(finalIVs);
|
||||
var rnd = Util.Rand;
|
||||
for (int i = 0; i < IVs.Length; i++)
|
||||
finalIVs[i] = IVs[i] == 0xFF ? rnd.Next(32) : IVs[i];
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
finalIVs[i] = finalIVs[i] == 0xFF ? rnd.Next(32) : finalIVs[i];
|
||||
pk.SetIVs(finalIVs);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,12 @@ namespace PKHeX.Core
|
|||
public override string OT_Name { get => PK.OT_Name; set => PK.OT_Name = value; }
|
||||
public override int Location { get => PK.Met_Location; set => PK.Met_Location = value; }
|
||||
public override int EggLocation { get => PK.Egg_Location; set => PK.Egg_Location = value; }
|
||||
public override bool HasFixedIVs => PK.IV32 != 0;
|
||||
public override void GetIVs(Span<int> value)
|
||||
{
|
||||
if (HasFixedIVs)
|
||||
PK.GetIVs(value);
|
||||
}
|
||||
|
||||
public override PKM ConvertToPKM(ITrainerInfo sav, EncounterCriteria criteria)
|
||||
{
|
||||
|
|
|
@ -254,6 +254,18 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
public override void GetIVs(Span<int> value)
|
||||
{
|
||||
if (value.Length != 6)
|
||||
return;
|
||||
value[0] = IV_HP;
|
||||
value[1] = IV_ATK;
|
||||
value[2] = IV_DEF;
|
||||
value[3] = IV_SPE;
|
||||
value[4] = IV_SPA;
|
||||
value[5] = IV_SPD;
|
||||
}
|
||||
|
||||
public int[] EVs
|
||||
{
|
||||
get => new[] { EV_HP, EV_ATK, EV_DEF, EV_SPE, EV_SPA, EV_SPD };
|
||||
|
@ -541,20 +553,27 @@ namespace PKHeX.Core
|
|||
private void SetIVs(PKM pk)
|
||||
{
|
||||
Span<int> finalIVs = stackalloc int[6];
|
||||
var ivflag = Array.Find(IVs, iv => (byte)(iv - 0xFC) < 3);
|
||||
GetIVs(finalIVs);
|
||||
var ivflag = finalIVs.Find(iv => (byte)(iv - 0xFC) < 3);
|
||||
var rng = Util.Rand;
|
||||
if (ivflag == 0) // Random IVs
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = IVs[i] > 31 ? rng.Next(32) : IVs[i];
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] > 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[rng.Next(6)] = 31; }
|
||||
while (finalIVs.Count(31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rng.Next(32);
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] != 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
pk.SetIVs(finalIVs);
|
||||
}
|
||||
|
|
|
@ -244,6 +244,18 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
public override void GetIVs(Span<int> value)
|
||||
{
|
||||
if (value.Length != 6)
|
||||
return;
|
||||
value[0] = IV_HP;
|
||||
value[1] = IV_ATK;
|
||||
value[2] = IV_DEF;
|
||||
value[3] = IV_SPE;
|
||||
value[4] = IV_SPA;
|
||||
value[5] = IV_SPD;
|
||||
}
|
||||
|
||||
public bool GetIsNicknamed(int language) => Data[GetNicknameOffset(language)] != 0;
|
||||
|
||||
private static int GetLanguageIndex(int language)
|
||||
|
@ -469,20 +481,27 @@ namespace PKHeX.Core
|
|||
private void SetIVs(PKM pk)
|
||||
{
|
||||
Span<int> finalIVs = stackalloc int[6];
|
||||
var ivflag = Array.Find(IVs, iv => (byte)(iv - 0xFC) < 3);
|
||||
GetIVs(finalIVs);
|
||||
var ivflag = finalIVs.Find(iv => (byte)(iv - 0xFC) < 3);
|
||||
var rng = Util.Rand;
|
||||
if (ivflag == 0) // Random IVs
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = IVs[i] > 31 ? rng.Next(32) : IVs[i];
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] > 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[rng.Next(6)] = 31; }
|
||||
while (finalIVs.Count(31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rng.Next(32);
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] != 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
pk.SetIVs(finalIVs);
|
||||
}
|
||||
|
|
|
@ -249,6 +249,18 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
public override void GetIVs(Span<int> value)
|
||||
{
|
||||
if (value.Length != 6)
|
||||
return;
|
||||
value[0] = IV_HP;
|
||||
value[1] = IV_ATK;
|
||||
value[2] = IV_DEF;
|
||||
value[3] = IV_SPE;
|
||||
value[4] = IV_SPA;
|
||||
value[5] = IV_SPD;
|
||||
}
|
||||
|
||||
public int[] EVs
|
||||
{
|
||||
get => new[] { EV_HP, EV_ATK, EV_DEF, EV_SPE, EV_SPA, EV_SPD };
|
||||
|
@ -537,20 +549,27 @@ namespace PKHeX.Core
|
|||
private void SetIVs(PKM pk)
|
||||
{
|
||||
Span<int> finalIVs = stackalloc int[6];
|
||||
var ivflag = Array.Find(IVs, iv => (byte)(iv - 0xFC) < 3);
|
||||
GetIVs(finalIVs);
|
||||
var ivflag = finalIVs.Find(iv => (byte)(iv - 0xFC) < 3);
|
||||
var rng = Util.Rand;
|
||||
if (ivflag == 0) // Random IVs
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = IVs[i] > 31 ? rng.Next(32) : IVs[i];
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] > 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[rng.Next(6)] = 31; }
|
||||
while (finalIVs.Count(31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rng.Next(32);
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] != 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
pk.SetIVs(finalIVs);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace PKHeX.Core
|
|||
public override byte Level { get; set; }
|
||||
public override int Ball { get; set; } = 4;
|
||||
public override bool IsShiny => Shiny == Shiny.Always;
|
||||
public override bool HasFixedIVs => false;
|
||||
public bool RibbonEarth { get; set; }
|
||||
public bool RibbonNational { get; set; }
|
||||
public bool RibbonCountry { get; set; }
|
||||
|
|
|
@ -473,23 +473,42 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
public override void GetIVs(Span<int> value)
|
||||
{
|
||||
if (value.Length != 6)
|
||||
return;
|
||||
value[0] = IV_HP;
|
||||
value[1] = IV_ATK;
|
||||
value[2] = IV_DEF;
|
||||
value[3] = IV_SPE;
|
||||
value[4] = IV_SPA;
|
||||
value[5] = IV_SPD;
|
||||
}
|
||||
|
||||
private void SetIVs(PKM pk)
|
||||
{
|
||||
Span<int> finalIVs = stackalloc int[6];
|
||||
var ivflag = Array.Find(IVs, iv => (byte)(iv - 0xFC) < 3);
|
||||
var rnd = Util.Rand;
|
||||
GetIVs(finalIVs);
|
||||
var ivflag = finalIVs.Find(iv => (byte)(iv - 0xFC) < 3);
|
||||
var rng = Util.Rand;
|
||||
if (ivflag == 0) // Random IVs
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = IVs[i] > 31 ? rnd.Next(32) : IVs[i];
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] > 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[rnd.Next(6)] = 31; }
|
||||
do { finalIVs[rng.Next(6)] = 31; }
|
||||
while (finalIVs.Count(31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rnd.Next(32);
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] != 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
pk.SetIVs(finalIVs);
|
||||
}
|
||||
|
|
|
@ -295,6 +295,18 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
public override void GetIVs(Span<int> value)
|
||||
{
|
||||
if (value.Length != 6)
|
||||
return;
|
||||
value[0] = IV_HP;
|
||||
value[1] = IV_ATK;
|
||||
value[2] = IV_DEF;
|
||||
value[3] = IV_SPE;
|
||||
value[4] = IV_SPA;
|
||||
value[5] = IV_SPD;
|
||||
}
|
||||
|
||||
public int[] EVs
|
||||
{
|
||||
get => new[] { EV_HP, EV_ATK, EV_DEF, EV_SPE, EV_SPA, EV_SPD };
|
||||
|
@ -507,20 +519,27 @@ namespace PKHeX.Core
|
|||
private void SetIVs(PKM pk)
|
||||
{
|
||||
Span<int> finalIVs = stackalloc int[6];
|
||||
var ivflag = Array.Find(IVs, iv => (byte)(iv - 0xFC) < 3);
|
||||
GetIVs(finalIVs);
|
||||
var ivflag = finalIVs.Find(iv => (byte)(iv - 0xFC) < 3);
|
||||
var rng = Util.Rand;
|
||||
if (ivflag == 0) // Random IVs
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = IVs[i] > 31 ? rng.Next(32) : IVs[i];
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] > 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[rng.Next(6)] = 31; }
|
||||
while (finalIVs.Count(31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rng.Next(32);
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] != 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
pk.SetIVs(finalIVs);
|
||||
}
|
||||
|
|
|
@ -241,6 +241,18 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
public override void GetIVs(Span<int> value)
|
||||
{
|
||||
if (value.Length != 6)
|
||||
return;
|
||||
value[0] = IV_HP;
|
||||
value[1] = IV_ATK;
|
||||
value[2] = IV_DEF;
|
||||
value[3] = IV_SPE;
|
||||
value[4] = IV_SPA;
|
||||
value[5] = IV_SPD;
|
||||
}
|
||||
|
||||
public int[] EVs
|
||||
{
|
||||
get => new[] { EV_HP, EV_ATK, EV_DEF, EV_SPE, EV_SPA, EV_SPD };
|
||||
|
@ -540,20 +552,27 @@ namespace PKHeX.Core
|
|||
private void SetIVs(PKM pk)
|
||||
{
|
||||
Span<int> finalIVs = stackalloc int[6];
|
||||
var ivflag = Array.Find(IVs, iv => (byte)(iv - 0xFC) < 3);
|
||||
GetIVs(finalIVs);
|
||||
var ivflag = finalIVs.Find(iv => (byte)(iv - 0xFC) < 3);
|
||||
var rng = Util.Rand;
|
||||
if (ivflag == 0) // Random IVs
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = IVs[i] > 31 ? rng.Next(32) : IVs[i];
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] > 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[rng.Next(6)] = 31; }
|
||||
while (finalIVs.Count(31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rng.Next(32);
|
||||
for (int i = 0; i < finalIVs.Length; i++)
|
||||
{
|
||||
if (finalIVs[i] != 31)
|
||||
finalIVs[i] = rng.Next(32);
|
||||
}
|
||||
}
|
||||
pk.SetIVs(finalIVs);
|
||||
}
|
||||
|
|
|
@ -376,6 +376,18 @@ namespace PKHeX.Core
|
|||
set => SetIVs(value);
|
||||
}
|
||||
|
||||
public void GetIVs(Span<int> value)
|
||||
{
|
||||
if (value.Length != 6)
|
||||
return;
|
||||
value[0] = IV_HP;
|
||||
value[1] = IV_ATK;
|
||||
value[2] = IV_DEF;
|
||||
value[3] = IV_SPE;
|
||||
value[4] = IV_SPA;
|
||||
value[5] = IV_SPD;
|
||||
}
|
||||
|
||||
public void SetIVs(ReadOnlySpan<int> value)
|
||||
{
|
||||
if (value.Length != 6)
|
||||
|
|
|
@ -23,6 +23,16 @@ namespace PKHeX.Core
|
|||
return ((ReadOnlySpan<T>)data).Count(value);
|
||||
}
|
||||
|
||||
public static T Find<T>(this Span<T> data, Func<T, bool> value) where T : unmanaged
|
||||
{
|
||||
foreach (var x in data)
|
||||
{
|
||||
if (value(x))
|
||||
return x;
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public static int Count<T>(this ReadOnlySpan<T> data, T value) where T : IEquatable<T>
|
||||
{
|
||||
int count = 0;
|
||||
|
|
Loading…
Reference in a new issue