diff --git a/PKHeX.Core/Legality/Encounters/Templates/GO/EncounterSlot7GO.cs b/PKHeX.Core/Legality/Encounters/Templates/GO/EncounterSlot7GO.cs index beb7d0969..33a5e6932 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/GO/EncounterSlot7GO.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/GO/EncounterSlot7GO.cs @@ -23,6 +23,7 @@ public sealed record EncounterSlot7GO(ushort DayStart, ushort DayEnd, ushort Spe public byte LevelMax => EncountersGO.MAX_LEVEL; public bool IsLocalDayStart => Flags.HasFlag(PogoFlags.LocalDateStart); public bool IsLocalDayEnd => Flags.HasFlag(PogoFlags.LocalDateEnd); + public bool IsAlwaysSpecialTrade => Flags.HasFlag(PogoFlags.AlwaysSpecialTrade); public string Name => $"GO Encounter ({Version})"; public string LongName @@ -164,4 +165,5 @@ public enum PogoFlags : byte LocalDateStart = 1 << 0, LocalDateEnd = 1 << 1, FeaturedWildArea = 1 << 2, + AlwaysSpecialTrade = 1 << 4, } diff --git a/PKHeX.Core/Legality/Encounters/Templates/GO/EncounterSlot8GO.cs b/PKHeX.Core/Legality/Encounters/Templates/GO/EncounterSlot8GO.cs index 63bf5d2e1..eee2fb27c 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/GO/EncounterSlot8GO.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/GO/EncounterSlot8GO.cs @@ -22,6 +22,7 @@ public sealed record EncounterSlot8GO(ushort DayStart, ushort DayEnd, ushort Spe public byte LevelMax => EncountersGO.MAX_LEVEL; public bool IsLocalDayStart => Flags.HasFlag(PogoFlags.LocalDateStart); public bool IsLocalDayEnd => Flags.HasFlag(PogoFlags.LocalDateEnd); + public bool IsAlwaysSpecialTrade => Flags.HasFlag(PogoFlags.AlwaysSpecialTrade); public string Name => $"GO Encounter ({Version})"; public string LongName @@ -249,8 +250,6 @@ public EncounterMatchRating GetMatchRating(PKM pk) return EncounterMatchRating.DeferredErrors; if (pk is ITeraType ro && IsTeraTypeMismatch(ro.TeraTypeOriginal, PersonalTable.SV[Species, Form])) return EncounterMatchRating.DeferredErrors; - if (!this.GetIVsValid(pk)) - return EncounterMatchRating.Deferred; return EncounterMatchRating.Match; } @@ -294,7 +293,7 @@ private bool IsMatchPartial(PKM pk) { if (!IsWithinDistributionWindow(pk)) return true; - if (!this.GetIVsAboveMinimum(pk)) + if (!this.GetIVsValid(pk)) return true; // Eevee & Glaceon have different base friendships. Make sure if it is invalid that we yield the other encounter before. diff --git a/PKHeX.Core/Legality/Encounters/Templates/GO/IPogoSlot.cs b/PKHeX.Core/Legality/Encounters/Templates/GO/IPogoSlot.cs index d91120e15..30d700671 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/GO/IPogoSlot.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/GO/IPogoSlot.cs @@ -16,6 +16,9 @@ public interface IPogoSlot : IPogoDateRange /// Minimum IV value for the encounter. byte MinimumIV { get; } + + /// If trading this Pokémon always results in a Special Trade. + bool IsAlwaysSpecialTrade { get; } } /// @@ -42,9 +45,20 @@ private static bool GetIVsAboveMinimum(PKM pk, int min) public static bool GetIVsValid(this IPogoSlot slot, PKM pk) { - if (!slot.GetIVsAboveMinimum(pk)) + if (!slot.GetIVsAboveMinimum(pk) && slot.IsAlwaysSpecialTrade) return false; + // when trading with new friends, the IV floor is 0 before reaching Good Friends, as long as it is not a Special Trade + if (slot.MinimumIV == 1 && (pk.IV_HP == 1 || (pk.IV_ATK == 1 && pk.IV_SPA == 1) || (pk.IV_DEF == 1 && pk.IV_SPD == 1))) + { + if (pk.IsShiny) + return false; + if (SpeciesCategory.IsSpecialPokemon(pk.Species)) + return false; + if (slot.Type.IsShadow) + return false; + } + // HP * 2 | 1 -> HP // ATK * 2 | 1 -> ATK&SPA // DEF * 2 | 1 -> DEF&SPD diff --git a/PKHeX.Core/Legality/Encounters/Templates/GO/PogoType.cs b/PKHeX.Core/Legality/Encounters/Templates/GO/PogoType.cs index d9b7a3f7b..d9d9f9e1b 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/GO/PogoType.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/GO/PogoType.cs @@ -77,6 +77,13 @@ or PogoType.RaidShadow or PogoType.RaidShadowMythical or PogoType.RaidShadowUltraBeast; + public bool IsShadow => type is PogoType.Shadow + or PogoType.ShadowMythical + or PogoType.ShadowUltraBeast + or PogoType.RaidShadow + or PogoType.RaidShadowMythical + or PogoType.RaidShadowUltraBeast; + public bool IsMaxBattle => type is PogoType.MaxBattle or PogoType.MaxBattleMythical or PogoType.MaxBattleUltraBeast @@ -119,8 +126,8 @@ public bool IsSafariBallUsable(PogoType type, PogoFlags flags) { if (ball is PogoBallRestriction.OnlySafari) return true; - if (!flags.HasFlag(PogoFlags.FeaturedWildArea) && (type.IsRaid || type.IsMaxBattle)) - return false; + if (type.IsRaid || type.IsMaxBattle) + return flags.HasFlag(PogoFlags.FeaturedWildArea); return type switch {