using System; namespace PKHeX.Core; /// /// Pokédex structure used for . /// > public sealed class Zukan9 : ZukanBase { private readonly SCBlock Paldea; public Zukan9(SAV9SV sav, SCBlock paldea) : base(sav, 0) { Paldea = paldea; } /// /// Checks how much DLC patches have been installed by detecting if DLC blocks are present. /// public int GetRevision() => 0; // No DLC1 data allocated private const int EntrySize = PokeDexEntry9SV.SIZE; public PokeDexEntry9SV Get(ushort species) { if (species > SAV.MaxSpeciesID) throw new ArgumentOutOfRangeException(nameof(species), species, null); var internalSpecies = SpeciesConverter.GetInternal9(species); var span = Paldea.Data.AsSpan(internalSpecies * EntrySize); return new PokeDexEntry9SV(span); } public override bool GetSeen(ushort species) => Get(species).IsSeen; public override bool GetCaught(ushort species) => Get(species).IsCaught; public void SetCaught(ushort species, bool value = true) => Get(species).SetCaught(value); public bool GetIsLanguageIndexObtained(ushort species, int langIndex) => Get(species).GetLanguageFlag(langIndex); public void SetIsLanguageIndexObtained(ushort species, int langIndex, bool value = true) => Get(species).SetLanguageFlag(langIndex, value); public bool GetIsLanguageObtained(ushort species, int language) { int langIndex = PokeDexEntry9SV.GetDexLangFlag(language); if (langIndex < 0) return false; return GetIsLanguageIndexObtained(species, language); } public void SetIsLanguageObtained(ushort species, int language, bool value = true) { int langIndex = PokeDexEntry9SV.GetDexLangFlag(language); if (langIndex < 0) return; SetIsLanguageIndexObtained(species, language, value); } public uint GetFormDisplayed(ushort species) => Get(species).GetDisplayForm(); public void SetFormDisplayed(ushort species, byte form = 0) => Get(species).SetDisplayForm(form); public uint GetGenderDisplayed(ushort species) => Get(species).GetDisplayGender(); public void SetGenderDisplayed(ushort species, int value = 0) => Get(species).SetDisplayGender(value); public bool GetDisplayShiny(ushort species) => Get(species).GetDisplayIsShiny(); public void SetDisplayShiny(ushort species, bool value = true) => Get(species).SetDisplayIsShiny(value); #region Inherited public override void SetDex(PKM pk) { if (pk.IsEgg) // do not add return; var species = pk.Species; var form = pk.Form; var pt = SAV.Personal; if (!pt.IsPresentInGame(species, form)) return; var entry = Get(species); if (!entry.IsKnown) entry.SetDisplayIsNew(); entry.SetCaught(true); entry.SetIsGenderSeen(pk.Gender, true); entry.SetIsFormSeen(form, true); entry.SetDisplayForm(form); entry.SetDisplayGender(pk.Gender); if (pk.IsShiny) { entry.SetDisplayIsShiny(); entry.SetSeenIsShiny(); } entry.SetLanguageFlag(pk.Language, true); if (SAV.Language != pk.Language) entry.SetLanguageFlag(SAV.Language, true); // Update adjacent entries if not seen. UpdateAdjacent(species); } public void UpdateAdjacent(ushort species) { var (group, index) = GetDexIndex(species); if (index == 0) return; MarkAsKnown1(group, index - 1); MarkAsKnown1(group, index + 1); } private void MarkAsKnown1(byte group, int index) { if (group == 1 && index <= 9) // Don't set adjacent for starters. Hide their evolutions! return; var species = GetSpecies(group, index); if (species == 0) return; var entry = Get(species); if (!entry.IsKnown) entry.SetState(1); } private ushort GetSpecies(byte group, int index) { for (ushort species = 0; species <= SAV.MaxSpeciesID; species++) { var (g, i) = GetDexIndex(species); if (g == group && i == index) return species; } return 0; } public (byte Group, ushort Index) GetDexIndex(ushort species) { var pt = SAV.Personal; // For each form including form 0, check the dex index. var pi = pt.GetFormEntry(species, 0); if (pi.DexIndex != 0) return (pi.DexGroup, pi.DexIndex); for (byte f = 1; f <= pi.FormCount; f++) { pi = pt.GetFormEntry(species, f); if (pi.DexIndex != 0) return (pi.DexGroup, pi.DexIndex); } return (0, 0); } public override void SeenNone() { Array.Clear(Paldea.Data, 0, Paldea.Data.Length); } public override void CaughtNone() { for (ushort i = 0; i <= SAV.MaxSpeciesID; i++) { var entry = Get(i); entry.ClearCaught(); } } public override void SeenAll(bool shinyToo = false) { SetAllSeen(true, shinyToo); } private void SeenAll(ushort species, byte formCount, bool value = true, bool shinyToo = false) { // Wipe existing gender flags. var entry = Get(species); entry.SetIsGenderSeen(0, false); entry.SetIsGenderSeen(1, false); if (value && !entry.IsSeen) entry.SetSeen(value); if (!value || shinyToo) entry.SetSeenIsShiny(value); var pt = SAV.Personal; for (byte form = 0; form < formCount; form++) { var pi = pt.GetFormEntry(species, form); bool seenForm = value && pi.IsPresentInGame; SetIsFormSeen(entry, pi, form, seenForm); } } private static void SetIsFormSeen(PokeDexEntry9SV entry, IGenderDetail pi, byte form, bool seenForm) { entry.SetIsFormSeen(form, seenForm); if (seenForm) SetIsFormSeenGender(entry, pi); } private static void SetIsFormSeenGender(PokeDexEntry9SV entry, IGenderDetail pi) { if (pi.IsDualGender) { entry.SetIsGenderSeen(0, true); entry.SetIsGenderSeen(1, true); } else { var gender = pi.FixedGender(); entry.SetIsGenderSeen(gender, true); } } public override void CompleteDex(bool shinyToo = false) { for (ushort species = 0; species <= SAV.MaxSpeciesID; species++) { if (!SAV.Personal.IsSpeciesInGame(species)) continue; if (GetDexIndex(species).Index == 0) continue; SetDexEntryAll(species, shinyToo); } } public override void CaughtAll(bool shinyToo = false) { SeenAll(shinyToo); for (ushort species = 0; species <= SAV.MaxSpeciesID; species++) { if (!SAV.Personal.IsSpeciesInGame(species)) continue; if (GetDexIndex(species).Index == 0) continue; SetAllCaught(species, true, shinyToo); } } private void SetAllCaught(ushort species, bool value = true, bool shinyToo = false) { SetCaught(species, value); for (int i = 1; i <= (int)LanguageID.ChineseT; i++) SetIsLanguageObtained(species, i, value); if (value) { var pi = SAV.Personal[species]; if (shinyToo) SetDisplayShiny(species); SetGenderDisplayed(species, pi.RandomGender()); } else { SetDisplayShiny(species, false); SetGenderDisplayed(species, 0); } } public override void SetAllSeen(bool value = true, bool shinyToo = false) { var pt = SAV.Personal; for (ushort species = 0; species < SAV.MaxSpeciesID; species++) { if (value && GetDexIndex(species).Index == 0) continue; var pi = pt[species]; SeenAll(species, pi.FormCount, value, shinyToo); } } private void SetAllSeen(ushort species, bool value = true, bool shinyToo = false) { var pi = SAV.Personal[species]; var fc = pi.FormCount; SeenAll(species, fc, value, shinyToo); } public override void SetDexEntryAll(ushort species, bool shinyToo = false) { SetAllSeen(species, true, shinyToo); SetAllCaught(species, true, shinyToo); } public override void ClearDexEntryAll(ushort species) => Get(species).Clear(); #endregion }