diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/EncounterSlot8GO.cs b/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/EncounterSlot8GO.cs
index a1653901b..8b77a4121 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/EncounterSlot8GO.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/EncounterSlot8GO.cs
@@ -66,6 +66,8 @@ private bool IsMatchPartial(PKM pk)
return true;
if (!GetIVsAboveMinimum(pk))
return true;
+ if (!GetIVsBelowMaximum(pk))
+ return true;
// Eevee & Glaceon have different base friendships. Make sure if it is invalid that we yield the other encounter before.
if (PersonalTable.SWSH.GetFormEntry(Species, Form).BaseFriendship != pk.OT_Friendship)
diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/EncounterSlotGO.cs b/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/EncounterSlotGO.cs
index e37ecbc16..5ba7c8e6a 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/EncounterSlotGO.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/EncounterSlotGO.cs
@@ -93,15 +93,25 @@ protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteri
pk.MetDate = GetRandomValidDate();
if (Gender != Gender.Random)
pk.Gender = (int)Gender;
- pk.SetRandomIVsGO(Type.GetMinIV());
+ pk.SetRandomIVsGO(Type.GetMinIV(), Type.GetMaxIV());
}
public bool GetIVsAboveMinimum(PKM pkm)
{
int min = Type.GetMinIV();
+ if (min == 0)
+ return false;
return GetIVsAboveMinimum(pkm, min);
}
+ public bool GetIVsBelowMaximum(PKM pkm)
+ {
+ int max = Type.GetMaxIV();
+ if (max == 15)
+ return false;
+ return GetIVsBelowMaximum(pkm, max);
+ }
+
private static bool GetIVsAboveMinimum(PKM pkm, int min)
{
if (pkm.IV_ATK >> 1 < min) // ATK
@@ -111,10 +121,21 @@ private static bool GetIVsAboveMinimum(PKM pkm, int min)
return pkm.IV_HP >> 1 >= min; // HP
}
+ private static bool GetIVsBelowMaximum(PKM pkm, int max)
+ {
+ if (pkm.IV_ATK >> 1 > max) // ATK
+ return false;
+ if (pkm.IV_DEF >> 1 > max) // DEF
+ return false;
+ return pkm.IV_HP >> 1 <= max; // HP
+ }
+
public bool GetIVsValid(PKM pkm)
{
if (!GetIVsAboveMinimum(pkm))
return false;
+ if (!GetIVsBelowMaximum(pkm))
+ return false;
// HP * 2 | 1 -> HP
// ATK * 2 | 1 -> ATK&SPA
diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/PogoType.cs b/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/PogoType.cs
index ba0db6762..e1685ee85 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/PogoType.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterSlot/GO/PogoType.cs
@@ -31,6 +31,12 @@ public enum PogoType : byte
GBL,
/// GO Battle League Reward (Mythical), requires Lv. 20 and IV = 10
GBLM,
+ /// GO Battle League Reward, requires Lv. 20 and IV = 0
+ /// On GO Battle Day (September 18, 2021), IV floor and ceiling were both temporarily set to 0 for non-Legendary encounters. This was fixed at 14:43 UTC (September 17, 2021).
+ GBLZero,
+ /// GO Battle League Reward, requires Lv. 20 and IV = 0
+ /// On GO Battle Day (September 18, 2021), IV floor was set to 0 after a mishap that also set the IV ceiling to 0.
+ GBLDay,
/// Purified, requires Lv. 8 and IV = 1 (Premier Ball only)
Shadow = 30,
@@ -68,9 +74,22 @@ public static class PogoTypeExtensions
PogoType.ResearchM => 10,
PogoType.ResearchP => 10,
PogoType.GBLM => 10,
+ PogoType.GBLZero => 0,
+ PogoType.GBLDay => 0,
_ => 1,
};
+ ///
+ /// Gets the minimum IVs (relative to GO's 0-15) the must have.
+ ///
+ /// Descriptor indicating how the Pokémon was encountered in GO.
+ /// Required minimum IV (0-15)
+ public static int GetMaxIV(this PogoType encounterType) => encounterType switch
+ {
+ PogoType.GBLZero => 0,
+ _ => 15,
+ };
+
///
/// Checks if the is valid for the .
///
diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs
index 45bb98784..201b88eae 100644
--- a/PKHeX.Core/PKM/PKM.cs
+++ b/PKHeX.Core/PKM/PKM.cs
@@ -895,13 +895,13 @@ public int[] SetRandomIVs(int? flawless = null)
return IVs = ivs;
}
- public int[] SetRandomIVsGO(int minIV = 0)
+ public int[] SetRandomIVsGO(int minIV = 0, int maxIV = 15)
{
int[] ivs = new int[6];
var rnd = Util.Rand;
- ivs[0] = (rnd.Next(minIV, 16) << 1) | 1; // hp
- ivs[1] = ivs[4] = (rnd.Next(minIV, 16) << 1) | 1; // attack
- ivs[2] = ivs[5] = (rnd.Next(minIV, 16) << 1) | 1; // defense
+ ivs[0] = (rnd.Next(minIV, maxIV + 1) << 1) | 1; // hp
+ ivs[1] = ivs[4] = (rnd.Next(minIV, maxIV + 1) << 1) | 1; // attack
+ ivs[2] = ivs[5] = (rnd.Next(minIV, maxIV + 1) << 1) | 1; // defense
ivs[3] = rnd.Next(MaxIV + 1); // speed
return IVs = ivs;
}