using static PKHeX.Core.OverworldCorrelation8Requirement; namespace PKHeX.Core { /// /// Encounter Slot found in . /// /// public sealed record EncounterSlot8 : EncounterSlot, IOverworldCorrelation8 { public readonly AreaWeather8 Weather; public override string LongName => Weather == AreaWeather8.All ? wild : $"{wild} [{(((EncounterArea8)Area).PermitCrossover ? "Symbol" : "Hidden")}] - {Weather.ToString().Replace("_", string.Empty)}"; public override int Generation => 8; public EncounterSlot8(EncounterArea8 area, int species, int form, int min, int max, AreaWeather8 weather) : base(area, species, form, min, max) { Weather = weather; } protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk) { base.ApplyDetails(sav, criteria, pk); if (Location is 30 or 54 && !((EncounterArea8)Area).PermitCrossover && (Weather & AreaWeather8.Fishing) == 0) ((PK8)pk).RibbonMarkCurry = true; var req = GetRequirement(pk); if (req != MustHave) { pk.SetRandomEC(); return; } Overworld8RNG.ApplyDetails(pk, criteria); } public OverworldCorrelation8Requirement GetRequirement(PKM pk) { if (((EncounterArea8)Area).PermitCrossover) return MustHave; // symbol walking overworld bool curry = pk is IRibbonSetMark8 {RibbonMarkCurry: true}; if (curry) return MustNotHave; // Tree encounters are generated via the global seed, not the u32 if ((Weather & AreaWeather8.Shaking_Trees) != 0) { // Some tree encounters are present in the regular encounters. return Weather == AreaWeather8.Shaking_Trees ? MustNotHave : CanBeEither; } return MustHave; } public bool IsOverworldCorrelationCorrect(PKM pk) { var flawless = GetFlawlessIVCount(); return Overworld8RNG.ValidateOverworldEncounter(pk, flawless: flawless); } private int GetFlawlessIVCount() { const int none = 0; const int any023 = -1; var area = (EncounterArea8) Area; if (area.PermitCrossover) return any023; // Symbol if ((Weather & AreaWeather8.Fishing) != 0) return any023; // Fishing return none; // Hidden } public override EncounterMatchRating GetMatchRating(PKM pkm) { var rating = base.GetMatchRating(pkm); if (rating != EncounterMatchRating.Match) return rating; // Glimwood Tangle does not spawn Symbol encounters, only Hidden. if (Location is 76 && ((EncounterArea8)Area).PermitCrossover) return EncounterMatchRating.PartialMatch; if (pkm is IRibbonSetMark8 m) { if (m.RibbonMarkCurry && (Weather & AreaWeather8.All) == 0) return EncounterMatchRating.Deferred; if (m.RibbonMarkFishing && (Weather & AreaWeather8.Fishing) == 0) return EncounterMatchRating.Deferred; // Galar Mine hidden encounters can only be found via Curry. if (Location is 30 or 54 && !((EncounterArea8)Area).PermitCrossover && !m.RibbonMarkCurry && (Weather & AreaWeather8.Fishing) == 0) return EncounterMatchRating.PartialMatch; } var req = GetRequirement(pkm); return req switch { MustHave when !IsOverworldCorrelationCorrect(pkm) => EncounterMatchRating.Deferred, MustNotHave when IsOverworldCorrelationCorrect(pkm) => EncounterMatchRating.Deferred, _ => EncounterMatchRating.Match, }; } } }