diff --git a/PKHeX.Core/Editing/IBattleTemplate.cs b/PKHeX.Core/Editing/IBattleTemplate.cs index 1fa1577e1..c91c5a80e 100644 --- a/PKHeX.Core/Editing/IBattleTemplate.cs +++ b/PKHeX.Core/Editing/IBattleTemplate.cs @@ -53,7 +53,7 @@ public interface IBattleTemplate : ISpeciesForm, IGigantamaxReadOnly, IDynamaxLe /// /// of the Set entity. /// - int HiddenPowerType { get; } + sbyte HiddenPowerType { get; } /// /// of the Set entity. diff --git a/PKHeX.Core/Editing/Showdown/ShowdownSet.cs b/PKHeX.Core/Editing/Showdown/ShowdownSet.cs index 1229f71e5..0fd1e6e4f 100644 --- a/PKHeX.Core/Editing/Showdown/ShowdownSet.cs +++ b/PKHeX.Core/Editing/Showdown/ShowdownSet.cs @@ -68,7 +68,7 @@ public sealed class ShowdownSet : IBattleTemplate public int[] IVs { get; } = [31, 31, 31, 31, 31, 31]; /// - public int HiddenPowerType { get; private set; } = -1; + public sbyte HiddenPowerType { get; private set; } = -1; public MoveType TeraType { get; private set; } = MoveType.Any; @@ -512,7 +512,7 @@ public ShowdownSet(PKM pk) var moves = Moves.AsSpan(); pk.GetMoves(moves); if (moves.Contains((ushort)Move.HiddenPower)) - HiddenPowerType = HiddenPower.GetType(IVs, Context); + HiddenPowerType = (sbyte)HiddenPower.GetType(IVs, Context); Nature = pk.StatNature; Gender = pk.Gender < 2 ? pk.Gender : (byte)2; @@ -719,7 +719,7 @@ private ReadOnlySpan ParseLineMove(ReadOnlySpan line) if (hpVal == -1) return hiddenPowerName; - HiddenPowerType = hpVal; + HiddenPowerType = (sbyte)hpVal; if (!Array.TrueForAll(IVs, z => z == 31)) { if (!HiddenPower.SetIVsForType(hpVal, IVs, Context)) diff --git a/PKHeX.Core/Legality/Encounters/Generator/EncounterCriteria.cs b/PKHeX.Core/Legality/Encounters/Generator/EncounterCriteria.cs index 40fe6336d..48788258b 100644 --- a/PKHeX.Core/Legality/Encounters/Generator/EncounterCriteria.cs +++ b/PKHeX.Core/Legality/Encounters/Generator/EncounterCriteria.cs @@ -14,8 +14,8 @@ public sealed record EncounterCriteria : IFixedNature, IFixedAbilityNumber, IShi public static readonly EncounterCriteria Unrestricted = new(); /// End result's gender. - /// Leave as null to not restrict gender. - public byte? Gender { get; init; } + /// Leave as to not restrict gender. + public Gender Gender { get; init; } = Gender.Random; /// End result's ability numbers permitted. /// Leave as to not restrict ability. @@ -29,12 +29,12 @@ public sealed record EncounterCriteria : IFixedNature, IFixedAbilityNumber, IShi /// Leave as to not restrict shininess. public Shiny Shiny { get; init; } - public int IV_HP { get; init; } = RandomIV; - public int IV_ATK { get; init; } = RandomIV; - public int IV_DEF { get; init; } = RandomIV; - public int IV_SPA { get; init; } = RandomIV; - public int IV_SPD { get; init; } = RandomIV; - public int IV_SPE { get; init; } = RandomIV; + public sbyte IV_HP { get; init; } = RandomIV; + public sbyte IV_ATK { get; init; } = RandomIV; + public sbyte IV_DEF { get; init; } = RandomIV; + public sbyte IV_SPA { get; init; } = RandomIV; + public sbyte IV_SPD { get; init; } = RandomIV; + public sbyte IV_SPE { get; init; } = RandomIV; /// /// If the Encounter yields variable level ranges (e.g. RNG correlation), force the minimum level instead of yielding first match. @@ -44,7 +44,7 @@ public sealed record EncounterCriteria : IFixedNature, IFixedAbilityNumber, IShi public sbyte TeraType { get; init; } = -1; // unused - public int HPType { get; init; } = -1; + public sbyte HPType { get; init; } = -1; private const int RandomIV = -1; @@ -102,12 +102,12 @@ public static EncounterCriteria GetCriteria(IBattleTemplate s, IPersonalTable t) public static EncounterCriteria GetCriteria(IBattleTemplate s, IPersonalInfo pi) => new() { Gender = GetGenderPermissions(s.Gender, pi), - IV_HP = s.IVs[0], - IV_ATK = s.IVs[1], - IV_DEF = s.IVs[2], - IV_SPE = s.IVs[3], - IV_SPA = s.IVs[4], - IV_SPD = s.IVs[5], + IV_HP = (sbyte)s.IVs[0], + IV_ATK = (sbyte)s.IVs[1], + IV_DEF = (sbyte)s.IVs[2], + IV_SPE = (sbyte)s.IVs[3], + IV_SPA = (sbyte)s.IVs[4], + IV_SPD = (sbyte)s.IVs[5], HPType = s.HiddenPowerType, Ability = GetAbilityPermissions(s.Ability, pi), @@ -116,14 +116,14 @@ public static EncounterCriteria GetCriteria(IBattleTemplate s, IPersonalInfo pi) TeraType = (sbyte)s.TeraType, }; - private static byte? GetGenderPermissions(byte? gender, IGenderDetail pi) + private static Gender GetGenderPermissions(byte? gender, IGenderDetail pi) { if (gender is not <= 1) - return null; + return Gender.Random; if (pi.IsDualGender) - return gender; + return (Gender)gender; var g = pi.FixedGender(); - return g <= 1 ? g : null; + return g <= 1 ? (Gender)g : Gender.Random; } private static AbilityPermission GetAbilityPermissions(int ability, IPersonalAbility pi) @@ -169,12 +169,12 @@ public Nature GetNature() /// /// Indicates if the is specified. /// - public bool IsGenderSpecified => Gender != null; + public bool IsGenderSpecified => Gender != Gender.Random; /// /// Indicates if the requested gender matches the criteria. /// - public bool IsGenderSatisfied(byte gender) => !IsGenderSpecified || gender == Gender; + public bool IsGenderSatisfied(byte gender) => !IsGenderSpecified || (Gender)gender == Gender; /// /// Gets the gender to generate, random if unspecified by the template or criteria. @@ -189,7 +189,7 @@ public byte GetGender(byte gender, IGenderDetail pkPersonalInfo) /// public byte GetGender(Gender gender, IGenderDetail pkPersonalInfo) { - if (gender == Core.Gender.Random) + if (gender == Gender.Random) return GetGender(pkPersonalInfo); return (byte)gender; } @@ -203,8 +203,8 @@ public byte GetGender(IGenderDetail pkPersonalInfo) return pkPersonalInfo.FixedGender(); if (pkPersonalInfo.Genderless) return 2; - if (Gender is { } request and (0 or 1)) - return request; + if (Gender is not Gender.Random) + return (byte)Gender; return pkPersonalInfo.RandomGender(); } @@ -356,4 +356,10 @@ public bool IsCompatibleIVs(ReadOnlySpan ivs) return false; return true; } + + public void GetCombinedIVs(out uint iv1, out uint iv2) + { + iv1 = (byte)IV_HP | (uint)IV_ATK << 5 | (uint)IV_DEF << 10; + iv2 = (byte)IV_SPE | (uint)IV_SPA << 5 | (uint)IV_SPD << 10; + } } diff --git a/PKHeX.Core/Legality/RNG/CXD/MethodCXD.cs b/PKHeX.Core/Legality/RNG/CXD/MethodCXD.cs index 64ce9b899..868525f12 100644 --- a/PKHeX.Core/Legality/RNG/CXD/MethodCXD.cs +++ b/PKHeX.Core/Legality/RNG/CXD/MethodCXD.cs @@ -14,7 +14,7 @@ public static class MethodCXD public static bool SetFromIVs(this T enc, G3PKM pk, EncounterCriteria criteria, PersonalInfo3 pi, bool noShiny = false) where T : IShadow3 { var gr = pi.Gender; - (uint iv1, uint iv2) = GetCombinedIVs(criteria); + criteria.GetCombinedIVs(out var iv1, out var iv2); Span all = stackalloc uint[XDRNG.MaxCountSeedsIV]; var count = XDRNG.GetSeedsIVs(all, iv1 << 16, iv2 << 16); var seeds = all[..count]; @@ -52,7 +52,7 @@ public static class MethodCXD public static bool SetFromIVsCXD(G3PKM pk, EncounterCriteria criteria, PersonalInfo3 pi, bool noShiny = true) { var gr = pi.Gender; - (uint iv1, uint iv2) = GetCombinedIVs(criteria); + criteria.GetCombinedIVs(out var iv1, out var iv2); Span all = stackalloc uint[XDRNG.MaxCountSeedsIV]; var count = XDRNG.GetSeedsIVs(all, iv1 << 16, iv2 << 16); var seeds = all[..count]; @@ -174,13 +174,6 @@ private static uint GetPIDStarterMale(ref uint seed, uint id32) private static uint GetPIDRegular(uint a, uint b) => a << 16 | b; - private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria) - { - uint iv1 = (uint)criteria.IV_HP | (uint)criteria.IV_ATK << 5 | (uint)criteria.IV_DEF << 10; - uint iv2 = (uint)criteria.IV_SPE | (uint)criteria.IV_SPA << 5 | (uint)criteria.IV_SPD << 10; - return (iv1, iv2); - } - private static void SetIVs(G3PKM pk, uint iv1, uint iv2) { Span ivs = stackalloc int[6]; diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/GenerateMethodH.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/GenerateMethodH.cs index 2693c518b..d77389523 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/GenerateMethodH.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/GenerateMethodH.cs @@ -95,7 +95,7 @@ public static bool SetFromIVs(this T enc, PK3 pk, EncounterCriteria criteria) where T : IEncounterSlot3 { var gr = pk.PersonalInfo.Gender; - (uint iv1, uint iv2) = GetCombinedIVs(criteria); + criteria.GetCombinedIVs(out var iv1, out var iv2); Span all = stackalloc uint[LCRNG.MaxCountSeedsIV]; var count = LCRNGReversal.GetSeedsIVs(all, iv1 << 16, iv2 << 16); var seeds = all[..count]; @@ -163,7 +163,7 @@ public static bool SetFromIVs(this T enc, PK3 pk, EncounterCriteria criteria) public static bool SetFromIVsUnown(this T enc, PK3 pk, EncounterCriteria criteria) where T : IEncounterSlot3 { - (uint iv1, uint iv2) = GetCombinedIVs(criteria); + criteria.GetCombinedIVs(out var iv1, out var iv2); Span all = stackalloc uint[LCRNG.MaxCountSeedsIV]; var count = LCRNGReversal.GetSeedsIVs(all, iv1 << 16, iv2 << 16); var seeds = all[..count]; @@ -235,11 +235,4 @@ private static void SetPIDIVSequential(PK3 pk, uint pid, uint rand) pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF); pk.RefreshAbility((int)(pid & 1)); } - - private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria) - { - uint iv1 = (uint)criteria.IV_HP | (uint)criteria.IV_ATK << 5 | (uint)criteria.IV_DEF << 10; - uint iv2 = (uint)criteria.IV_SPE | (uint)criteria.IV_SPA << 5 | (uint)criteria.IV_SPD << 10; - return (iv1, iv2); - } } diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/MethodH.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/MethodH.cs index fb2e48ad6..eb54e5e4e 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/MethodH.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/MethodH.cs @@ -564,10 +564,11 @@ private static bool IsOriginalLevelValid(byte min, byte max, byte format, uint l return LevelRangeExtensions.IsLevelWithinRange((int)level, min, max); } - private static uint GetExpectedLevel(ILevelRange enc, uint u16LevelRand) + private static uint GetExpectedLevel(T enc, uint u16LevelRand) where T : ILevelRange { - uint mod = 1u + enc.LevelMax - enc.LevelMin; - return (u16LevelRand % mod) + enc.LevelMin; + var min = enc.LevelMin; + uint mod = 1u + enc.LevelMax - min; + return (u16LevelRand % mod) + min; } private static bool IsRockSmashPossible(byte areaRate, ref uint seed) diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodJ.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodJ.cs index 2ac010489..0ab0c9923 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodJ.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodJ.cs @@ -89,7 +89,7 @@ public static bool SetFromIVsJ(this T enc, PK4 pk, PersonalInfo4 pi, Encounte where T : IEncounterSlot4 { var gr = pi.Gender; - (uint iv1, uint iv2) = GetCombinedIVs(criteria); + criteria.GetCombinedIVs(out var iv1, out var iv2); Span all = stackalloc uint[LCRNG.MaxCountSeedsIV]; var count = LCRNGReversal.GetSeedsIVs(all, iv1 << 16, iv2 << 16); var seeds = all[..count]; @@ -124,11 +124,4 @@ public static bool SetFromIVsJ(this T enc, PK4 pk, PersonalInfo4 pi, Encounte } public static uint GetPIDRegular(uint a, uint b) => b << 16 | a; - - private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria) - { - uint iv1 = (uint)criteria.IV_HP | (uint)criteria.IV_ATK << 5 | (uint)criteria.IV_DEF << 10; - uint iv2 = (uint)criteria.IV_SPE | (uint)criteria.IV_SPA << 5 | (uint)criteria.IV_SPD << 10; - return (iv1, iv2); - } } diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs index 4c87a8c4c..b25846318 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs @@ -88,7 +88,7 @@ public static bool SetFromIVsK(this T enc, PK4 pk, PersonalInfo4 pi, Encounte where T : IEncounterSlot4 { var gr = pi.Gender; - (uint iv1, uint iv2) = GetCombinedIVs(criteria); + criteria.GetCombinedIVs(out var iv1, out var iv2); Span all = stackalloc uint[LCRNG.MaxCountSeedsIV]; var count = LCRNGReversal.GetSeedsIVs(all, iv1 << 16, iv2 << 16); var seeds = all[..count]; @@ -123,11 +123,4 @@ public static bool SetFromIVsK(this T enc, PK4 pk, PersonalInfo4 pi, Encounte } public static uint GetPIDRegular(uint a, uint b) => b << 16 | a; - - private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria) - { - uint iv1 = (uint)criteria.IV_HP | (uint)criteria.IV_ATK << 5 | (uint)criteria.IV_DEF << 10; - uint iv2 = (uint)criteria.IV_SPE | (uint)criteria.IV_SPA << 5 | (uint)criteria.IV_SPD << 10; - return (iv1, iv2); - } } diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodJ.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodJ.cs index 2644e30f2..a66384bb4 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodJ.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodJ.cs @@ -456,10 +456,11 @@ private static bool IsOriginalLevelValid(byte min, byte max, byte format, uint l return LevelRangeExtensions.IsLevelWithinRange((int)level, min, max); } - private static uint GetExpectedLevel(ILevelRange enc, uint u16LevelRand) + private static uint GetExpectedLevel(T enc, uint u16LevelRand) where T : ILevelRange { - uint mod = 1u + enc.LevelMax - enc.LevelMin; - return (u16LevelRand % mod) + enc.LevelMin; + var min = enc.LevelMin; + uint mod = 1u + enc.LevelMax - min; + return (u16LevelRand % mod) + min; } /// diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodK.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodK.cs index a85c7a2c4..8367e21f1 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodK.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodK.cs @@ -482,10 +482,11 @@ private static bool IsOriginalLevelValid(byte min, byte max, byte format, uint l return LevelRangeExtensions.IsLevelWithinRange((int)level, min, max); } - private static uint GetExpectedLevel(ILevelRange enc, uint u16LevelRand) + private static uint GetExpectedLevel(T enc, uint u16LevelRand) where T : ILevelRange { - uint mod = 1u + enc.LevelMax - enc.LevelMin; - return (u16LevelRand % mod) + enc.LevelMin; + var min = enc.LevelMin; + uint mod = 1u + enc.LevelMax - min; + return (u16LevelRand % mod) + min; } private static bool IsBugContestPossibleDeadlock(uint areaRate, ref uint result) diff --git a/PKHeX.WinForms/Subforms/SAV_Encounters.cs b/PKHeX.WinForms/Subforms/SAV_Encounters.cs index ef365a362..01f40a093 100644 --- a/PKHeX.WinForms/Subforms/SAV_Encounters.cs +++ b/PKHeX.WinForms/Subforms/SAV_Encounters.cs @@ -187,7 +187,7 @@ private EncounterCriteria GetCriteria(ISpeciesForm enc, EncounterDatabaseSetting var set = new ShowdownSet(editor); var criteria = EncounterCriteria.GetCriteria(set, editor.PersonalInfo); if (!isInChain) - criteria = criteria with { Gender = default }; // Genderless tabs and a gendered enc -> let's play safe. + criteria = criteria with { Gender = Gender.Random }; // Genderless tabs and a gendered enc -> let's play safe. return criteria; }