Misc tweaks

Gift1: use IVs if required
Gift2: Enforce 0 TimeOfDay
Egg9: Require Egg Location to match encounter
PGT: keep requested gender in the event of antishiny
PGT: never yield Korean Ranger Manaphy for Format4

Simplify ushort range checks
Rename `EReader` bool to `IsEReader`
Extract Gender/Nature fetch for unfixed encounters
Remove Unown PIDIV branch when template has no Unown
Remove unnecessary loop for Pokewalker PID creation
This commit is contained in:
Kurt 2023-09-04 00:50:26 -07:00
parent 63c027879f
commit 3fdfd29e4b
46 changed files with 116 additions and 124 deletions

View file

@ -33,9 +33,9 @@ public sealed class ItemStorage3RS : IItemStorage
internal static ReadOnlySpan<ushort> Pouch_TM_RS => Pouch_TMHM_RS[..COUNT_TM];
public static bool IsTMHM(ushort itemID) => (uint)(itemID - 289) < COUNT_TM + COUNT_HM;
public static bool IsTM(ushort itemID) => (uint)(itemID - 289) < COUNT_TM;
public static bool IsHM(ushort itemID) => (uint)(itemID - 339) < COUNT_HM;
public static bool IsTMHM(ushort itemID) => itemID - 289u < COUNT_TM + COUNT_HM;
public static bool IsTM(ushort itemID) => itemID - 289u < COUNT_TM;
public static bool IsHM(ushort itemID) => itemID - 339u < COUNT_HM;
internal static ReadOnlySpan<ushort> Pouch_Berries_RS => new ushort[]
{

View file

@ -104,7 +104,7 @@ public sealed class ItemStorage8SWSH : IItemStorage
private const int COUNT_TR = 100;
private static ReadOnlySpan<ushort> Pouch_TR_SWSH => Pouch_TMTR_SWSH.Slice(99, COUNT_TR);
public static bool IsTechRecord(ushort itemID) => (uint)(itemID - 1130) < COUNT_TR;
public static bool IsTechRecord(ushort itemID) => itemID - 1130u < COUNT_TR;
private static ReadOnlySpan<ushort> Pouch_Medicine_SWSH => new ushort[]
{

View file

@ -47,7 +47,7 @@ public sealed class BulkAnalysis
private static bool IsEmptyData(SlotCache obj)
{
var pk = obj.Entity;
if ((uint)(pk.Species - 1) >= pk.MaxSpeciesID)
if (pk.Species - 1u >= pk.MaxSpeciesID)
return true;
if (!pk.ChecksumValid)
return true;

View file

@ -72,7 +72,7 @@ public sealed class EncounterGenerator3GC : IEncounterGenerator
private static bool GetIsShadowLockValid(PKM pk, LegalInfo info, IShadow3 s) => s switch
{
EncounterShadow3Colo { EReader: true } => GetIsShadowLockValidEReader(pk, info, s),
EncounterShadow3Colo { IsEReader: true } => GetIsShadowLockValidEReader(pk, info, s),
_ => LockFinder.IsAllShadowLockValid(s, info.PIDIV, pk),
};

View file

@ -127,24 +127,40 @@ public sealed record EncounterCriteria : IFixedNature, IFixedGender, IFixedAbili
}
/// <summary>
/// Gets a random nature to generate, based off an encounter's <see cref="encValue"/>.
/// Gets the nature to generate, random if unspecified by the template or criteria.
/// </summary>
public Nature GetNature(Nature encValue)
{
if ((uint)encValue < 25)
return encValue;
return GetNature();
}
/// <summary>
/// Gets the nature to generate, random if unspecified.
/// </summary>
public Nature GetNature()
{
if (Nature != Nature.Random)
return Nature;
return (Nature)Util.Rand.Next(25);
}
/// <summary>
/// Gets a random gender to generate, based off an encounter's <see cref="gender"/>.
/// Gets the gender to generate, random if unspecified by the template or criteria.
/// </summary>
public int GetGender(int gender, IGenderDetail pkPersonalInfo)
{
if ((uint)gender < 3)
return gender;
return GetGender(pkPersonalInfo);
}
/// <summary>
/// Gets the gender to generate, random if unspecified.
/// </summary>
public int GetGender(IGenderDetail pkPersonalInfo)
{
if (!pkPersonalInfo.IsDualGender)
return pkPersonalInfo.FixedGender();
if (pkPersonalInfo.Genderless)

View file

@ -209,7 +209,7 @@ public static class EncounterMovesetGenerator
private static bool IsSane(PKM pk, ReadOnlySpan<ushort> moves)
{
var species = pk.Species;
if ((uint)(species - 1) >= pk.MaxSpeciesID) // can enter this method after failing to set a species ID that cannot exist in the format
if (species - 1u >= pk.MaxSpeciesID) // can enter this method after failing to set a species ID that cannot exist in the format
return false;
if (AnyMoveOutOfRange(moves, pk.MaxMoveID))
return false;

View file

@ -74,7 +74,7 @@ public record struct EncounterEnumerator9(PKM Entity, EvoCriteria[] Chain, GameV
case YieldState.Bred:
State = YieldState.TradeStart;
if (EncounterGenerator9.TryGetEgg(Entity, Chain, Version, out var egg))
if (Locations.IsEggLocationBred9(Entity.Egg_Location) && EncounterGenerator9.TryGetEgg(Entity, Chain, Version, out var egg))
return SetCurrent(egg);
goto case YieldState.TradeStart;

View file

@ -78,7 +78,7 @@ public sealed record EncounterSlot7GO(int StartDate, int EndDate, ushort Species
{
var g = Gender == Gender.Random ? -1 : (int)Gender;
int gender = criteria.GetGender(g, PersonalTable.GG[Species]);
int nature = (int)criteria.GetNature(Nature.Random);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
criteria.SetRandomIVsGO(pk, Type.GetMinIV());

View file

@ -170,7 +170,7 @@ public sealed record EncounterSlot8GO(int StartDate, int EndDate, ushort Species
pk.EXP = Experience.GetEXP(LevelMin, pi.EXPGrowth);
var g = Gender == Gender.Random ? -1 : (int)Gender;
int gender = criteria.GetGender(g, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
pk.Nature = pk.StatNature = nature;

View file

@ -58,7 +58,7 @@ public sealed record EncounterGift1(ushort Species, byte Level, GameVersion Vers
Species = Species,
CurrentLevel = LevelMin,
Catch_Rate = GetInitialCatchRate(),
DV16 = EncounterUtil1.GetRandomDVs(Util.Rand),
DV16 = IVs.IsSpecified ? EncounterUtil1.GetDV16(IVs) : EncounterUtil1.GetRandomDVs(Util.Rand),
OT_Name = EncounterUtil1.GetTrainerName(tr, lang),
TID16 = tr.TID16,

View file

@ -90,8 +90,8 @@ public sealed record EncounterGift3Colo : IEncounterable, IEncounterMatch, IEnco
private void SetPINGA(CK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
do
{

View file

@ -38,7 +38,7 @@ public sealed record EncounterShadow3Colo(byte ID, short Gauge, ReadOnlyMemory<T
/// <summary>
/// Originates from the EReader scans (Japanese Only)
/// </summary>
public bool EReader => Location == 128; // @ Card e Room (Japanese games only)
public bool IsEReader => Location == 128; // @ Card e Room (Japanese games only)
#region Generating
PKM IEncounterConvertible.ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria) => ConvertToPKM(tr, criteria);
@ -77,11 +77,11 @@ public sealed record EncounterShadow3Colo(byte ID, short Gauge, ReadOnlyMemory<T
return pk;
}
private int GetTemplateLanguage(ITrainerInfo tr) => EReader ? 1 : (int)Language.GetSafeLanguage(Generation, (LanguageID)tr.Language);
private int GetTemplateLanguage(ITrainerInfo tr) => IsEReader ? 1 : (int)Language.GetSafeLanguage(Generation, (LanguageID)tr.Language);
private void SetPINGA(CK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
if (!EReader)
if (!IsEReader)
SetPINGA_Regular(pk, criteria, pi);
else
SetPINGA_EReader(pk);
@ -89,9 +89,9 @@ public sealed record EncounterShadow3Colo(byte ID, short Gauge, ReadOnlyMemory<T
private void SetPINGA_Regular(CK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int ability = criteria.GetAbilityFromNumber(0);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
int ability = criteria.GetAbilityFromNumber(Ability);
// Ensure that any generated specimen has valid Shadow Locks
// This can be kinda slow, depending on how many locks / how strict they are.
@ -108,7 +108,7 @@ public sealed record EncounterShadow3Colo(byte ID, short Gauge, ReadOnlyMemory<T
}
while (++ctr <= max);
System.Diagnostics.Debug.Assert(ctr < 100_000);
System.Diagnostics.Debug.Assert(ctr < max);
}
private void SetPINGA_EReader(CK3 pk)
@ -139,7 +139,7 @@ public sealed record EncounterShadow3Colo(byte ID, short Gauge, ReadOnlyMemory<T
while (++ctr <= max);
#if DEBUG
System.Diagnostics.Debug.Assert(ctr < 100_000);
System.Diagnostics.Debug.Assert(ctr < max);
#endif
}
@ -200,14 +200,14 @@ public sealed record EncounterShadow3Colo(byte ID, short Gauge, ReadOnlyMemory<T
public bool IsCompatible(PIDType val, PKM pk)
{
if (EReader)
if (IsEReader)
return true;
return val is PIDType.CXD;
}
public PIDType GetSuggestedCorrelation()
{
if (EReader)
if (IsEReader)
return PIDType.None;
return PIDType.CXD;
}

View file

@ -72,12 +72,11 @@ public sealed record EncounterStatic3Colo(ushort Species, byte Level)
private void SetPINGA(CK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
int gender = criteria.GetGender(Gender, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
const PIDType type = PIDType.CXD;
do
{
PIDGenerator.SetRandomWildPID4(pk, nature, ability, gender, type);
PIDGenerator.SetRandomWildPID4(pk, nature, ability, gender, PIDType.CXD);
} while (Shiny == Shiny.Never && pk.IsShiny);
}
#endregion

View file

@ -61,8 +61,8 @@ public record EncounterSlot3(EncounterArea3 Parent, ushort Species, byte Form, b
private void SetPINGA(PK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
if (Species == (int)Core.Species.Unown)
{

View file

@ -93,29 +93,14 @@ public sealed record EncounterStatic3(ushort Species, byte Level, GameVersion Ve
private void SetPINGA(PK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
if (Species == (int)Core.Species.Unown)
var type = Roaming && Version != GameVersion.E ? PIDType.Method_1_Roamer : PIDType.Method_1;
do
{
do
{
PIDGenerator.SetRandomWildPID4(pk, nature, ability, gender, PIDType.Method_1_Unown);
ability ^= 1; // some nature-forms cannot have a certain PID-ability set, so just flip it as Unown doesn't have dual abilities.
} while (pk.Form != Form);
}
else
{
PIDType type = this switch
{
{ Roaming: true, Version: not GameVersion.E } => PIDType.Method_1_Roamer,
_ => PIDType.Method_1,
};
do
{
PIDGenerator.SetRandomWildPID4(pk, nature, ability, gender, type);
} while (Shiny == Shiny.Never && pk.IsShiny);
}
PIDGenerator.SetRandomWildPID4(pk, nature, ability, gender, type);
} while (Shiny == Shiny.Never && pk.IsShiny);
}
#endregion

View file

@ -79,9 +79,9 @@ public sealed record EncounterShadow3XD(byte ID, short Gauge, ReadOnlyMemory<Tea
private void SetPINGA(XK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int ability = criteria.GetAbilityFromNumber(0);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
int ability = criteria.GetAbilityFromNumber(Ability);
// Ensure that any generated specimen has valid Shadow Locks
// This can be kinda slow, depending on how many locks / how strict they are.
@ -98,7 +98,7 @@ public sealed record EncounterShadow3XD(byte ID, short Gauge, ReadOnlyMemory<Tea
}
while (++ctr <= max);
System.Diagnostics.Debug.Assert(ctr < 100_000);
System.Diagnostics.Debug.Assert(ctr < max);
}
#endregion

View file

@ -60,8 +60,8 @@ public sealed record EncounterSlot3XD(EncounterArea3XD Parent, ushort Species, b
private void SetPINGA(XK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
int ability = criteria.GetAbilityFromNumber(Ability);
PIDGenerator.SetRandomPokeSpotPID(pk, nature, gender, ability, SlotNumber);
}

View file

@ -71,25 +71,13 @@ public sealed record EncounterStatic3XD(ushort Species, byte Level)
private void SetPINGA(XK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
if (Species == (int)Core.Species.Unown)
do
{
do
{
PIDGenerator.SetRandomWildPID4(pk, nature, ability, gender, PIDType.Method_1_Unown);
ability ^= 1; // some nature-forms cannot have a certain PID-ability set, so just flip it as Unown doesn't have dual abilities.
} while (pk.Form != Form);
}
else
{
const PIDType type = PIDType.CXD;
do
{
PIDGenerator.SetRandomWildPID4(pk, nature, ability, gender, type);
} while (Shiny == Shiny.Never && pk.IsShiny);
}
PIDGenerator.SetRandomWildPID4(pk, nature, ability, gender, PIDType.CXD);
} while (Shiny == Shiny.Never && pk.IsShiny);
}
#endregion

View file

@ -93,8 +93,8 @@ public sealed record EncounterTrade3XD : IEncounterable, IEncounterMatch, IEncou
private void SetPINGA(XK3 pk, EncounterCriteria criteria, PersonalInfo3 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
if (Species == (int)Core.Species.Unown)
{

View file

@ -78,8 +78,8 @@ public sealed record EncounterSlot4(EncounterArea4 Parent, ushort Species, byte
private void SetPINGA(PK4 pk, EncounterCriteria criteria, PersonalInfo4 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
int ctr = 0;
do

View file

@ -99,7 +99,7 @@ public sealed record EncounterStatic4Pokewalker(PokewalkerCourse4 Course)
private void SetPINGA(PK4 pk, EncounterCriteria criteria, PersonalInfo4 pi)
{
int gender = criteria.GetGender(Gender, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int nature = (int)criteria.GetNature();
// Cannot force an ability; nature-gender-trainerID only yield fixed PIDs.
// int ability = criteria.GetAbilityFromNumber(Ability, pi);

View file

@ -82,8 +82,8 @@ public sealed record EncounterSlot5(EncounterArea5 Parent, ushort Species, byte
private void SetPINGA(PK5 pk, EncounterCriteria criteria, PersonalInfo5B2W2 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
PIDGenerator.SetRandomWildPID5(pk, nature, ability, gender);
criteria.SetRandomIVs(pk);

View file

@ -84,7 +84,7 @@ public sealed record EncounterStatic5(GameVersion Version)
private void SetPINGA(PK5 pk, EncounterCriteria criteria, PersonalInfo5B2W2 pi)
{
int gender = criteria.GetGender(Gender, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
var type = Shiny == Shiny.Always ? PIDType.G5MGShiny : PIDType.None;
PIDGenerator.SetRandomWildPID5(pk, nature, ability, gender, type);

View file

@ -70,7 +70,7 @@ public sealed record EncounterStatic5Entree(GameVersion Version, ushort Species,
private void SetPINGA(PK5 pk, EncounterCriteria criteria, PersonalInfo5B2W2 pi)
{
int gender = criteria.GetGender(Gender, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
PIDGenerator.SetRandomWildPID5(pk, nature, ability, gender);
if (pk.IsShiny)

View file

@ -62,8 +62,8 @@ public sealed record EncounterStatic5Radar(ushort Species, byte Form, AbilityPer
private void SetPINGA(PK5 pk, EncounterCriteria criteria, PersonalInfo5B2W2 pi)
{
int gender = criteria.GetGender(-1, pi);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pi);
int nature = (int)criteria.GetNature();
var ability = criteria.GetAbilityFromNumber(Ability);
PIDGenerator.SetRandomWildPID5(pk, nature, ability, gender);
if (pk.IsShiny)

View file

@ -106,8 +106,8 @@ public sealed record EncounterSlot6AO(EncounterArea6AO Parent, ushort Species, b
{
pk.PID = Util.Rand32();
pk.EncryptionConstant = Util.Rand32();
pk.Nature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(pi);
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
criteria.SetRandomIVs(pk);
}

View file

@ -96,8 +96,8 @@ public sealed record EncounterSlot6XY(EncounterArea6XY Parent, ushort Species, b
var pi = PersonalTable.XY.GetFormEntry(Species, Form);
pk.PID = Util.Rand32();
pk.EncryptionConstant = Util.Rand32();
pk.Nature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(pi);
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
criteria.SetRandomIVs(pk, FlawlessIVCount);
}

View file

@ -90,8 +90,8 @@ public sealed record EncounterSlot7(EncounterArea7 Parent, ushort Species, byte
{
pk.PID = Util.Rand32();
pk.EncryptionConstant = Util.Rand32();
pk.Nature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(pi);
criteria.SetRandomIVs(pk);
var num = Ability;

View file

@ -63,8 +63,8 @@ public sealed record EncounterSlot7b(EncounterArea7b Parent, ushort Species, byt
{
pk.PID = Util.Rand32();
pk.EncryptionConstant = Util.Rand32();
pk.Nature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(pi);
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
criteria.SetRandomIVs(pk);

View file

@ -71,8 +71,8 @@ public sealed record EncounterStatic7b(GameVersion Version)
{
pk.PID = Util.Rand32();
pk.EncryptionConstant = Util.Rand32();
pk.Nature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(pi);
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
if (IVs.IsSpecified)

View file

@ -89,8 +89,8 @@ public sealed record EncounterTrade7b(GameVersion Version) : IEncounterable, IEn
{
pk.PID = Util.Rand32();
pk.EncryptionConstant = Util.Rand32();
pk.Nature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(pi);
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
criteria.SetRandomIVs(pk, IVs);
}

View file

@ -102,8 +102,8 @@ public sealed record EncounterSlot8(EncounterArea8 Parent, ushort Species, byte
pk.EncryptionConstant = rand.Rand32();
pk.PID = rand.Rand32();
criteria.SetRandomIVs(pk);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = pk.StatNature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(pi);
pk.Nature = pk.StatNature = (int)criteria.GetNature();
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
return;
}

View file

@ -115,8 +115,8 @@ public sealed record EncounterStatic8(GameVersion Version = GameVersion.SWSH)
var pi = PersonalTable.SWSH[Species, Form];
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
pk.Nature = pk.StatNature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = pk.StatNature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(pi);
var req = GetRequirement(pk);
if (req != MustHave)

View file

@ -97,8 +97,8 @@ public sealed record EncounterSlot8b(EncounterArea8b Parent, ushort Species, byt
pk.PID = Util.Rand32();
pk.EncryptionConstant = Util.Rand32();
criteria.SetRandomIVs(pk);
pk.Nature = pk.StatNature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = pk.StatNature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(pi);
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
}

View file

@ -123,8 +123,8 @@ public sealed record EncounterFixed9
{
pk.PID = Util.Rand32();
pk.EncryptionConstant = Util.Rand32();
pk.Nature = pk.StatNature = (int)criteria.GetNature(Nature.Random);
pk.Gender = criteria.GetGender(-1, pi);
pk.Nature = pk.StatNature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(pi);
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
criteria.SetRandomIVs(pk, FlawlessIVCount);

View file

@ -133,7 +133,7 @@ public sealed record EncounterSlot9(EncounterArea9 Parent, ushort Species, byte
pk.EncryptionConstant = Util.Rand32();
criteria.SetRandomIVs(pk);
pk.Nature = pk.StatNature = (int)criteria.GetNature(Nature.Random);
pk.Nature = pk.StatNature = (int)criteria.GetNature();
pk.Gender = criteria.GetGender(Gender, pi);
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));

View file

@ -120,8 +120,8 @@ public sealed record EncounterEgg(ushort Species, byte Form, byte Level, int Gen
if (pk.Format <= 2)
return;
int gender = criteria.GetGender(-1, pk.PersonalInfo);
int nature = (int)criteria.GetNature(Nature.Random);
int gender = criteria.GetGender(pk.PersonalInfo);
int nature = (int)criteria.GetNature();
if (pk.Format <= 5)
{

View file

@ -22,7 +22,7 @@ public static class EncounterVerifier
private static CheckResult VerifyEncounter(PKM pk, IEncounterTemplate enc) => enc switch
{
EncounterEgg e => VerifyEncounterEgg(pk, e.Generation),
EncounterShadow3Colo { EReader: true } when pk.Language != (int)LanguageID.Japanese => GetInvalid(LG3EReader),
EncounterShadow3Colo { IsEReader: true } when pk.Language != (int)LanguageID.Japanese => GetInvalid(LG3EReader),
EncounterStatic3 { Species: (int)Species.Mew, Location: 201 } when pk.Language != (int)LanguageID.Japanese => GetInvalid(LEncUnreleasedEMewJP),
EncounterStatic3 { Species: (int)Species.Deoxys, Location: 200 } when pk.Language == (int)LanguageID.Japanese => GetInvalid(LEncUnreleased),
EncounterStatic4 { Roaming: true } when pk is G4PKM { Met_Location: 193, GroundTile: GroundTileType.Water } => GetInvalid(LG4InvalidTileR45Surf),

View file

@ -291,8 +291,7 @@ public static class PIDGenerator
// Pokewalker PIDs cannot yield multiple abilities from the input nature-gender-trainerID. Disregard any ability request.
var pi = pk.PersonalInfo.Gender;
pk.Gender = gender;
do pk.PID = GetPokeWalkerPID(pk.TID16, pk.SID16, (uint)nature, gender, pi);
while (!pk.IsGenderValid());
pk.PID = GetPokeWalkerPID(pk.TID16, pk.SID16, (uint)nature, gender, pi);
pk.RefreshAbility((int) (pk.PID & 1));
}

View file

@ -267,7 +267,12 @@ public sealed class MiscVerifier : Verifier
if (pk is ICaughtData2 { CaughtData: not 0 } t)
{
var time = t.Met_TimeOfDay;
bool valid = data.EncounterOriginal is EncounterTrade2 ? time == 0 : time is 1 or 2 or 3;
bool valid = data.EncounterOriginal switch
{
EncounterGift2 => time == 0,
EncounterTrade2 => time == 0,
_ => time is 1 or 2 or 3,
};
if (!valid)
data.AddLine(new CheckResult(Severity.Invalid, Encounter, LMetDetailTimeOfDay));
}

View file

@ -297,7 +297,7 @@ public sealed class PGF : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, I
{
var pi = PersonalTable.B2W2.GetFormEntry(Species, Form);
pk.Nature = (int)criteria.GetNature((Nature)Nature);
pk.Gender = pi.Genderless ? 2 : Gender != 2 ? Gender : criteria.GetGender(-1, pi);
pk.Gender = pi.Genderless ? 2 : Gender != 2 ? Gender : criteria.GetGender(pi);
var av = GetAbilityIndex(criteria);
SetPID(pk, av);
pk.RefreshAbility(av);

View file

@ -212,7 +212,7 @@ public sealed class PGT : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, I
if ((pk4.IV32 & 0x3FFF_FFFFu) == 0) // Ignore Nickname/Egg flag bits
{
uint iv1 = ((seed = LCRNG.Next(seed)) >> 16) & 0x7FFF;
uint iv2 = ((LCRNG.Next(seed)) >> 16) & 0x7FFF;
uint iv2 = (LCRNG.Next(seed) >> 16) & 0x7FFF;
pk4.IV32 |= iv1 | (iv2 << 15);
}
}
@ -225,7 +225,7 @@ public sealed class PGT : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, I
// The games don't decide the Nature/Gender up-front, but we can try to honor requests.
// Pre-determine the result values, and generate something.
var n = (int)criteria.GetNature(Nature.Random);
var n = (int)criteria.GetNature();
// Gender is already pre-determined in the template.
while (true)
{
@ -258,25 +258,25 @@ public sealed class PGT : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, I
uint pid1 = (seed = LCRNG.Next(seed)) >> 16; // low
uint pid2 = (seed = LCRNG.Next(seed)) & 0xFFFF0000; // hi
pk4.PID = pid2 | pid1;
while (pk4.IsShiny) // Call the ARNG to change the PID
pk4.PID = ARNG.Next(pk4.PID);
// sanity check gender for non-genderless PID cases
} while (!pk4.IsGenderValid());
while (pk4.IsShiny) // Call the ARNG to change the PID
pk4.PID = ARNG.Next(pk4.PID);
return seed;
}
public static bool IsRangerManaphy(PKM pk)
{
if (pk.Language >= (int)LanguageID.Korean) // never korean
return false;
var egg = pk.Egg_Location;
if (!pk.IsEgg) // Link Trade Egg or Ranger
return egg is Locations.LinkTrade4 or Locations.Ranger4;
if (egg != Locations.Ranger4)
return false;
if (pk.Language == (int)LanguageID.Korean) // never korean
return false;
var met = pk.Met_Location;
return met is Locations.LinkTrade4 or 0;
}

View file

@ -32,7 +32,7 @@ public enum SCTypeCode : byte
public static class SCTypeCodeExtensions
{
public static bool IsBoolean(this SCTypeCode type) => unchecked((uint)type - 1) < 3;
public static bool IsBoolean(this SCTypeCode type) => unchecked((uint)type - 1u) < 3;
public static int GetTypeSize(this SCTypeCode type) => type switch
{

View file

@ -179,7 +179,7 @@ public sealed class GP1 : IEncounterInfo, IFixedAbilityNumber, IScaledSizeReadOn
var pi = pk.PersonalInfo;
pk.Gender = criteria.GetGender(Gender, pi);
pk.Nature = (int)criteria.GetNature(Nature.Random);
pk.Nature = (int)criteria.GetNature();
pk.RefreshAbility(criteria.GetAbilityFromNumber(Ability));
bool isShiny = pk.IsShiny;

View file

@ -152,7 +152,7 @@ public abstract class Zukan<T> : ZukanBase<T> where T : SaveFile
public override void SetDex(PKM pk)
{
if ((uint)(pk.Species - 1) >= SAV.MaxSpeciesID) // out of range
if (pk.Species - 1u >= SAV.MaxSpeciesID) // out of range
return;
if (pk.IsEgg) // do not add
return;

View file

@ -58,7 +58,7 @@ public partial class ReportGrid : Form
foreach (var entry in Data)
{
var pk = entry.Entity;
if ((uint)(pk.Species - 1) >= pk.MaxSpeciesID)
if (pk.Species - 1u >= pk.MaxSpeciesID)
{
continue;
}