mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 14:44:24 +00:00
Update Random to be a bit more thread safe
Random isn't thread safe; users of PKHeX.Core.dll might run multithreaded operations (see PKSM + ALM), so we need to have a thread-specific RNG available. Thread Local get; to improve performance, save the random object locally whenever it is used more than once in the method. https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadlocal-1?redirectedfrom=MSDN&view=netframework-4.8 https://stackoverflow.com/questions/18333885/threadstatic-v-s-threadlocalt-is-generic-better-than-attribute/18337158#18337158
This commit is contained in:
parent
1520210e68
commit
c301ce88ab
23 changed files with 128 additions and 77 deletions
|
@ -66,8 +66,9 @@ namespace PKHeX.Core
|
|||
/// <param name="gender">Desired <see cref="PKM.Gender"/>.</param>
|
||||
public static void SetATKIVGender(this PKM pk, int gender)
|
||||
{
|
||||
var rnd = Util.Rand;
|
||||
while (pk.Gender != gender)
|
||||
pk.IV_ATK = Util.Rand.Next(pk.MaxIV + 1);
|
||||
pk.IV_ATK = rnd.Next(16);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,7 +90,7 @@ namespace PKHeX.Core
|
|||
if (pk is PK5 pk5 && abilIndex == 2)
|
||||
pk5.HiddenAbility = true;
|
||||
else if (pk.Format <= 5)
|
||||
pk.PID = PKX.GetRandomPID(pk.Species, pk.Gender, pk.Version, pk.Nature, pk.AltForm, (uint)(abilIndex * 0x10001));
|
||||
pk.PID = PKX.GetRandomPID(Util.Rand, pk.Species, pk.Gender, pk.Version, pk.Nature, pk.AltForm, (uint)(abilIndex * 0x10001));
|
||||
pk.RefreshAbility(abilIndex);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,12 @@ namespace PKHeX.Core
|
|||
|
||||
internal static int RandomValidTime(this EncounterTime t1)
|
||||
{
|
||||
int val = Util.Rand.Next(1, 4);
|
||||
var rnd = Util.Rand;
|
||||
int val = rnd.Next(1, 4);
|
||||
if (t1 == EncounterTime.Any)
|
||||
return val;
|
||||
while (!t1.Contains(val))
|
||||
val = Util.Rand.Next(1, 4);
|
||||
val = rnd.Next(1, 4);
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -401,14 +401,15 @@ namespace PKHeX.Core
|
|||
|
||||
private static void SetRandomIVs(PKM pk)
|
||||
{
|
||||
var rng = Util.Rand;
|
||||
pk.IVs = new[]
|
||||
{
|
||||
Util.Rand.Next(32),
|
||||
Util.Rand.Next(32),
|
||||
Util.Rand.Next(32),
|
||||
Util.Rand.Next(32),
|
||||
Util.Rand.Next(32),
|
||||
Util.Rand.Next(32),
|
||||
rng.Next(32),
|
||||
rng.Next(32),
|
||||
rng.Next(32),
|
||||
rng.Next(32),
|
||||
rng.Next(32),
|
||||
rng.Next(32),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,9 +183,10 @@ namespace PKHeX.Core
|
|||
public static int GetRandomFeeling(int memory, int max = 24)
|
||||
{
|
||||
var bits = MemoryFeelings[memory];
|
||||
var rnd = Util.Rand;
|
||||
while (true)
|
||||
{
|
||||
int feel = Util.Rand.Next(max);
|
||||
int feel = rnd.Next(max);
|
||||
if ((bits & (1 << feel)) != 0)
|
||||
return feel;
|
||||
}
|
||||
|
|
|
@ -38,9 +38,10 @@ namespace PKHeX.Core
|
|||
const int max = (int) GameVersion.RB;
|
||||
if ((int)ver.Version < max)
|
||||
return ver.Version;
|
||||
var rnd = Util.Rand;
|
||||
while (true) // this isn't optimal, but is low maintenance
|
||||
{
|
||||
var game = (GameVersion)Util.Rand.Next(1, max);
|
||||
var game = (GameVersion)rnd.Next(1, max);
|
||||
if (ver.CanBeReceivedBy(game))
|
||||
return game;
|
||||
}
|
||||
|
|
|
@ -166,6 +166,8 @@ namespace PKHeX.Core
|
|||
if (!IsPokémon)
|
||||
throw new ArgumentException(nameof(IsPokémon));
|
||||
|
||||
var rnd = Util.Rand;
|
||||
|
||||
var dt = DateTime.Now;
|
||||
if (Day == 0)
|
||||
{
|
||||
|
@ -174,14 +176,14 @@ namespace PKHeX.Core
|
|||
Year = (byte)dt.Year;
|
||||
}
|
||||
|
||||
int currentLevel = Level > 0 ? Level : Util.Rand.Next(100) + 1;
|
||||
int currentLevel = Level > 0 ? Level : rnd.Next(1, 101);
|
||||
var pi = PersonalTable.B2W2.GetFormeEntry(Species, Form);
|
||||
PK5 pk = new PK5
|
||||
{
|
||||
Species = Species,
|
||||
HeldItem = HeldItem,
|
||||
Met_Level = currentLevel,
|
||||
Nature = Nature != -1 ? Nature : Util.Rand.Next(25),
|
||||
Nature = Nature != -1 ? Nature : rnd.Next(25),
|
||||
AltForm = Form,
|
||||
Version = OriginGame == 0 ? SAV.Game : OriginGame,
|
||||
Language = Language == 0 ? SAV.Language : Language,
|
||||
|
@ -223,7 +225,7 @@ namespace PKHeX.Core
|
|||
FatefulEncounter = true,
|
||||
};
|
||||
if (SAV.Generation > 5 && OriginGame == 0) // Gen6+, give random gen5 game
|
||||
pk.Version = (int)GameVersion.W + Util.Rand.Next(4);
|
||||
pk.Version = (int)GameVersion.W + rnd.Next(4);
|
||||
|
||||
if (Move1 == 0) // No moves defined
|
||||
pk.Moves = MoveLevelUp.GetEncounterMoves(Species, Form, Level, (GameVersion)pk.Version);
|
||||
|
@ -304,7 +306,8 @@ namespace PKHeX.Core
|
|||
|
||||
pk.PID = Util.Rand32();
|
||||
// Force Gender
|
||||
do { pk.PID = (pk.PID & 0xFFFFFF00) | (uint)Util.Rand.Next(0x100); }
|
||||
var rnd = Util.Rand;
|
||||
do { pk.PID = (pk.PID & 0xFFFFFF00) | (uint)rnd.Next(0x100); }
|
||||
while (!pk.IsGenderValid());
|
||||
|
||||
if (PIDType == 2) // Always
|
||||
|
@ -327,8 +330,9 @@ namespace PKHeX.Core
|
|||
private void SetIVs(PKM pk)
|
||||
{
|
||||
int[] finalIVs = new int[6];
|
||||
var rnd = Util.Rand;
|
||||
for (int i = 0; i < IVs.Length; i++)
|
||||
finalIVs[i] = IVs[i] == 0xFF ? Util.Rand.Next(pk.MaxIV + 1) : IVs[i];
|
||||
finalIVs[i] = IVs[i] == 0xFF ? rnd.Next(32) : IVs[i];
|
||||
pk.IVs = finalIVs;
|
||||
}
|
||||
|
||||
|
|
|
@ -317,7 +317,9 @@ namespace PKHeX.Core
|
|||
if (!IsPokémon)
|
||||
throw new ArgumentException(nameof(IsPokémon));
|
||||
|
||||
int currentLevel = Level > 0 ? Level : Util.Rand.Next(100) + 1;
|
||||
var rnd = Util.Rand;
|
||||
|
||||
int currentLevel = Level > 0 ? Level : rnd.Next(1, 101);
|
||||
int metLevel = MetLevel > 0 ? MetLevel : currentLevel;
|
||||
var pi = PersonalTable.GG.GetFormeEntry(Species, Form);
|
||||
var OT = GetOT(SAV.Language);
|
||||
|
@ -370,7 +372,7 @@ namespace PKHeX.Core
|
|||
if ((SAV.Generation > Format && OriginGame == 0) || !CanBeReceivedByVersion(pk.Version))
|
||||
{
|
||||
// give random valid game
|
||||
do { pk.Version = (int)GameVersion.GP + Util.Rand.Next(2); }
|
||||
do { pk.Version = (int)GameVersion.GP + rnd.Next(2); }
|
||||
while (!CanBeReceivedByVersion(pk.Version));
|
||||
}
|
||||
|
||||
|
@ -390,8 +392,8 @@ namespace PKHeX.Core
|
|||
SetEggMetData(pk);
|
||||
pk.CurrentFriendship = pk.IsEgg ? pi.HatchCycles : pi.BaseFriendship;
|
||||
|
||||
pk.HeightScalar = Util.Rand.Next(0x100);
|
||||
pk.WeightScalar = Util.Rand.Next(0x100);
|
||||
pk.HeightScalar = rnd.Next(0x100);
|
||||
pk.WeightScalar = rnd.Next(0x100);
|
||||
pk.ResetCalculatedValues(); // cp & dimensions
|
||||
|
||||
pk.RefreshChecksum();
|
||||
|
@ -458,18 +460,19 @@ namespace PKHeX.Core
|
|||
{
|
||||
int[] finalIVs = new int[6];
|
||||
var ivflag = Array.Find(IVs, 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 ? Util.Rand.Next(pk.MaxIV + 1) : IVs[i];
|
||||
finalIVs[i] = IVs[i] > 31 ? rng.Next(32) : IVs[i];
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[Util.Rand.Next(6)] = 31; }
|
||||
do { finalIVs[rng.Next(6)] = 31; }
|
||||
while (finalIVs.Count(iv => iv == 31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? pk.MaxIV : Util.Rand.Next(pk.MaxIV + 1);
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rng.Next(32);
|
||||
}
|
||||
pk.IVs = finalIVs;
|
||||
}
|
||||
|
|
|
@ -270,7 +270,9 @@ namespace PKHeX.Core
|
|||
if (!IsPokémon)
|
||||
throw new ArgumentException(nameof(IsPokémon));
|
||||
|
||||
int currentLevel = Level > 0 ? Level : Util.Rand.Next(100) + 1;
|
||||
var rnd = Util.Rand;
|
||||
|
||||
int currentLevel = Level > 0 ? Level : rnd.Next(1, 101);
|
||||
var pi = PersonalTable.AO.GetFormeEntry(Species, Form);
|
||||
PK6 pk = new PK6
|
||||
{
|
||||
|
@ -342,7 +344,7 @@ namespace PKHeX.Core
|
|||
if ((SAV.Generation > Format && OriginGame == 0) || !CanBeReceivedByVersion(pk.Version))
|
||||
{
|
||||
// give random valid game
|
||||
do { pk.Version = (int)GameVersion.X + Util.Rand.Next(4); }
|
||||
do { pk.Version = (int)GameVersion.X + rnd.Next(4); }
|
||||
while (!CanBeReceivedByVersion(pk.Version));
|
||||
}
|
||||
|
||||
|
@ -438,18 +440,19 @@ namespace PKHeX.Core
|
|||
{
|
||||
int[] finalIVs = new int[6];
|
||||
var ivflag = Array.Find(IVs, iv => (byte)(iv - 0xFC) < 3);
|
||||
var rnd = Util.Rand;
|
||||
if (ivflag == 0) // Random IVs
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = IVs[i] > 31 ? Util.Rand.Next(pk.MaxIV + 1) : IVs[i];
|
||||
finalIVs[i] = IVs[i] > 31 ? rnd.Next(32) : IVs[i];
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[Util.Rand.Next(6)] = 31; }
|
||||
do { finalIVs[rnd.Next(6)] = 31; }
|
||||
while (finalIVs.Count(iv => iv == 31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? pk.MaxIV : Util.Rand.Next(pk.MaxIV + 1);
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rnd.Next(32);
|
||||
}
|
||||
pk.IVs = finalIVs;
|
||||
}
|
||||
|
|
|
@ -313,7 +313,9 @@ namespace PKHeX.Core
|
|||
if (!IsPokémon)
|
||||
throw new ArgumentException(nameof(IsPokémon));
|
||||
|
||||
int currentLevel = Level > 0 ? Level : Util.Rand.Next(100) + 1;
|
||||
var rnd = Util.Rand;
|
||||
|
||||
int currentLevel = Level > 0 ? Level : rnd.Next(1, 101);
|
||||
int metLevel = MetLevel > 0 ? MetLevel : currentLevel;
|
||||
var pi = PersonalTable.USUM.GetFormeEntry(Species, Form);
|
||||
PK7 pk = new PK7
|
||||
|
@ -384,7 +386,7 @@ namespace PKHeX.Core
|
|||
if ((SAV.Generation > Format && OriginGame == 0) || !CanBeReceivedByVersion(pk.Version))
|
||||
{
|
||||
// give random valid game
|
||||
do { pk.Version = (int)GameVersion.SN + Util.Rand.Next(4); }
|
||||
do { pk.Version = (int)GameVersion.SN + rnd.Next(4); }
|
||||
while (!CanBeReceivedByVersion(pk.Version));
|
||||
}
|
||||
|
||||
|
@ -469,18 +471,19 @@ namespace PKHeX.Core
|
|||
{
|
||||
int[] finalIVs = new int[6];
|
||||
var ivflag = Array.Find(IVs, 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 ? Util.Rand.Next(pk.MaxIV + 1) : IVs[i];
|
||||
finalIVs[i] = IVs[i] > 31 ? rng.Next(32) : IVs[i];
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[Util.Rand.Next(6)] = 31; }
|
||||
do { finalIVs[rng.Next(6)] = 31; }
|
||||
while (finalIVs.Count(iv => iv == 31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? pk.MaxIV : Util.Rand.Next(pk.MaxIV + 1);
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rng.Next(32);
|
||||
}
|
||||
pk.IVs = finalIVs;
|
||||
}
|
||||
|
|
|
@ -299,7 +299,7 @@ namespace PKHeX.Core
|
|||
if (!IsPokémon)
|
||||
throw new ArgumentException(nameof(IsPokémon));
|
||||
|
||||
int currentLevel = Level > 0 ? Level : Util.Rand.Next(100) + 1;
|
||||
int currentLevel = Level > 0 ? Level : Util.Rand.Next(1, 101);
|
||||
int metLevel = MetLevel > 0 ? MetLevel : currentLevel;
|
||||
var pi = PersonalTable.SWSH.GetFormeEntry(Species, Form);
|
||||
var OT = GetOT(SAV.Language);
|
||||
|
@ -356,7 +356,8 @@ namespace PKHeX.Core
|
|||
if ((SAV.Generation > Format && OriginGame == 0) || !CanBeReceivedByVersion(pk.Version))
|
||||
{
|
||||
// give random valid game
|
||||
do { pk.Version = (int)GameVersion.SW + Util.Rand.Next(2); }
|
||||
var rnd = Util.Rand;
|
||||
do { pk.Version = (int)GameVersion.SW + rnd.Next(2); }
|
||||
while (!CanBeReceivedByVersion(pk.Version));
|
||||
}
|
||||
|
||||
|
@ -471,18 +472,19 @@ namespace PKHeX.Core
|
|||
{
|
||||
int[] finalIVs = new int[6];
|
||||
var ivflag = Array.Find(IVs, 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 ? Util.Rand.Next(pk.MaxIV + 1) : IVs[i];
|
||||
finalIVs[i] = IVs[i] > 31 ? rng.Next(32) : IVs[i];
|
||||
}
|
||||
else // 1/2/3 perfect IVs
|
||||
{
|
||||
int IVCount = ivflag - 0xFB;
|
||||
do { finalIVs[Util.Rand.Next(6)] = 31; }
|
||||
do { finalIVs[rng.Next(6)] = 31; }
|
||||
while (finalIVs.Count(iv => iv == 31) < IVCount);
|
||||
for (int i = 0; i < 6; i++)
|
||||
finalIVs[i] = finalIVs[i] == 31 ? pk.MaxIV : Util.Rand.Next(pk.MaxIV + 1);
|
||||
finalIVs[i] = finalIVs[i] == 31 ? 31 : rng.Next(32);
|
||||
}
|
||||
pk.IVs = finalIVs;
|
||||
}
|
||||
|
|
|
@ -167,8 +167,11 @@ namespace PKHeX.Core
|
|||
// IVs
|
||||
var new_ivs = new int[6];
|
||||
int flawless = Species == (int)Core.Species.Mew ? 5 : 3;
|
||||
for (var i = 0; i < new_ivs.Length; i++) new_ivs[i] = Util.Rand.Next(pk7.MaxIV + 1);
|
||||
for (var i = 0; i < flawless; i++) new_ivs[i] = 31;
|
||||
var rnd = Util.Rand;
|
||||
for (var i = 0; i < new_ivs.Length; i++)
|
||||
new_ivs[i] = rnd.Next(pk7.MaxIV + 1);
|
||||
for (var i = 0; i < flawless; i++)
|
||||
new_ivs[i] = 31;
|
||||
Util.Shuffle(new_ivs);
|
||||
pk7.IVs = new_ivs;
|
||||
|
||||
|
|
|
@ -167,8 +167,11 @@ namespace PKHeX.Core
|
|||
var special = Species == 151 || Species == 251;
|
||||
var new_ivs = new int[6];
|
||||
int flawless = special ? 5 : 3;
|
||||
for (var i = 0; i < new_ivs.Length; i++) new_ivs[i] = Util.Rand.Next(pk7.MaxIV + 1);
|
||||
for (var i = 0; i < flawless; i++) new_ivs[i] = 31;
|
||||
var rnd = Util.Rand;
|
||||
for (var i = 0; i < new_ivs.Length; i++)
|
||||
new_ivs[i] = rnd.Next(pk7.MaxIV + 1);
|
||||
for (var i = 0; i < flawless; i++)
|
||||
new_ivs[i] = 31;
|
||||
Util.Shuffle(new_ivs);
|
||||
pk7.IVs = new_ivs;
|
||||
|
||||
|
|
|
@ -937,7 +937,8 @@ namespace PKHeX.Core
|
|||
/// </remarks>
|
||||
public virtual void SetShiny()
|
||||
{
|
||||
do { PID = PKX.GetRandomPID(Species, Gender, Version, Nature, AltForm, PID); }
|
||||
var rnd = Util.Rand;
|
||||
do { PID = PKX.GetRandomPID(rnd, Species, Gender, Version, Nature, AltForm, PID); }
|
||||
while (!IsShiny);
|
||||
if (Format >= 6 && (Gen3 || Gen4 || Gen5))
|
||||
EncryptionConstant = PID;
|
||||
|
@ -948,7 +949,8 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public void SetShinySID()
|
||||
{
|
||||
if (IsShiny) return;
|
||||
if (IsShiny)
|
||||
return;
|
||||
var xor = TID ^ (PID >> 16) ^ (PID & 0xFFFF);
|
||||
SID = (int)(xor & 0xFFF8) | Util.Rand.Next(8);
|
||||
}
|
||||
|
@ -962,7 +964,9 @@ namespace PKHeX.Core
|
|||
/// </remarks>
|
||||
public void SetPIDGender(int gender)
|
||||
{
|
||||
do PID = PKX.GetRandomPID(Species, gender, Version, Nature, AltForm, PID); while (IsShiny);
|
||||
var rnd = Util.Rand;
|
||||
do PID = PKX.GetRandomPID(rnd, Species, gender, Version, Nature, AltForm, PID);
|
||||
while (IsShiny);
|
||||
if (Format >= 6 && (Gen3 || Gen4 || Gen5))
|
||||
EncryptionConstant = PID;
|
||||
}
|
||||
|
@ -976,7 +980,9 @@ namespace PKHeX.Core
|
|||
/// </remarks>
|
||||
public void SetPIDNature(int nature)
|
||||
{
|
||||
do PID = PKX.GetRandomPID(Species, Gender, Version, nature, AltForm, PID); while (IsShiny);
|
||||
var rnd = Util.Rand;
|
||||
do PID = PKX.GetRandomPID(rnd, Species, Gender, Version, nature, AltForm, PID);
|
||||
while (IsShiny);
|
||||
if (Format >= 6 && (Gen3 || Gen4 || Gen5))
|
||||
EncryptionConstant = PID;
|
||||
}
|
||||
|
@ -1007,8 +1013,9 @@ namespace PKHeX.Core
|
|||
return SetRandomIVsGO();
|
||||
|
||||
int[] ivs = new int[6];
|
||||
var rnd = Util.Rand;
|
||||
for (int i = 0; i < 6; i++)
|
||||
ivs[i] = Util.Rand.Next(MaxIV + 1);
|
||||
ivs[i] = rnd.Next(MaxIV + 1);
|
||||
|
||||
int count = flawless ?? GetFlawlessIVCount();
|
||||
if (count != 0)
|
||||
|
@ -1023,10 +1030,11 @@ namespace PKHeX.Core
|
|||
private int[] SetRandomIVsGO()
|
||||
{
|
||||
int[] ivs = new int[6];
|
||||
ivs[0] = (Util.Rand.Next(16) << 1) | 1; // hp
|
||||
ivs[1] = ivs[4] = (Util.Rand.Next(16) << 1) | 1; // attack
|
||||
ivs[2] = ivs[5] = (Util.Rand.Next(16) << 1) | 1; // defense
|
||||
ivs[3] = Util.Rand.Next(MaxIV + 1); // speed
|
||||
var rnd = Util.Rand;
|
||||
ivs[0] = (rnd.Next(16) << 1) | 1; // hp
|
||||
ivs[1] = ivs[4] = (rnd.Next(16) << 1) | 1; // attack
|
||||
ivs[2] = ivs[5] = (rnd.Next(16) << 1) | 1; // defense
|
||||
ivs[3] = rnd.Next(MaxIV + 1); // speed
|
||||
return IVs = ivs;
|
||||
}
|
||||
|
||||
|
@ -1040,10 +1048,11 @@ namespace PKHeX.Core
|
|||
{
|
||||
int count = flawless ?? GetFlawlessIVCount();
|
||||
int[] ivs = new int[6];
|
||||
var rnd = Util.Rand;
|
||||
do
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
ivs[i] = template[i] < 0 ? Util.Rand.Next(MaxIV + 1) : template[i];
|
||||
ivs[i] = template[i] < 0 ? rnd.Next(MaxIV + 1) : template[i];
|
||||
} while (ivs.Count(z => z == MaxIV) < count);
|
||||
|
||||
IVs = ivs;
|
||||
|
|
|
@ -45,6 +45,10 @@
|
|||
/// <summary>
|
||||
/// Gets a random size scalar with a triangular distribution (copying official implementation).
|
||||
/// </summary>
|
||||
public static int GetRandomScalar() => Util.Rand.Next(0x81) + Util.Rand.Next(0x80);
|
||||
public static int GetRandomScalar()
|
||||
{
|
||||
var rnd = Util.Rand;
|
||||
return rnd.Next(0x81) + rnd.Next(0x80);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,15 +37,15 @@ namespace PKHeX.Core
|
|||
/// <returns>Array containing randomized EVs (H/A/B/S/C/D)</returns>
|
||||
public static int[] GetRandomEVs(int generation = Generation)
|
||||
{
|
||||
var rnd = Util.Rand;
|
||||
if (generation > 2)
|
||||
{
|
||||
var evs = new int[6];
|
||||
do
|
||||
{
|
||||
int max = 510;
|
||||
int randomEV() => (byte)Math.Min(Util.Rand.Next(Math.Min(300, max)), 252);
|
||||
for (int i = 0; i < evs.Length - 1; i++)
|
||||
max -= evs[i] = randomEV();
|
||||
max -= evs[i] = (byte)Math.Min(rnd.Next(Math.Min(300, max)), 252);
|
||||
evs[5] = max;
|
||||
} while (evs[5] > 252);
|
||||
Util.Shuffle(evs);
|
||||
|
@ -55,7 +55,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
var evs = new int[6];
|
||||
for (int i = 0; i < evs.Length; i++)
|
||||
evs[i] = Util.Rand.Next(ushort.MaxValue + 1);
|
||||
evs[i] = rnd.Next(ushort.MaxValue + 1);
|
||||
return evs;
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ namespace PKHeX.Core
|
|||
/// <summary>
|
||||
/// Gets a random PID according to specifications.
|
||||
/// </summary>
|
||||
/// <param name="rnd">RNG to use</param>
|
||||
/// <param name="species">National Dex ID</param>
|
||||
/// <param name="cg">Current Gender</param>
|
||||
/// <param name="origin">Origin Generation</param>
|
||||
|
@ -115,17 +116,17 @@ namespace PKHeX.Core
|
|||
/// <param name="OLDPID">Current PID</param>
|
||||
/// <remarks>Used to retain ability bits.</remarks>
|
||||
/// <returns>Rerolled PID.</returns>
|
||||
public static uint GetRandomPID(int species, int cg, int origin, int nature, int form, uint OLDPID)
|
||||
public static uint GetRandomPID(Random rnd, int species, int cg, int origin, int nature, int form, uint OLDPID)
|
||||
{
|
||||
uint bits = OLDPID & 0x00010001;
|
||||
int gt = Personal[species].Gender;
|
||||
if (origin >= 24)
|
||||
return Util.Rand32();
|
||||
return Util.Rand32(rnd);
|
||||
|
||||
bool g3unown = origin <= 5 && species == (int)Species.Unown;
|
||||
while (true) // Loop until we find a suitable PID
|
||||
{
|
||||
uint pid = Util.Rand32();
|
||||
uint pid = Util.Rand32(rnd);
|
||||
|
||||
// Gen 3/4: Nature derived from PID
|
||||
if (origin <= 15 && pid%25 != nature)
|
||||
|
|
|
@ -35,16 +35,17 @@ namespace PKHeX.Core
|
|||
|
||||
public void MaxCheat(bool special = false)
|
||||
{
|
||||
var rnd = Util.Rand;
|
||||
if (special)
|
||||
{
|
||||
for (int i = 0; i < PuffSlots; i++)
|
||||
Data[Offset + i] = (byte)(21 + Util.Rand.Next(2)); // Supreme Wish or Honor
|
||||
Data[Offset + i] = (byte)(21 + rnd.Next(2)); // Supreme Wish or Honor
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < PuffSlots; i++)
|
||||
Data[Offset + i] = (byte)((i % MaxPuffID) + 1);
|
||||
Util.Shuffle(Data, Offset, Offset + PuffSlots);
|
||||
Util.Shuffle(Data, Offset, Offset + PuffSlots, rnd);
|
||||
}
|
||||
PuffCount = PuffSlots;
|
||||
}
|
||||
|
|
|
@ -21,10 +21,11 @@ namespace PKHeX.Core
|
|||
|
||||
public void ActivateAllRaids(bool rare, bool isEvent)
|
||||
{
|
||||
var rnd = Util.Rand;
|
||||
for (int i = 0; i < RaidCount; i++)
|
||||
{
|
||||
var star = (byte)Util.Rand.Next(0, 5);
|
||||
var rand = (byte)Util.Rand.Next(0, 100);
|
||||
var star = (byte)rnd.Next(0, 5);
|
||||
var rand = (byte)rnd.Next(0, 100);
|
||||
GetRaid(i).Activate(star, rand, rare, isEvent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public static partial class Util
|
||||
{
|
||||
public static readonly Random Rand = new Random();
|
||||
// Multithread safe rand, ha
|
||||
public static Random Rand => _local.Value;
|
||||
|
||||
public static uint Rand32()
|
||||
{
|
||||
return (uint)Rand.Next(1 << 30) << 2 | (uint)Rand.Next(1 << 2);
|
||||
}
|
||||
private static readonly ThreadLocal<Random> _local = new ThreadLocal<Random>(() => new Random());
|
||||
|
||||
public static uint Rand32() => Rand32(Rand);
|
||||
public static uint Rand32(Random rnd) => (uint)rnd.Next(1 << 30) << 2 | (uint)rnd.Next(1 << 2);
|
||||
|
||||
/// <summary>
|
||||
/// Shuffles the order of items within a collection of items.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Item type</typeparam>
|
||||
/// <param name="items">Item collection</param>
|
||||
public static void Shuffle<T>(IList<T> items) => Shuffle(items, 0, items.Count);
|
||||
public static void Shuffle<T>(IList<T> items) => Shuffle(items, 0, items.Count, Rand);
|
||||
|
||||
/// <summary>
|
||||
/// Shuffles the order of items within a collection of items.
|
||||
|
@ -26,11 +28,12 @@ namespace PKHeX.Core
|
|||
/// <param name="items">Item collection</param>
|
||||
/// <param name="start">Starting position</param>
|
||||
/// <param name="end">Ending position</param>
|
||||
public static void Shuffle<T>(IList<T> items, int start, int end)
|
||||
/// <param name="rnd">RNG object to use</param>
|
||||
public static void Shuffle<T>(IList<T> items, int start, int end, Random rnd)
|
||||
{
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
int index = i + Rand.Next(end - i);
|
||||
int index = i + rnd.Next(end - i);
|
||||
T t = items[index];
|
||||
items[index] = items[i];
|
||||
items[i] = t;
|
||||
|
|
|
@ -364,8 +364,9 @@ namespace PKHeX.WinForms.Controls
|
|||
a.AwakeningSetAllTo(0);
|
||||
break;
|
||||
default:
|
||||
var rnd = Util.Rand;
|
||||
foreach (var index in Enumerable.Range(0, 6))
|
||||
a.SetAV(index, Util.Rand.Next(Legal.AwakeningMax + 1));
|
||||
a.SetAV(index, rnd.Next(Legal.AwakeningMax + 1));
|
||||
break;
|
||||
}
|
||||
LoadAVs(a);
|
||||
|
|
|
@ -23,7 +23,10 @@ namespace PKHeX.WinForms
|
|||
public partial class Main : Form
|
||||
{
|
||||
private static readonly Version CurrentProgramVersion = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
|
||||
static async Task<LegalityAnalysis> GetLegal(PKM pkm)
|
||||
{
|
||||
return await Task.Run(() => new LegalityAnalysis(pkm));
|
||||
}
|
||||
public Main()
|
||||
{
|
||||
Form splash = null; // popup a splash screen in another thread
|
||||
|
|
|
@ -672,14 +672,15 @@ namespace PKHeX.WinForms
|
|||
private void B_RandForest_Click(object sender, EventArgs e)
|
||||
{
|
||||
var source = (SAV is SAV5B2W2 ? Encounters5.B2W2_DreamWorld : Encounters5.BW_DreamWorld).ToList();
|
||||
var rnd = Util.Rand;
|
||||
foreach (var s in AllSlots)
|
||||
{
|
||||
int index = Util.Rand.Next(source.Count);
|
||||
int index = rnd.Next(source.Count);
|
||||
var slot = source[index];
|
||||
source.Remove(slot);
|
||||
s.Species = slot.Species;
|
||||
s.Form = slot.Form;
|
||||
s.Move = slot.Moves[Util.Rand.Next(slot.Moves.Count)];
|
||||
s.Move = slot.Moves[rnd.Next(slot.Moves.Count)];
|
||||
s.Gender = slot.Gender == -1 ? PersonalTable.B2W2[slot.Species].RandomGender() : slot.Gender;
|
||||
}
|
||||
ChangeArea(null, EventArgs.Empty); // refresh
|
||||
|
|
|
@ -47,9 +47,10 @@ namespace PKHeX.WinForms
|
|||
// Randomize the trees.
|
||||
byte[] tree = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x80, 0x40, 0x01, 0x00, 0x00, 0x00, };
|
||||
var plantable = Legal.Pouch_Berry_XY; // 0 index is None, skip with rand
|
||||
var rnd = Util.Rand;
|
||||
for (int i = 0; i < 90; i++) // amount of plots in the game
|
||||
{
|
||||
ushort berry = plantable[Util.Rand.Next(1, plantable.Length)]; // get random berry item ID from list
|
||||
ushort berry = plantable[rnd.Next(1, plantable.Length)]; // get random berry item ID from list
|
||||
BitConverter.GetBytes(berry).CopyTo(tree, 6); // put berry into tree.
|
||||
tree.CopyTo(SAV.Data, SAV.BerryField + (0x10 * i)); // put tree into plot
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue