mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-03-21 17:48:28 -05:00
Misc tweaks
Add rejections for shiny criteria for gen8+ generators Unrelated: use recent c# lang feature for settings property field
This commit is contained in:
parent
ca6fbf024c
commit
3ad376be44
|
|
@ -126,6 +126,12 @@ public EncounterCriteria()
|
||||||
/// <returns>><see langword="true"/> if an Ability is specified; otherwise, <see langword="false"/>.</returns>
|
/// <returns>><see langword="true"/> if an Ability is specified; otherwise, <see langword="false"/>.</returns>
|
||||||
public bool IsSpecifiedAbility() => Ability != Any12H;
|
public bool IsSpecifiedAbility() => Ability != Any12H;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the shiny value is explicitly specified rather than set to random.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>><see langword="true"/> if a Shiny is specified; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public bool IsSpecifiedShiny() => Shiny != Shiny.Random;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether all IVs are specified in the criteria.
|
/// Determines whether all IVs are specified in the criteria.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -183,6 +189,20 @@ public int GetCountSpecifiedIVs() => Convert.ToInt32(IV_HP != RandomIV)
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(ability), ability, null),
|
_ => throw new ArgumentOutOfRangeException(nameof(ability), ability, null),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified shiny properties satisfy the shiny criteria based on the current <see cref="Shiny"/> setting.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>><see langword="true"/> if the index satisfies the shiny criteria; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public bool IsSatisfiedShiny(uint xor, uint cmp) => Shiny switch
|
||||||
|
{
|
||||||
|
Shiny.Random => true,
|
||||||
|
Shiny.Never => xor > cmp, // not shiny
|
||||||
|
Shiny.AlwaysSquare => xor == 0, // square shiny
|
||||||
|
Shiny.AlwaysStar => xor < cmp && xor != 0, // star shiny
|
||||||
|
Shiny.Always => xor < cmp, // shiny
|
||||||
|
_ => false, // shouldn't be set
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the specified Nature satisfies the criteria.
|
/// Determines whether the specified Nature satisfies the criteria.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,10 @@ protected override void SetPINGA(PK8 pk, in EncounterCriteria criteria, Personal
|
||||||
{
|
{
|
||||||
Span<int> iv = stackalloc int[6];
|
Span<int> iv = stackalloc int[6];
|
||||||
|
|
||||||
|
// Honor a shiny request only at the end; generate as never-shiny to avoid shiny PID rejection in main RNG method.
|
||||||
|
var isShinyRequested = criteria.Shiny.IsShiny();
|
||||||
|
var iterCriteria = criteria with { Shiny = ShinyMethod };
|
||||||
|
|
||||||
int ctr = 0;
|
int ctr = 0;
|
||||||
var rand = new Xoroshiro128Plus(Util.Rand.Rand64());
|
var rand = new Xoroshiro128Plus(Util.Rand.Rand64());
|
||||||
var param = GetParam(pi);
|
var param = GetParam(pi);
|
||||||
|
|
@ -64,21 +68,22 @@ protected override void SetPINGA(PK8 pk, in EncounterCriteria criteria, Personal
|
||||||
const int max = 100_000;
|
const int max = 100_000;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (TryApply(pk, seed = rand.Next(), iv, param, criteria))
|
if (TryApply(pk, seed = rand.Next(), iv, param, iterCriteria))
|
||||||
break;
|
break;
|
||||||
} while (++ctr < max);
|
} while (++ctr < max);
|
||||||
|
|
||||||
if (ctr == max) // fail
|
if (ctr == max) // fail
|
||||||
{
|
{
|
||||||
if (!TryApply(pk, seed = rand.Next(), iv, param, criteria.WithoutIVs()))
|
iterCriteria = iterCriteria.WithoutIVs();
|
||||||
|
if (!TryApply(pk, seed = rand.Next(), iv, param, iterCriteria))
|
||||||
{
|
{
|
||||||
var tmp = EncounterCriteria.Unrestricted with { Shiny = ShinyMethod };
|
iterCriteria = EncounterCriteria.Unrestricted with { Shiny = ShinyMethod };
|
||||||
while (!TryApply(pk, seed = rand.Next(), iv, param, tmp)) { }
|
while (!TryApply(pk, seed = rand.Next(), iv, param, iterCriteria)) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FinishCorrelation(pk, seed);
|
FinishCorrelation(pk, seed);
|
||||||
if (criteria.Shiny.IsShiny())
|
if (isShinyRequested)
|
||||||
pk.PID = ShinyUtil.GetShinyPID(pk.TID16, pk.SID16, pk.PID, ShinyXor);
|
pk.PID = ShinyUtil.GetShinyPID(pk.TID16, pk.SID16, pk.PID, ShinyXor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ public static bool GenerateData(PA9 pk, in GenerateParam9a enc, in EncounterCrit
|
||||||
{
|
{
|
||||||
var rand = new Xoroshiro128Plus(seed);
|
var rand = new Xoroshiro128Plus(seed);
|
||||||
pk.EncryptionConstant = (uint)rand.NextInt(uint.MaxValue);
|
pk.EncryptionConstant = (uint)rand.NextInt(uint.MaxValue);
|
||||||
pk.PID = GetAdaptedPID(ref rand, pk, enc);
|
var pid = GetAdaptedPID(ref rand, pk, enc);
|
||||||
|
if (enc.Shiny is Shiny.Random && criteria.IsSpecifiedShiny() && !criteria.IsSatisfiedShiny(ShinyUtil.GetShinyXor(pid, pk.ID32), 16))
|
||||||
if (enc.Shiny is Shiny.Random && criteria.Shiny.IsShiny() != pk.IsShiny)
|
|
||||||
return false;
|
return false;
|
||||||
|
pk.PID = pid;
|
||||||
|
|
||||||
Span<int> ivs = [UNSET, UNSET, UNSET, UNSET, UNSET, UNSET];
|
Span<int> ivs = [UNSET, UNSET, UNSET, UNSET, UNSET, UNSET];
|
||||||
if (enc.IVs.IsSpecified)
|
if (enc.IVs.IsSpecified)
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,8 @@ private static bool TryApplyFromSeed(PK8 pk, in EncounterCriteria criteria, Shin
|
||||||
if (shiny == Shiny.AlwaysStar && type != Shiny.AlwaysStar)
|
if (shiny == Shiny.AlwaysStar && type != Shiny.AlwaysStar)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (shiny is Shiny.Random && criteria.IsSpecifiedShiny() && !criteria.IsSatisfiedShiny(GetShinyXor(pid, pk.ID32), 16))
|
||||||
|
return false;
|
||||||
pk.PID = pid;
|
pk.PID = pid;
|
||||||
|
|
||||||
// IVs
|
// IVs
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,8 @@ public static bool TryApply(PK8 pk, ulong seed, Span<int> ivs, in GenerateParam8
|
||||||
|
|
||||||
var trID = (uint)rng.NextInt();
|
var trID = (uint)rng.NextInt();
|
||||||
var pid = (uint)rng.NextInt();
|
var pid = (uint)rng.NextInt();
|
||||||
|
|
||||||
|
// Battle
|
||||||
var xor = GetShinyXor(pid, trID);
|
var xor = GetShinyXor(pid, trID);
|
||||||
bool isShiny = xor < 16;
|
bool isShiny = xor < 16;
|
||||||
if (isShiny && param.Shiny == Shiny.Never)
|
if (isShiny && param.Shiny == Shiny.Never)
|
||||||
|
|
@ -167,9 +169,8 @@ public static bool TryApply(PK8 pk, ulong seed, Span<int> ivs, in GenerateParam8
|
||||||
ForceShinyState(false, ref pid, trID, 0);
|
ForceShinyState(false, ref pid, trID, 0);
|
||||||
isShiny = false;
|
isShiny = false;
|
||||||
}
|
}
|
||||||
if (param.Shiny is Shiny.Random && isShiny != criteria.Shiny.IsShiny())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
// Captured
|
||||||
if (isShiny)
|
if (isShiny)
|
||||||
{
|
{
|
||||||
if (!GetIsShiny6(pk.ID32, pid))
|
if (!GetIsShiny6(pk.ID32, pid))
|
||||||
|
|
@ -181,6 +182,8 @@ public static bool TryApply(PK8 pk, ulong seed, Span<int> ivs, in GenerateParam8
|
||||||
pid ^= 0x1000_0000;
|
pid ^= 0x1000_0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (param.Shiny is Shiny.Random && criteria.IsSpecifiedShiny() && !criteria.IsSatisfiedShiny(GetShinyXor(pid, pk.ID32), 16))
|
||||||
|
return false;
|
||||||
pk.PID = pid;
|
pk.PID = pid;
|
||||||
|
|
||||||
const int UNSET = -1;
|
const int UNSET = -1;
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,8 @@ public static bool TryApplyFromSeed(PA8 pk, in EncounterCriteria criteria, in Ov
|
||||||
if (para.Shiny == Shiny.AlwaysStar && type != Shiny.AlwaysStar)
|
if (para.Shiny == Shiny.AlwaysStar && type != Shiny.AlwaysStar)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (para.Shiny is Shiny.Random && criteria.IsSpecifiedShiny() && !criteria.IsSatisfiedShiny(GetShinyXor(pid, pk.ID32), 16))
|
||||||
|
return false;
|
||||||
pk.PID = pid;
|
pk.PID = pid;
|
||||||
|
|
||||||
Span<int> ivs = [UNSET, UNSET, UNSET, UNSET, UNSET, UNSET];
|
Span<int> ivs = [UNSET, UNSET, UNSET, UNSET, UNSET, UNSET];
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ public static bool TryApplyFromSeed(PB8 pk, in EncounterCriteria criteria, Shiny
|
||||||
if (shiny == Shiny.AlwaysStar && type != Shiny.AlwaysStar)
|
if (shiny == Shiny.AlwaysStar && type != Shiny.AlwaysStar)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (shiny is Shiny.Random && criteria.IsSpecifiedShiny() && !criteria.IsSatisfiedShiny(GetShinyXor(pid, pk.ID32), 16))
|
||||||
|
return false;
|
||||||
pk.PID = pid;
|
pk.PID = pid;
|
||||||
|
|
||||||
// Check IVs: Create flawless IVs at random indexes, then the random IVs for not flawless.
|
// Check IVs: Create flawless IVs at random indexes, then the random IVs for not flawless.
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ public static bool TryApplyFromSeed(PB8 pk, in EncounterCriteria criteria, Shiny
|
||||||
if (shiny == Shiny.AlwaysStar && type != Shiny.AlwaysStar)
|
if (shiny == Shiny.AlwaysStar && type != Shiny.AlwaysStar)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (shiny is Shiny.Random && criteria.IsSpecifiedShiny() && !criteria.IsSatisfiedShiny(GetShinyXor(pid, pk.ID32), 16))
|
||||||
|
return false;
|
||||||
pk.PID = pid;
|
pk.PID = pid;
|
||||||
|
|
||||||
// Check IVs: Create flawless IVs at random indexes, then the random IVs for not flawless.
|
// Check IVs: Create flawless IVs at random indexes, then the random IVs for not flawless.
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,10 @@ public static bool GenerateData(PK9 pk, in GenerateParam9 enc, in EncounterCrite
|
||||||
{
|
{
|
||||||
var rand = new Xoroshiro128Plus(seed);
|
var rand = new Xoroshiro128Plus(seed);
|
||||||
pk.EncryptionConstant = (uint)rand.NextInt(uint.MaxValue);
|
pk.EncryptionConstant = (uint)rand.NextInt(uint.MaxValue);
|
||||||
pk.PID = GetAdaptedPID(ref rand, pk, enc);
|
var pid = GetAdaptedPID(ref rand, pk, enc);
|
||||||
|
if (enc.Shiny is Shiny.Random && criteria.IsSpecifiedShiny() && !criteria.IsSatisfiedShiny(GetShinyXor(pid, pk.ID32), 16))
|
||||||
if (enc.Shiny is Shiny.Random && criteria.Shiny.IsShiny() != pk.IsShiny)
|
|
||||||
return false;
|
return false;
|
||||||
|
pk.PID = pid;
|
||||||
|
|
||||||
const int UNSET = -1;
|
const int UNSET = -1;
|
||||||
const int MAX = 31;
|
const int MAX = 31;
|
||||||
|
|
|
||||||
|
|
@ -39,15 +39,14 @@ public sealed class StartupSettings : IStartupSettings
|
||||||
public List<string> RecentlyLoaded { get; set; } = new(DefaultMaxRecent);
|
public List<string> RecentlyLoaded { get; set; } = new(DefaultMaxRecent);
|
||||||
|
|
||||||
private const int DefaultMaxRecent = 10;
|
private const int DefaultMaxRecent = 10;
|
||||||
private uint MaxRecentCount = DefaultMaxRecent;
|
|
||||||
|
|
||||||
[LocalizedDescription("Amount of recently loaded save files to remember.")]
|
[LocalizedDescription("Amount of recently loaded save files to remember.")]
|
||||||
public uint RecentlyLoadedMaxCount
|
public uint RecentlyLoadedMaxCount
|
||||||
{
|
{
|
||||||
get => MaxRecentCount;
|
get;
|
||||||
// Sanity check to not let the user foot-gun themselves a slow recall time.
|
// Sanity check to not let the user foot-gun themselves a slow recall time.
|
||||||
set => MaxRecentCount = Math.Clamp(value, 1, 1000);
|
set => field = Math.Clamp(value, 1, 1000);
|
||||||
}
|
} = DefaultMaxRecent;
|
||||||
|
|
||||||
// Don't let invalid values slip into the startup version.
|
// Don't let invalid values slip into the startup version.
|
||||||
|
|
||||||
|
|
@ -89,7 +88,7 @@ public void LoadSaveFile(string path)
|
||||||
{
|
{
|
||||||
var recent = RecentlyLoaded;
|
var recent = RecentlyLoaded;
|
||||||
// Remove from list if already present.
|
// Remove from list if already present.
|
||||||
if (!recent.Remove(path) && recent.Count >= MaxRecentCount)
|
if (!recent.Remove(path) && recent.Count >= RecentlyLoadedMaxCount)
|
||||||
recent.RemoveAt(recent.Count - 1);
|
recent.RemoveAt(recent.Count - 1);
|
||||||
recent.Insert(0, path);
|
recent.Insert(0, path);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user