PKHeX/PKHeX.Core/Legality/Bulk/DuplicatePIDChecker.cs
Kurt 95fbf66a6e
Refactor: Gen3/4 Lead Encounters, property fixing (#4193)
In addition to the Method 1 (and other sibling PIDIV types) correlation, an encounter can only be triggered if the calls prior land on the Method {1} seed. The RNG community has dubbed these patterns as "Method J" (D/P/Pt), "Method K" (HG/SS), and "Method H" (Gen3, coined by yours truly). The basic gist of these is that they are pre-requisites, like the Shadow locks of Colosseum/XD. 

Rename/re-type a bunch of properties to get the codebase more in line with correct property names & more obvious underlying types.
2024-02-22 21:20:54 -06:00

76 lines
2.3 KiB
C#

using System.Collections.Generic;
using static PKHeX.Core.CheckIdentifier;
namespace PKHeX.Core.Bulk;
public sealed class DuplicatePIDChecker : IBulkAnalyzer
{
public void Analyze(BulkAnalysis input)
{
if (input.Trainer.Generation < 3)
return; // no PID yet
CheckPIDReuse(input);
}
private static void CheckPIDReuse(BulkAnalysis input)
{
var dict = new Dictionary<uint, CombinedReference>();
for (int i = 0; i < input.AllData.Count; i++)
{
if (input.GetIsClone(i))
continue; // already flagged
var cp = input.AllData[i];
var ca = input.AllAnalysis[i];
Verify(input, dict, ca, cp);
}
}
private static void Verify(BulkAnalysis input, Dictionary<uint, CombinedReference> dict, LegalityAnalysis ca, SlotCache cp)
{
bool g345 = ca.Info.Generation is 3 or 4 or 5;
var id = g345 ? cp.Entity.EncryptionConstant : cp.Entity.PID;
var cr = new CombinedReference(cp, ca);
if (!dict.TryGetValue(id, out var pr))
{
dict.Add(id, cr);
return;
}
VerifyPIDShare(input, pr, cr);
}
private static void VerifyPIDShare(BulkAnalysis input, CombinedReference pr, CombinedReference cr)
{
var ps = pr.Slot;
var pa = pr.Analysis;
var cs = cr.Slot;
var ca = cr.Analysis;
const CheckIdentifier ident = PID;
var gen = pa.Info.Generation;
if (ca.Info.Generation != gen)
{
input.AddLine(ps, cs, "PID sharing across generations detected.", ident);
return;
}
bool gbaNDS = gen is 3 or 4 or 5;
if (!gbaNDS)
{
input.AddLine(ps, cs, "PID sharing for 3DS-onward origin detected.", ident);
return;
}
// eggs/mystery gifts shouldn't share with wild encounters
var cenc = ca.Info.EncounterMatch;
bool eggMysteryCurrent = cenc is EncounterEgg or MysteryGift;
var penc = pa.Info.EncounterMatch;
bool eggMysteryPrevious = penc is EncounterEgg or MysteryGift;
if (eggMysteryCurrent != eggMysteryPrevious)
{
input.AddLine(ps, cs, "PID sharing across RNG encounters detected.", ident);
}
}
}