using static PKHeX.Core.PIDType; using static PKHeX.Core.SlotType3; using static PKHeX.Core.RandomCorrelationRating; namespace PKHeX.Core; /// /// Encounter Slot found in . /// public record EncounterSlot3(EncounterArea3 Parent, ushort Species, byte Form, byte LevelMin, byte LevelMax, byte SlotNumber, byte MagnetPullIndex, byte MagnetPullCount, byte StaticIndex, byte StaticCount) : IEncounterable, IEncounterMatch, IEncounterConvertible, IEncounterSlot3, IRandomCorrelation { public byte Generation => 3; ushort ILocation.Location => Location; public EntityContext Context => EntityContext.Gen3; public bool IsEgg => false; public Ball FixedBall => GetRequiredBall(); public byte AreaRate => Parent.Rate; public AbilityPermission Ability => AbilityPermission.Any12; public Shiny Shiny => Shiny.Random; public bool IsShiny => false; public ushort EggLocation => 0; public string Name => $"Wild Encounter ({Version})"; public string LongName => $"{Name} {Type.ToString().Replace('_', ' ')}"; public GameVersion Version => Parent.Version; public byte Location => Parent.Location; public SlotType3 Type => Parent.Type; public bool IsSafari => Locations.IsSafariZoneLocation3(Location); public bool IsSafariHoenn => Locations.IsSafariZoneLocation3RSE(Location); private Ball GetRequiredBall(Ball fallback = Ball.None) => IsSafari ? Ball.Safari : fallback; #region Generating PKM IEncounterConvertible.ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria) => ConvertToPKM(tr, criteria); PKM IEncounterConvertible.ConvertToPKM(ITrainerInfo tr) => ConvertToPKM(tr); public PK3 ConvertToPKM(ITrainerInfo tr) => ConvertToPKM(tr, EncounterCriteria.Unrestricted); public PK3 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria) { int language = (int)Language.GetSafeLanguage3((LanguageID)tr.Language); var version = Version switch { GameVersion.RSE => tr.Version switch { GameVersion.R => GameVersion.R, GameVersion.S => GameVersion.S, GameVersion.RS => GameVersion.R, _ => GameVersion.E, }, _ => Version }; var pi = PersonalTable.E[Species]; var pk = new PK3 { Species = Species, CurrentLevel = LevelMin, OriginalTrainerFriendship = pi.BaseFriendship, MetLocation = Location, MetLevel = LevelMin, Version = version, Ball = (byte)GetRequiredBall(Ball.Poke), Language = language, OriginalTrainerGender = tr.Gender, ID32 = tr.ID32, Nickname = SpeciesName.GetSpeciesNameGeneration(Species, language, Generation), }; // Copy from SaveFile's OT name. Trash bytes here should be pure, but our OT name might not always source from a PK3/SAV3. // Condition the buffer as if it came from a correct SAV3 named after the OT. var ot = pk.OriginalTrainerTrash; ot[..(language == 1 ? 6 : 7)].Fill(0xFF); pk.OriginalTrainerName = EncounterUtil.GetTrainerName(tr, language); SetPINGA(pk, criteria, pi); SetEncounterMoves(pk); pk.ResetPartyStats(); return pk; } private void SetPINGA(PK3 pk, in EncounterCriteria criteria, PersonalInfo3 pi) { if (Species != (int)Core.Species.Unown) { if (criteria.IsSpecifiedIVsAll() && this.SetFromIVs(pk, pi, criteria, pk.E)) return; this.SetRandom(pk, pi, criteria, Util.Rand32()); } else { if (criteria.IsSpecifiedIVsAll() && this.SetFromIVsUnown(pk, criteria)) return; this.SetRandomUnown(pk, criteria, Util.Rand32()); } } protected virtual void SetEncounterMoves(PK3 pk) => EncounterUtil.SetEncounterMoves(pk, Version, LevelMin); #endregion #region Matching public bool IsMatchExact(PKM pk, EvoCriteria evo) { if (Form != evo.Form && Species is not (int)Core.Species.Burmy) return false; if (pk.Format == 3) { // Must match level exactly. if (!this.IsLevelWithinRange(pk.MetLevel)) return false; } else { if (evo.LevelMax < LevelMin) return false; } return true; } public EncounterMatchRating GetMatchRating(PKM pk) { if (IsDeferredSafari3(pk.Ball == (int)Ball.Safari)) return EncounterMatchRating.PartialMatch; if (IsDeferredWurmple(pk)) return EncounterMatchRating.PartialMatch; return EncounterMatchRating.Match; } private bool IsDeferredWurmple(PKM pk) => Species == (int)Core.Species.Wurmple && pk.Species != (int)Core.Species.Wurmple && !WurmpleUtil.IsWurmpleEvoValid(pk); private bool IsDeferredSafari3(bool IsSafariBall) => IsSafariBall != Locations.IsSafariZoneLocation3(Location); #endregion public RandomCorrelationRating IsCompatible(PIDType type, PKM pk) { var match = Species != (int)Core.Species.Unown ? type is Method_1 or Method_2 or Method_3 or Method_4 : type is Method_1_Unown or Method_2_Unown or Method_3_Unown or Method_4_Unown; return match ? Match : Mismatch; } public PIDType GetSuggestedCorrelation() => Species == (int)Core.Species.Unown ? Method_1_Unown : Method_1; public byte PressureLevel => Type != Grass ? LevelMax : Parent.GetPressureMax(Species, LevelMax); }