diff --git a/PKHeX.Core/Legality/Encounters/EncounterMatchRating.cs b/PKHeX.Core/Legality/Encounters/EncounterMatchRating.cs
index e7965f923..411bc94aa 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterMatchRating.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterMatchRating.cs
@@ -2,16 +2,22 @@ namespace PKHeX.Core
{
public enum EncounterMatchRating
{
- /// Unused
- None,
-
/// Matches all data, no other matches will be better.
Match,
/// Matches most data, might have a better match later.
Deferred,
+ /// Matches most data, might have a better match later. Less preferred than due to potentially small errors in secondary data.
+ DeferredSecondary,
+
+ /// Matches most data, might have a better match later. Less preferred than due to small errors in secondary data.
+ DeferredErrors,
+
/// Matches some data, but will likely have a better match later.
PartialMatch,
+
+ /// Unused
+ None,
}
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlot/EncounterSlot8.cs b/PKHeX.Core/Legality/Encounters/EncounterSlot/EncounterSlot8.cs
index 40a3067c8..6342bd99d 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterSlot/EncounterSlot8.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterSlot/EncounterSlot8.cs
@@ -93,25 +93,25 @@ public override EncounterMatchRating GetMatchRating(PKM pkm)
if (pkm is IRibbonSetMark8 m)
{
if (m.RibbonMarkCurry && (Weather & AreaWeather8.All) == 0)
- return EncounterMatchRating.Deferred;
+ return EncounterMatchRating.DeferredErrors;
if (m.RibbonMarkFishing && (Weather & AreaWeather8.Fishing) == 0)
- return EncounterMatchRating.Deferred;
+ return EncounterMatchRating.DeferredErrors;
// Check if it has a mark and the weather does not permit the mark.
// Tree/Fishing slots should be deferred here and are checked later.
if (!Weather.IsMarkCompatible(m))
- return EncounterMatchRating.Deferred;
+ return EncounterMatchRating.DeferredErrors;
// Galar Mine hidden encounters can only be found via Curry or Fishing.
if(Location is (30 or 54) && SlotType is AreaSlotType8.HiddenMain && !m.RibbonMarkCurry && !SlotType.CanEncounterViaFishing(Weather))
- return EncounterMatchRating.PartialMatch;
+ return EncounterMatchRating.DeferredErrors;
}
var req = GetRequirement(pkm);
return req switch
{
- MustHave when !IsOverworldCorrelationCorrect(pkm) => EncounterMatchRating.Deferred,
- MustNotHave when IsOverworldCorrelationCorrect(pkm) => EncounterMatchRating.Deferred,
+ MustHave when !IsOverworldCorrelationCorrect(pkm) => EncounterMatchRating.DeferredErrors,
+ MustNotHave when IsOverworldCorrelationCorrect(pkm) => EncounterMatchRating.DeferredErrors,
_ => EncounterMatchRating.Match,
};
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs
index fb08df8c0..1fb4af2f4 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs
@@ -289,15 +289,13 @@ public virtual EncounterMatchRating GetMatchRating(PKM pkm)
{
if (IsMatchPartial(pkm))
return EncounterMatchRating.PartialMatch;
- if (IsMatchDeferred(pkm))
- return EncounterMatchRating.Deferred;
- return EncounterMatchRating.Match;
+ return IsMatchDeferred(pkm);
}
///
/// Checks if the provided might not be the best match, or even a bad match due to minor reasons.
///
- protected virtual bool IsMatchDeferred(PKM pkm) => false;
+ protected virtual EncounterMatchRating IsMatchDeferred(PKM pkm) => EncounterMatchRating.Match;
///
/// Checks if the provided is not an exact match due to minor reasons.
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic8.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic8.cs
index a27c2e275..e15fb12b9 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic8.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic8.cs
@@ -86,7 +86,7 @@ public override EncounterMatchRating GetMatchRating(PKM pkm)
var req = GetRequirement(pkm);
bool correlation = IsOverworldCorrelationCorrect(pkm);
if ((req == MustHave) != correlation)
- return EncounterMatchRating.Deferred;
+ return EncounterMatchRating.DeferredErrors;
// Only encounter slots can have these marks; defer for collisions.
if (pkm.Species == (int) Core.Species.Shedinja)
@@ -94,14 +94,14 @@ public override EncounterMatchRating GetMatchRating(PKM pkm)
// Loses Mark on evolution to Shedinja, but not affixed ribbon value.
return pkm switch
{
- IRibbonSetMark8 {RibbonMarkCurry: true} => EncounterMatchRating.Deferred,
+ IRibbonSetMark8 {RibbonMarkCurry: true} => EncounterMatchRating.DeferredErrors,
PK8 {AffixedRibbon: (int) RibbonIndex.MarkCurry} => EncounterMatchRating.Deferred,
_ => EncounterMatchRating.Match
};
}
if (pkm is IRibbonSetMark8 m && (m.RibbonMarkCurry || m.RibbonMarkFishing || m.HasWeatherMark()))
- return EncounterMatchRating.Deferred;
+ return EncounterMatchRating.DeferredErrors;
return EncounterMatchRating.Match;
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic8Nest.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic8Nest.cs
index 36fdc87ea..140cf7f37 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic8Nest.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic8Nest.cs
@@ -43,27 +43,32 @@ public override bool IsMatchExact(PKM pkm, DexLevel evo)
return base.IsMatchExact(pkm, evo);
}
- protected sealed override bool IsMatchDeferred(PKM pkm)
+ protected sealed override EncounterMatchRating IsMatchDeferred(PKM pkm)
{
+ var rating = EncounterMatchRating.Match;
if (Ability != -1) // Any
{
- bool CanBeHidden() => ((PersonalInfoSWSH) PersonalTable.SWSH.GetFormEntry(Species, Form)).HasHiddenAbility;
-
// HA-Only is a strict match. Ability Capsule and Patch can potentially change these.
- if (Ability == 0 && pkm.AbilityNumber == 4)
- return !CanBeHidden(); // 0/1
- if (Ability == 1 && pkm.AbilityNumber != 1)
- return pkm.AbilityNumber != 4 || !CanBeHidden(); // 0
- if (Ability == 2 && pkm.AbilityNumber != 2)
- return pkm.AbilityNumber != 4 || !CanBeHidden(); // 1
+ if (pkm.AbilityNumber == 4)
+ {
+ if (Ability is not 4 && !AbilityVerifier.CanAbilityPatch(8, PersonalTable.SWSH.GetFormEntry(Species, Form).Abilities, pkm.Species))
+ return EncounterMatchRating.DeferredErrors;
+ rating = EncounterMatchRating.Deferred;
+ }
+ if (pkm.AbilityNumber != Ability) // Fixed regular ability
+ {
+ if (Ability is 1 or 2 && !AbilityVerifier.CanAbilityCapsule(8, PersonalTable.SWSH.GetFormEntry(Species, Form).Abilities))
+ return EncounterMatchRating.DeferredErrors;
+ rating = EncounterMatchRating.Deferred;
+ }
}
if (pkm is IMemoryOT m && MemoryPermissions.IsMoveKnowMemory(m.OT_Memory) && !Moves.Contains(m.OT_TextVar))
- return true;
+ return EncounterMatchRating.DeferredSecondary;
if (pkm is IMemoryHT h && MemoryPermissions.IsMoveKnowMemory(h.HT_Memory) && !Moves.Contains(h.HT_TextVar))
- return true;
+ return EncounterMatchRating.DeferredSecondary;
- return base.IsMatchDeferred(pkm);
+ return rating;
}
protected override bool IsMatchPartial(PKM pkm)
diff --git a/PKHeX.Core/Legality/Encounters/Generator/ByGeneration/EncounterGenerator8.cs b/PKHeX.Core/Legality/Encounters/Generator/ByGeneration/EncounterGenerator8.cs
index 5dc6e0454..2c658b83d 100644
--- a/PKHeX.Core/Legality/Encounters/Generator/ByGeneration/EncounterGenerator8.cs
+++ b/PKHeX.Core/Legality/Encounters/Generator/ByGeneration/EncounterGenerator8.cs
@@ -38,8 +38,8 @@ private static IEnumerable GetEncountersMainline(PKM pkm, IReadO
if (ctr == 0) yield break;
}
- IEncounterable? deferred = null;
- IEncounterable? partial = null;
+ IEncounterable? cache = null;
+ EncounterMatchRating rating = None;
// Trades
if (pkm.Met_Location == Locations.LinkTrade6NPC)
@@ -47,23 +47,19 @@ private static IEnumerable GetEncountersMainline(PKM pkm, IReadO
foreach (var z in GetValidEncounterTrades(pkm, chain))
{
var match = z.GetMatchRating(pkm);
- switch (match)
+ if (match == Match)
{
- case Match: yield return z; ++ctr; break;
- case Deferred: deferred ??= z; break;
- case PartialMatch: partial ??= z; break;
+ yield return z;
+ }
+ else if (match < rating)
+ {
+ cache = z;
+ rating = match;
}
}
- if (ctr != 0)
- {
- if (deferred != null)
- yield return deferred;
-
- if (partial != null)
- yield return partial;
- }
-
+ if (cache != null)
+ yield return cache;
yield break;
}
@@ -71,30 +67,33 @@ private static IEnumerable GetEncountersMainline(PKM pkm, IReadO
foreach (var z in GetValidStaticEncounter(pkm, chain))
{
var match = z.GetMatchRating(pkm);
- switch (match)
+ if (match == Match)
{
- case Match: yield return z; break;
- case Deferred: deferred ??= z; break;
- case PartialMatch: partial ??= z; break;
+ yield return z;
+ }
+ else if (match < rating)
+ {
+ cache = z;
+ rating = match;
}
}
foreach (var z in GetValidWildEncounters(pkm, chain))
{
var match = z.GetMatchRating(pkm);
- switch (match)
+ if (match == Match)
{
- case Match: yield return z; break;
- case Deferred: deferred ??= z; break;
- case PartialMatch: partial ??= z; break;
+ yield return z;
+ }
+ else if (match < rating)
+ {
+ cache = z;
+ rating = match;
}
}
- if (deferred != null)
- yield return deferred;
-
- if (partial != null)
- yield return partial;
+ if (cache != null)
+ yield return cache;
}
}
}
diff --git a/PKHeX.Core/Legality/Verifiers/Ability/AbilityVerifier.cs b/PKHeX.Core/Legality/Verifiers/Ability/AbilityVerifier.cs
index a93702d64..26628c439 100644
--- a/PKHeX.Core/Legality/Verifiers/Ability/AbilityVerifier.cs
+++ b/PKHeX.Core/Legality/Verifiers/Ability/AbilityVerifier.cs
@@ -447,7 +447,7 @@ private static bool IsAbilityCapsuleModified(PKM pkm, IReadOnlyList abiliti
return true;
}
- private static bool CanAbilityCapsule(int format, IReadOnlyList abilities)
+ public static bool CanAbilityCapsule(int format, IReadOnlyList abilities)
{
if (format < 6) // Ability Capsule does not exist
return false;
diff --git a/PKHeX.Core/Legality/Verifiers/MemoryPermissions.cs b/PKHeX.Core/Legality/Verifiers/MemoryPermissions.cs
index 051a629ca..e7a6044ba 100644
--- a/PKHeX.Core/Legality/Verifiers/MemoryPermissions.cs
+++ b/PKHeX.Core/Legality/Verifiers/MemoryPermissions.cs
@@ -173,11 +173,15 @@ private static bool GetCanKnowMove(PKM pkm, int move, int generation, IReadOnlyL
return false;
for (int i = 1; i <= generation; i++)
{
- var moves = MoveList.GetValidMoves(pkm, version, evos[i], i, types: MoveSourceType.All);
+ var chain = evos[i];
+ if (chain.Count == 0)
+ continue;
+
+ var moves = MoveList.GetValidMoves(pkm, version, chain, i, types: MoveSourceType.All);
if (moves.Contains(move))
return true;
- if (IsOtherFormMove(pkm, evos[i], move, i, GameVersion.Any, types: MoveSourceType.All))
+ if (IsOtherFormMove(pkm, chain, move, i, GameVersion.Any, types: MoveSourceType.All))
return true;
}
return false;