diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen6/EncounterSlot6AO.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen6/EncounterSlot6AO.cs
index 0314a3733..c9bb0b699 100644
--- a/PKHeX.Core/Legality/Encounters/Templates/Gen6/EncounterSlot6AO.cs
+++ b/PKHeX.Core/Legality/Encounters/Templates/Gen6/EncounterSlot6AO.cs
@@ -7,7 +7,7 @@ namespace PKHeX.Core;
/// Encounter Slot found in .
///
public sealed record EncounterSlot6AO(EncounterArea6AO Parent, ushort Species, byte Form, byte LevelMin, byte LevelMax)
- : IEncounterable, IEncounterMatch, IEncounterConvertible, IEncounterFormRandom
+ : IEncounterable, IEncounterMatch, IEncounterConvertible, IEncounterFormRandom, IEncounterDownlevel
{
public byte Generation => 6;
public EntityContext Context => EntityContext.Gen6;
@@ -121,6 +121,8 @@ public sealed record EncounterSlot6AO(EncounterArea6AO Parent, ushort Species, b
private const int FluteBoostMax = 4; // Black Flute increases levels.
private const int DexNavBoost = 29 + FluteBoostMax; // Maximum DexNav chain (95) and Flute.
+ public byte GetDownleveledMin() => (byte)(LevelMin - FluteBoostMin);
+
public bool IsMatchExact(PKM pk, EvoCriteria evo)
{
var boostMax = Type != Rock_Smash ? DexNavBoost : FluteBoostMax;
diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8N.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8N.cs
index 71113735a..c72d36727 100644
--- a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8N.cs
+++ b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8N.cs
@@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// Generation 8 Nest Encounter (Regular Raid Dens)
///
///
-public sealed record EncounterStatic8N : EncounterStatic8Nest
+public sealed record EncounterStatic8N : EncounterStatic8Nest, IEncounterDownlevel
{
private readonly byte MinRank;
private readonly byte MaxRank;
@@ -77,6 +77,10 @@ public sealed record EncounterStatic8N : EncounterStatic8Nest
return metLevel % 10 <= 5;
}
+ private const byte SharedNestMinLevel = 20;
+
+ public byte GetDownleveledMin() => SharedNestMinLevel;
+
public bool IsDownLeveled(PKM pk)
{
var met = pk.MetLevel;
@@ -91,7 +95,7 @@ public sealed record EncounterStatic8N : EncounterStatic8Nest
// shared nests can be down-leveled to any
if (pk.MetLocation == SharedNest)
- return met >= 20;
+ return met >= SharedNestMinLevel;
// native down-levels: only allow 1 rank down (1 badge 2star -> 25), (3badge 3star -> 35)
return ((MinRank <= 1 && 1 <= MaxRank && met == 25)
diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8NC.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8NC.cs
index 6fac123d4..ddb6072f4 100644
--- a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8NC.cs
+++ b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8NC.cs
@@ -6,7 +6,7 @@ namespace PKHeX.Core;
/// Generation 8 Nest Encounter (Distributed Crystal Data)
///
///
-public sealed record EncounterStatic8NC(GameVersion Version) : EncounterStatic8Nest(Version), ILocation
+public sealed record EncounterStatic8NC(GameVersion Version) : EncounterStatic8Nest(Version), ILocation, IEncounterDownlevel
{
ushort ILocation.Location => Watchtower;
public const ushort Location = Watchtower;
@@ -20,6 +20,10 @@ public sealed record EncounterStatic8NC(GameVersion Version) : EncounterStatic8N
return loc is SharedNest or Watchtower;
}
+ private const byte SharedNestMinLevel = 20;
+
+ public byte GetDownleveledMin() => SharedNestMinLevel;
+
protected override bool IsMatchLevel(PKM pk)
{
var lvl = pk.MetLevel;
@@ -29,7 +33,7 @@ public sealed record EncounterStatic8NC(GameVersion Version) : EncounterStatic8N
// Check downleveled (20-55)
if (lvl > Level)
return false;
- if (lvl is < 20 or > 55)
+ if (lvl is < SharedNestMinLevel or > 55)
return false;
if (pk is { MetLocation: Watchtower, IsShiny: true })
return false; // host cannot downlevel and be shiny
diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8ND.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8ND.cs
index ae1e44cba..adf32d3b2 100644
--- a/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8ND.cs
+++ b/PKHeX.Core/Legality/Encounters/Templates/Gen8/EncounterStatic8ND.cs
@@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// Generation 8 Nest Encounter (Distributed Data)
///
///
-public sealed record EncounterStatic8ND : EncounterStatic8Nest
+public sealed record EncounterStatic8ND : EncounterStatic8Nest, IEncounterDownlevel
{
///
/// Distribution raid index for
@@ -56,6 +56,10 @@ public sealed record EncounterStatic8ND : EncounterStatic8Nest SharedNestMinLevel;
+
protected override bool IsMatchLevel(PKM pk)
{
var lvl = pk.MetLevel;
@@ -73,7 +77,7 @@ public sealed record EncounterStatic8ND : EncounterStatic8Nest Level)
return false;
- if (lvl is < 20 or > 55)
+ if (lvl is < SharedNestMinLevel or > 55)
return false;
if (lvl % 5 != 0)
diff --git a/PKHeX.Core/PKM/Interfaces/Templates/IEncounterDownlevel.cs b/PKHeX.Core/PKM/Interfaces/Templates/IEncounterDownlevel.cs
new file mode 100644
index 000000000..adf6decf7
--- /dev/null
+++ b/PKHeX.Core/PKM/Interfaces/Templates/IEncounterDownlevel.cs
@@ -0,0 +1,12 @@
+namespace PKHeX.Core;
+
+///
+/// Interface for encounters that can be down-leveled by an additional game situation.
+///
+public interface IEncounterDownlevel
+{
+ ///
+ /// Get the minimum level when forcibly down-leveled by an additional game situation.
+ ///
+ byte GetDownleveledMin();
+}