mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-27 00:44:05 -05:00
Add PIDIV checking for encounters
Fixes HGSS egg moves, and improves encounter detail detection. example: togepi from FRLG transferred up, old detection couldn't differentiate the gift egg from a regular egg; however, PIDIVs can lend a hand -- eggs don't have a PIDIV! fixed shiny BACD spread detection (in regards to antishiny rerolls). Shiny WISHMKR now detected correctly.
This commit is contained in:
@@ -2716,15 +2716,13 @@ internal static int[] getEggMoves(PKM pkm, int species, int formnum, GameVersion
|
||||
case 3:
|
||||
return EggMovesRS[species].Moves;
|
||||
case 4:
|
||||
switch (Version)
|
||||
switch (pkm.Version)
|
||||
{
|
||||
case GameVersion.DP:
|
||||
case GameVersion.Pt:
|
||||
return EggMovesDPPt[species].Moves;
|
||||
case GameVersion.HGSS:
|
||||
case (int)GameVersion.HG:
|
||||
case (int)GameVersion.SS:
|
||||
return EggMovesHGSS[species].Moves;
|
||||
default:
|
||||
return new int[0];
|
||||
return EggMovesDPPt[species].Moves;
|
||||
}
|
||||
case 5:
|
||||
return EggMovesBW[species].Moves;
|
||||
|
||||
@@ -20,6 +20,7 @@ public static LegalInfo verifyEncounter(PKM pkm)
|
||||
while (encounter.MoveNext())
|
||||
{
|
||||
var EncounterMatch = info.EncounterMatch = encounter.Current;
|
||||
bool PIDMatch = info.PIDIVMatches;
|
||||
|
||||
var e = EncounterValidator(pkm, EncounterMatch);
|
||||
if (!e.Valid && encounter.PeekIsNext())
|
||||
@@ -43,9 +44,15 @@ public static LegalInfo verifyEncounter(PKM pkm)
|
||||
var evo = VerifyEvolution.verifyEvolution(pkm, EncounterMatch);
|
||||
if (!evo.Valid && encounter.PeekIsNext())
|
||||
continue;
|
||||
|
||||
info.Parse.Add(evo);
|
||||
|
||||
if (!PIDMatch)
|
||||
{
|
||||
if (encounter.PeekIsNext())
|
||||
continue;
|
||||
info.Parse.Add(new CheckResult(Severity.Invalid, "PID Type Mismatch", CheckIdentifier.PID));
|
||||
}
|
||||
|
||||
// Encounter Passes
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -50,19 +50,33 @@ private static IEnumerable<IEncounterable> getEncounters12(PKM pkm, LegalInfo in
|
||||
}
|
||||
private static IEnumerable<IEncounterable> getEncounters3(PKM pkm, LegalInfo info)
|
||||
{
|
||||
info.PIDIV = MethodFinder.Analyze(pkm);
|
||||
var deferred = new List<IEncounterable>();
|
||||
foreach (var z in GenerateRawEncounters3(pkm))
|
||||
{
|
||||
// todo: pidiv filtering
|
||||
yield return z;
|
||||
if (info.PIDIV.Type.IsCompatible3(z, pkm))
|
||||
yield return z;
|
||||
else
|
||||
deferred.Add(z);
|
||||
}
|
||||
info.PIDIVMatches = false;
|
||||
foreach (var z in deferred)
|
||||
yield return z;
|
||||
}
|
||||
private static IEnumerable<IEncounterable> getEncounters4(PKM pkm, LegalInfo info)
|
||||
{
|
||||
info.PIDIV = MethodFinder.Analyze(pkm);
|
||||
var deferred = new List<IEncounterable>();
|
||||
foreach (var z in GenerateRawEncounters4(pkm))
|
||||
{
|
||||
// todo: pidiv filtering
|
||||
yield return z;
|
||||
if (info.PIDIV.Type.IsCompatible4(z))
|
||||
yield return z;
|
||||
else
|
||||
deferred.Add(z);
|
||||
}
|
||||
info.PIDIVMatches = false;
|
||||
foreach (var z in deferred)
|
||||
yield return z;
|
||||
}
|
||||
private static IEnumerable<GBEncounterData> GenerateRawEncounters12(PKM pkm, GameVersion game)
|
||||
{
|
||||
@@ -157,7 +171,6 @@ private static IEnumerable<IEncounterable> GenerateRawEncounters(PKM pkm)
|
||||
{
|
||||
foreach (var z in generateEggs(pkm))
|
||||
yield return z;
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var z in getValidStaticEncounter(pkm))
|
||||
@@ -187,7 +200,6 @@ private static IEnumerable<IEncounterable> GenerateRawEncounters4(PKM pkm)
|
||||
{
|
||||
foreach (var z in generateEggs(pkm))
|
||||
{ yield return z; ++ctr; }
|
||||
if (ctr != 0) yield break;
|
||||
}
|
||||
|
||||
bool safariSport = pkm.Ball == 0x05 || pkm.Ball == 0x18; // never static encounters
|
||||
@@ -212,10 +224,8 @@ private static IEnumerable<IEncounterable> GenerateRawEncounters4(PKM pkm)
|
||||
}
|
||||
private static IEnumerable<IEncounterable> GenerateRawEncounters3(PKM pkm)
|
||||
{
|
||||
int ctr = 0;
|
||||
foreach (var z in getValidGifts(pkm))
|
||||
{ yield return z; ++ctr; }
|
||||
if (ctr != 0) yield break;
|
||||
yield return z;
|
||||
|
||||
bool safari = pkm.Ball == 0x05; // never static encounters
|
||||
if (!safari)
|
||||
@@ -288,12 +298,9 @@ private static IEnumerable<EncounterStatic> getMatchingStaticEncounters(PKM pkm,
|
||||
{
|
||||
if (e.Nature != Nature.Random && pkm.Nature != (int)e.Nature)
|
||||
continue;
|
||||
if (pkm.Gen3 && e.EggLocation != 0)
|
||||
if (pkm.Gen3 && e.EggLocation != 0) // egg
|
||||
{
|
||||
// Hatched gen 3 gift egg can not be differentiated from normal eggs
|
||||
if (!pkm.IsEgg || pkm.Format > 3)
|
||||
continue;
|
||||
if (e.EggLocation != pkm.Met_Location)
|
||||
if (pkm.Format == 3 && e.EggLocation != pkm.Met_Location)
|
||||
continue;
|
||||
}
|
||||
else if (e.EggLocation != pkm.Egg_Location)
|
||||
@@ -770,8 +777,8 @@ private static IEnumerable<MysteryGift> getMatchingWC3(PKM pkm, IEnumerable<Myst
|
||||
|
||||
if (!wc.IsEgg)
|
||||
{
|
||||
if (wc.SID != -1 && wc.SID != pkm.SID) continue;
|
||||
if (wc.TID != -1 && wc.TID != pkm.TID) continue;
|
||||
if (wc.SID != pkm.SID) continue;
|
||||
if (wc.TID != pkm.TID) continue;
|
||||
if (wc.OT_Name != pkm.OT_Name) continue;
|
||||
if (wc.OT_Gender < 3 && wc.OT_Gender != pkm.OT_Gender) continue;
|
||||
if (wc.Language != 0 && wc.Language != pkm.Language) continue;
|
||||
|
||||
@@ -39,6 +39,7 @@ public IEncounterable EncounterMatch
|
||||
private DexLevel[][] _evochains;
|
||||
private IEncounterable _match;
|
||||
public PIDIV PIDIV;
|
||||
public bool PIDIVMatches = true;
|
||||
|
||||
public LegalInfo(PKM pk)
|
||||
{
|
||||
|
||||
@@ -55,7 +55,7 @@ public static PIDIV Analyze(PKM pk)
|
||||
if (getBACDMatch(pk, pid, IVs, out pidiv))
|
||||
return pidiv;
|
||||
|
||||
return null; // no match
|
||||
return new PIDIV {Type=PIDType.None}; // no match
|
||||
}
|
||||
|
||||
private static bool getLCRNGMatch(uint top, uint bot, uint[] IVs, out PIDIV pidiv)
|
||||
@@ -336,6 +336,7 @@ private static bool getBACDMatch(PKM pk, uint pid, uint[] IVs, out PIDIV pidiv)
|
||||
var PID = A & 0xFFFF0000 | B >> 16;
|
||||
bool isShiny = (pk.TID ^ pk.SID ^ PID >> 16 ^ PID & 0xFFFF) < 8;
|
||||
bool forceShiny = false;
|
||||
bool antiShiny = false;
|
||||
if (PID != pid)
|
||||
{
|
||||
if (!isShiny)
|
||||
@@ -359,8 +360,12 @@ private static bool getBACDMatch(PKM pk, uint pid, uint[] IVs, out PIDIV pidiv)
|
||||
continue;
|
||||
forceShiny = true;
|
||||
}
|
||||
if (!forceShiny && (PID + 8 & 0xFFFFFFF8) != pid)
|
||||
continue;
|
||||
if (!forceShiny)
|
||||
{
|
||||
if ((PID + 8 & 0xFFFFFFF8) != pid)
|
||||
continue;
|
||||
antiShiny = true;
|
||||
}
|
||||
}
|
||||
var s = RNG.LCRNG.Prev(A);
|
||||
|
||||
@@ -370,12 +375,12 @@ private static bool getBACDMatch(PKM pk, uint pid, uint[] IVs, out PIDIV pidiv)
|
||||
{
|
||||
if ((sn & 0xFFFF0000) != 0)
|
||||
continue;
|
||||
var type = forceShiny ? PIDType.BACD_R_S : isShiny ? PIDType.BACD_R_A : PIDType.BACD_R;
|
||||
var type = forceShiny ? PIDType.BACD_R_S : antiShiny ? PIDType.BACD_R_A : PIDType.BACD_R;
|
||||
pidiv = new PIDIV {OriginSeed = sn, RNG = RNG.LCRNG, Type = type};
|
||||
return true;
|
||||
}
|
||||
// no restricted seed found, thus unrestricted
|
||||
var t = forceShiny ? PIDType.BACD_U_S : isShiny ? PIDType.BACD_U_A : PIDType.BACD_U;
|
||||
var t = forceShiny ? PIDType.BACD_U_S : antiShiny ? PIDType.BACD_U_A : PIDType.BACD_U;
|
||||
pidiv = new PIDIV {OriginSeed = s, RNG = RNG.LCRNG, Type = t};
|
||||
return true;
|
||||
}
|
||||
@@ -502,5 +507,40 @@ public static IEnumerable<PIDIV> getPokeSpotSeeds(PKM pkm, int slot)
|
||||
yield return new PIDIV {OriginSeed = s, RNG = RNG.XDRNG, Type = PIDType.None};
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsCompatible3(this PIDType val, IEncounterable encounter, PKM pkm)
|
||||
{
|
||||
switch (encounter)
|
||||
{
|
||||
case WC3 g:
|
||||
return val == g.Method;
|
||||
case EncounterStaticShadow _:
|
||||
return val == PIDType.CXD;
|
||||
case EncounterStatic s:
|
||||
return s.Roaming ? val == PIDType.Method_1_Roamer : MethodH.Any(z => z == val);
|
||||
case EncounterSlot w:
|
||||
if (pkm.Version == 15)
|
||||
return val == PIDType.CXD;
|
||||
return (w.Species == 201 ? MethodH_Unown : MethodH).Any(z => z == val);
|
||||
default:
|
||||
return val == PIDType.None;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsCompatible4(this PIDType val, IEncounterable encounter)
|
||||
{
|
||||
switch (encounter)
|
||||
{
|
||||
case EncounterStatic s:
|
||||
return s.Shiny == true ? val == PIDType.ChainShiny : val == PIDType.Method_1;
|
||||
case EncounterSlot _:
|
||||
return val == PIDType.Method_1;
|
||||
default:
|
||||
return val == PIDType.None;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly PIDType[] MethodH = { PIDType.Method_1, PIDType.Method_2, PIDType.Method_4 };
|
||||
private static readonly PIDType[] MethodH_Unown = { PIDType.Method_1_Unown, PIDType.Method_2_Unown, PIDType.Method_4_Unown };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,15 +283,18 @@ public static partial class Legal
|
||||
new WC3 { Species = 359, IsEgg = true, Level = 05, Version = (int)GameVersion.RS, Moves = new[]{273} }, // Absol with Wish
|
||||
new WC3 { Species = 371, IsEgg = true, Level = 05, Version = (int)GameVersion.RS, Moves = new[]{334} }, // Bagon with Iron Defense
|
||||
new WC3 { Species = 371, IsEgg = true, Level = 05, Version = (int)GameVersion.RS, Moves = new[]{273} }, // Bagon with Wish
|
||||
|
||||
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 30317, OT_Name = "RUBY" },
|
||||
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 30317, OT_Name = "SAPHIRE" },
|
||||
};
|
||||
|
||||
internal static readonly MysteryGift[] Encounter_Event3_Common =
|
||||
{
|
||||
// Pokémon Box
|
||||
new WC3 { Species = 333, IsEgg = true, Level = 05, /*Version = (int)GameVersion.RSBOX,*/ Moves = new[]{206} }, // Swablu Egg with False Swipe
|
||||
new WC3 { Species = 263, IsEgg = true, Level = 05, /*Version = (int)GameVersion.RSBOX,*/ Moves = new[]{245} }, // Zigzagoon Egg with Extreme Speed
|
||||
new WC3 { Species = 300, IsEgg = true, Level = 05, /*Version = (int)GameVersion.RSBOX,*/ Moves = new[]{006} }, // Skitty Egg with Pay Day
|
||||
new WC3 { Species = 172, IsEgg = true, Level = 05, /*Version = (int)GameVersion.RSBOX,*/ Moves = new[]{057} }, // Pichu Egg with Surf
|
||||
new WC3 { Species = 333, IsEgg = true, Level = 05, /*Version = (int)GameVersion.RSBOX,*/ Moves = new[]{206}, Method = PIDType.BACD_U }, // Swablu Egg with False Swipe
|
||||
new WC3 { Species = 263, IsEgg = true, Level = 05, /*Version = (int)GameVersion.RSBOX,*/ Moves = new[]{245}, Method = PIDType.BACD_U }, // Zigzagoon Egg with Extreme Speed
|
||||
new WC3 { Species = 300, IsEgg = true, Level = 05, /*Version = (int)GameVersion.RSBOX,*/ Moves = new[]{006}, Method = PIDType.BACD_U }, // Skitty Egg with Pay Day
|
||||
new WC3 { Species = 172, IsEgg = true, Level = 05, /*Version = (int)GameVersion.RSBOX,*/ Moves = new[]{057}, Method = PIDType.BACD_U }, // Pichu Egg with Surf
|
||||
// PokePark Eggs
|
||||
new WC3 { Species = 054, IsEgg = true, Level = 05, Moves = new[]{300} }, // Psyduck with Mud Sport
|
||||
new WC3 { Species = 172, IsEgg = true, Level = 05, Moves = new[]{266} }, // Pichu with Follow me
|
||||
|
||||
@@ -13,8 +13,8 @@ public class WC3 : MysteryGift
|
||||
|
||||
public string OT_Name;
|
||||
public int OT_Gender = 3;
|
||||
public int TID = -1;
|
||||
public int SID = -1;
|
||||
public int TID;
|
||||
public int SID;
|
||||
public int Met_Location = 255;
|
||||
public int Version;
|
||||
public int Language;
|
||||
|
||||
Reference in New Issue
Block a user