private void parsePK6(PKM pk) { pkm = pk; if (!pkm.IsOriginValid()) { AddLine(Severity.Invalid, "Species does not exist in origin game.", CheckIdentifier.None); return; } updateRelearnLegality(); updateEncounterChain(); updateMoveLegality(); updateChecks(); }
public BatchEditor(PKM pk) { InitializeComponent(); pkm = pk; DragDrop += tabMain_DragDrop; DragEnter += tabMain_DragEnter; CB_Format.Items.Clear(); CB_Format.Items.Add("All"); foreach (Type t in types) CB_Format.Items.Add(t.Name.ToLower()); CB_Format.Items.Add("Any"); CB_Format.SelectedIndex = CB_Require.SelectedIndex = 0; new ToolTip().SetToolTip(CB_Property, "Property of a given PKM to modify."); new ToolTip().SetToolTip(L_PropType, "PropertyType of the currently loaded PKM in the main window."); new ToolTip().SetToolTip(L_PropValue, "PropertyValue of the currently loaded PKM in the main window."); }
public LegalityAnalysis(PKM pk) { for (int i = 0; i < 4; i++) { vMoves[i] = new CheckResult(CheckIdentifier.Move); vRelearn[i] = new CheckResult(CheckIdentifier.RelearnMove); } try { switch (pk.GenNumber) { case 6: parsePK6(pk); break; case 7: parsePK7(pk); break; default: return; } if (pkm.Format == 7) // Temp G7 Bank Checks verifyG7PreBank(); Valid = Parsed = Parse.Any(); if (Parsed) { if (Parse.Any(chk => !chk.Valid)) Valid = false; if (vMoves.Any(m => m.Valid != true)) Valid = false; else if (vRelearn.Any(m => m.Valid != true)) Valid = false; if (pkm.FatefulEncounter && vRelearn.Any(chk => !chk.Valid) && EncounterMatch == null) AddLine(Severity.Indeterminate, "Fateful Encounter with no matching Encounter. Has the Mystery Gift data been contributed?", CheckIdentifier.Fateful); } } catch { Valid = false; } getLegalityReport(); AllSuggestedMoves = !pkm.IsOriginValid() ? new int[4] : getSuggestedMoves(true, true, true); AllSuggestedRelearnMoves = !pkm.IsOriginValid() ? new int[4] : Legal.getValidRelearn(pkm, -1).ToArray(); AllSuggestedMovesAndRelearn = AllSuggestedMoves.Concat(AllSuggestedRelearnMoves).ToArray(); }
public QR(Image qr, Image icon, string line1, string line2, string line3, string line4, PKM pk = null) { InitializeComponent(); pkm = pk; // Layer on Text const int stretch = 50; Height += stretch; if (pkm != null && pkm.Format == 7) Height += 40; this.qr = qr; this.icon = icon; Line1 = line1; Line2 = line2; Line3 = line3; Line4 = line4; if (pkm != null && pkm.Format == 7) updateBoxSlotCopies(null, null); else RefreshImage(); }
public void populateFields(PKM pk, bool focus = true) { if (pk == null) { WinFormsUtil.Error("Attempted to load a null file."); return; } if ((pk.Format >= 3 && pk.Format > SAV.Generation) // pk3-7, can't go backwards || (pk.Format <= 2 && SAV.Generation > 2 && SAV.Generation < 7)) // pk1-2, can't go 3-6 { WinFormsUtil.Alert($"Can't load Gen{pk.Format} to Gen{SAV.Generation} games."); return; } bool oldInit = fieldsInitialized; fieldsInitialized = fieldsLoaded = false; if (focus) Tab_Main.Focus(); pkm = pk.Clone(); if (fieldsInitialized & !pkm.ChecksumValid) WinFormsUtil.Alert("PKX File has an invalid checksum."); if (pkm.Format != SAV.Generation) // past gen format { string c; pkm = PKMConverter.convertToFormat(pkm, SAV.PKMType, out c); if (pk.Format != pkm.Format && focus) // converted WinFormsUtil.Alert("Converted File."); } try { getFieldsfromPKM(); } catch { fieldsInitialized = oldInit; throw; } CB_EncounterType.Visible = Label_EncounterType.Visible = pkm.Gen4 && SAV.Generation < 7; fieldsInitialized = oldInit; updateIVs(null, null); updatePKRSInfected(null, null); updatePKRSCured(null, null); if (HaX) // Load original values from pk not pkm { MT_Level.Text = (pk.Stat_HPMax != 0 ? pk.Stat_Level : PKX.getLevel(pk.Species, pk.EXP)).ToString(); TB_EXP.Text = pk.EXP.ToString(); MT_Form.Text = pk.AltForm.ToString(); if (pk.Stat_HPMax != 0) // stats present { Stat_HP.Text = pk.Stat_HPCurrent.ToString(); Stat_ATK.Text = pk.Stat_ATK.ToString(); Stat_DEF.Text = pk.Stat_DEF.ToString(); Stat_SPA.Text = pk.Stat_SPA.ToString(); Stat_SPD.Text = pk.Stat_SPD.ToString(); Stat_SPE.Text = pk.Stat_SPE.ToString(); } } fieldsLoaded = true; Label_HatchCounter.Visible = CHK_IsEgg.Checked && SAV.Generation > 1; Label_Friendship.Visible = !CHK_IsEgg.Checked && SAV.Generation > 1; // Set the Preview Box dragout.Image = pk.Sprite(); setMarkings(); updateLegality(); }
internal static int[] GetBaseEggMoves(PKM pkm, int species, GameVersion gameSource, int lvl) { if (gameSource == GameVersion.Any) { gameSource = (GameVersion)pkm.Version; } switch (gameSource) { case GameVersion.GSC: case GameVersion.GS: // If checking back-transfer specimen (GSC->RBY), remove moves that must be deleted prior to transfer int[] getRBYCompatibleMoves(int[] moves) => pkm.Format == 1 ? moves.Where(m => m <= MaxMoveID_1).ToArray() : moves; if (pkm.InhabitedGeneration(2)) { return(getRBYCompatibleMoves(LevelUpGS[species].GetMoves(lvl))); } break; case GameVersion.C: if (pkm.InhabitedGeneration(2)) { return(getRBYCompatibleMoves(LevelUpC[species].GetMoves(lvl))); } break; case GameVersion.R: case GameVersion.S: case GameVersion.RS: if (pkm.InhabitedGeneration(3)) { return(LevelUpRS[species].GetMoves(lvl)); } break; case GameVersion.E: if (pkm.InhabitedGeneration(3)) { return(LevelUpE[species].GetMoves(lvl)); } break; case GameVersion.FR: case GameVersion.LG: case GameVersion.FRLG: // only difference in FR/LG is deoxys which doesn't breed. if (pkm.InhabitedGeneration(3)) { return(LevelUpFR[species].GetMoves(lvl)); } break; case GameVersion.D: case GameVersion.P: case GameVersion.DP: if (pkm.InhabitedGeneration(4)) { return(LevelUpDP[species].GetMoves(lvl)); } break; case GameVersion.Pt: if (pkm.InhabitedGeneration(4)) { return(LevelUpPt[species].GetMoves(lvl)); } break; case GameVersion.HG: case GameVersion.SS: case GameVersion.HGSS: if (pkm.InhabitedGeneration(4)) { return(LevelUpHGSS[species].GetMoves(lvl)); } break; case GameVersion.B: case GameVersion.W: case GameVersion.BW: if (pkm.InhabitedGeneration(5)) { return(LevelUpBW[species].GetMoves(lvl)); } break; case GameVersion.B2: case GameVersion.W2: case GameVersion.B2W2: if (pkm.InhabitedGeneration(5)) { return(LevelUpB2W2[species].GetMoves(lvl)); } break; case GameVersion.X: case GameVersion.Y: case GameVersion.XY: if (pkm.InhabitedGeneration(6)) { return(LevelUpXY[species].GetMoves(lvl)); } break; case GameVersion.AS: case GameVersion.OR: case GameVersion.ORAS: if (pkm.InhabitedGeneration(6)) { return(LevelUpAO[species].GetMoves(lvl)); } break; case GameVersion.SN: case GameVersion.MN: case GameVersion.SM: if (species > MaxSpeciesID_7) { break; } if (pkm.InhabitedGeneration(7)) { int index = PersonalTable.SM.GetFormeIndex(species, pkm.AltForm); return(LevelUpSM[index].GetMoves(lvl)); } break; case GameVersion.US: case GameVersion.UM: case GameVersion.USUM: if (pkm.InhabitedGeneration(7)) { int index = PersonalTable.USUM.GetFormeIndex(species, pkm.AltForm); return(LevelUpUSUM[index].GetMoves(lvl)); } break; } return(Array.Empty <int>()); }
private static bool IsStarter(PKM pb7) => (pb7.Species == (int)Species.Pikachu && pb7.AltForm == 8) || (pb7.Species == (int)Species.Eevee && pb7.AltForm == 1);
protected virtual void setDex(PKM pkm) { setSeen(pkm); setCaught(pkm); }
protected override void setDex(PKM pkm) { if (pkm.Species == 0) return; if (pkm.Species > MaxSpeciesID) return; if (Version == GameVersion.Unknown) return; if (PokeDex < 0) return; const int brSize = 0x54; int bit = pkm.Species - 1; int lang = pkm.Language - 1; if (lang > 5) lang--; // 0-6 language vals int gender = pkm.Gender % 2; // genderless -> male int shiny = pkm.IsShiny ? 1 : 0; int shiftoff = shiny * brSize * 2 + gender * brSize + brSize; // Set the Species Owned Flag Data[PokeDex + 0x8 + bit / 8] |= (byte)(1 << (bit % 8)); // Set the [Species/Gender/Shiny] Seen Flag Data[PokeDex + 0x8 + shiftoff + bit / 8] |= (byte)(1 << (bit % 8)); // Set the Display flag if none are set bool Displayed = false; Displayed |= (Data[PokeDex + 0x8 + brSize*5 + bit/8] & (byte)(1 << (bit%8))) != 0; Displayed |= (Data[PokeDex + 0x8 + brSize*6 + bit/8] & (byte)(1 << (bit%8))) != 0; Displayed |= (Data[PokeDex + 0x8 + brSize*7 + bit/8] & (byte)(1 << (bit%8))) != 0; Displayed |= (Data[PokeDex + 0x8 + brSize*8 + bit/8] & (byte)(1 << (bit%8))) != 0; if (!Displayed) // offset is already biased by brSize, reuse shiftoff but for the display flags. Data[PokeDex + 0x8 + shiftoff + brSize*4 + bit/8] |= (byte)(1 << (bit%8)); // Set the Language if (lang < 0) lang = 1; Data[PokeDexLanguageFlags + (bit*7 + lang) / 8] |= (byte)(1 << ((bit*7 + lang) % 8)); // Formes int fc = Personal[pkm.Species].FormeCount; int f = B2W2 ? SaveUtil.getDexFormIndexB2W2(pkm.Species, fc) : SaveUtil.getDexFormIndexBW(pkm.Species, fc); if (f < 0) return; int FormLen = B2W2 ? 0xB : 0x9; int FormDex = PokeDex + 0x8 + brSize*9; bit = f + pkm.AltForm; // Set Form Seen Flag Data[FormDex + FormLen*shiny + bit/8] |= (byte)(1 << (bit%8)); // Set Displayed Flag if necessary, check all flags for (int i = 0; i < fc; i++) { bit = f + i; if ((Data[FormDex + FormLen*2 + bit/8] & (byte)(1 << (bit%8))) != 0) // Nonshiny return; // already set if ((Data[FormDex + FormLen*3 + bit/8] & (byte)(1 << (bit%8))) != 0) // Shiny return; // already set } bit = f + pkm.AltForm; Data[FormDex + FormLen * (2 + shiny) + bit / 8] |= (byte)(1 << (bit % 8)); }
internal static bool GetCanRelearnMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any) { return(GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, LVL: true, Relearn: true).Contains(move)); }
public override void setCaught(PKM pkm, bool caught = true) { if (pkm.Species == 0) return; if (pkm.Species > MaxSpeciesID) return; if (Version == GameVersion.Unknown) return; int bit = pkm.Species - 1; int ofs = bit >> 3; byte bitval = (byte)(1 << (bit & 7)); // Set the Captured Flag Data[(Japanese ? 0x259E : 0x25A3) + ofs] &= (byte)~bitval; if (caught) Data[(Japanese ? 0x259E : 0x25A3) + ofs] |= bitval; }
private static bool GetModified8BitMatch(PKM pk, uint pid, out PIDIV pidiv) { return(pk.Gen4 ? (pid <= 0xFF && GetCuteCharmMatch(pk, pid, out pidiv)) || GetG5MGShinyMatch(pk, pid, out pidiv) : GetG5MGShinyMatch(pk, pid, out pidiv) || (pid <= 0xFF && GetCuteCharmMatch(pk, pid, out pidiv))); }
/// <summary> /// Analyzes a <see cref="PKM"/> to find a matching PIDIV method. /// </summary> /// <param name="pk">Input <see cref="PKM"/>.</param> /// <returns><see cref="PIDIV"/> object containing seed and method info.</returns> public static PIDIV Analyze(PKM pk) { if (pk.Format < 3) { return(AnalyzeGB(pk)); } var pid = pk.EncryptionConstant; var top = pid >> 16; var bot = pid & 0xFFFF; var IVs = new uint[6]; for (int i = 0; i < 6; i++) { IVs[i] = (uint)pk.GetIV(i); } if (GetLCRNGMatch(top, bot, IVs, out PIDIV pidiv)) { return(pidiv); } if (pk.Species == (int)Species.Unown && GetLCRNGUnownMatch(top, bot, IVs, out pidiv)) // frlg only { return(pidiv); } if (GetColoStarterMatch(pk, top, bot, IVs, out pidiv)) { return(pidiv); } if (GetXDRNGMatch(pk, top, bot, IVs, out pidiv)) { return(pidiv); } // Special cases if (GetLCRNGRoamerMatch(top, bot, IVs, out pidiv)) { return(pidiv); } if (GetChannelMatch(top, bot, IVs, out pidiv, pk)) { return(pidiv); } if (GetMG4Match(pid, IVs, out pidiv)) { return(pidiv); } if (GetBACDMatch(pk, pid, IVs, out pidiv)) { return(pidiv); } if (GetModifiedPIDMatch(pk, pid, IVs, out pidiv)) { return(pidiv); } return(new PIDIV { Type = PIDType.None, NoSeed = true }); // no match }
/// <summary> /// Verifies Evolution scenarios of an <see cref="IEncounterable"/> for an input <see cref="PKM"/> and relevant <see cref="LegalInfo"/>. /// </summary> /// <param name="pkm">Source data to verify</param> /// <param name="info">Source supporting information to verify with</param> /// <returns></returns> public static CheckResult VerifyEvolution(PKM pkm, LegalInfo info) { return(IsValidEvolution(pkm, info) ? new CheckResult(CheckIdentifier.Evolution) : new CheckResult(Severity.Invalid, LEvoInvalid, CheckIdentifier.Evolution)); }
private void ResetView(ISlotViewer <T> sub, ISlotInfo slot, SlotTouchType type, PKM pkm) { if (PreviousPKM != null) { sub.NotifySlotOld(Previous); } if (!(slot is SlotInfoBox b) || sub.ViewIndex == b.Box) { sub.NotifySlotChanged(slot, type, pkm); } }
private static IEnumerable <int> GetValidMoves(PKM pkm, GameVersion Version, IReadOnlyList <EvoCriteria> vs, int generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true) { var r = new List <int> { 0 }; if (vs.Count == 0) { return(r); } int species = pkm.Species; if (FormChangeMoves.Contains(species)) // Deoxys & Shaymin & Giratina (others don't have extra but whatever) { // These don't evolve, so don't bother iterating for all entries in the evolution chain (should always be count==1). int formcount; // In gen 3 deoxys has different forms depending on the current game, in the PersonalInfo there is no alternate form info if (pkm.Format == 3 && species == 386) { formcount = 4; } else { formcount = pkm.PersonalInfo.FormeCount; } for (int i = 0; i < formcount; i++) { r.AddRange(GetMoves(pkm, species, minLvLG1, minLvLG2, vs[0].Level, i, Tutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, generation)); } if (Relearn) { r.AddRange(pkm.RelearnMoves); } return(r.Distinct()); } // Special Type Tutors Availability bool moveTutor = Tutor || MoveReminder; // Usually true, except when called for move suggestions (no tutored moves) for (var i = 0; i < vs.Count; i++) { var evo = vs[i]; var moves = GetEvoMoves(pkm, Version, vs, generation, minLvLG1, minLvLG2, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, moveTutor, i, evo); r.AddRange(moves); } if (pkm.Format <= 3) { return(r.Distinct()); } if (LVL) { MoveTutor.AddSpecialFormChangeMoves(r, pkm, generation, species); } if (Tutor) { MoveTutor.AddSpecialTutorMoves(r, pkm, generation, species); } if (Relearn && generation >= 6) { r.AddRange(pkm.RelearnMoves); } return(r.Distinct()); }
private static int GetMaxLevelGeneration(PKM pkm) { return(GetMaxLevelGeneration(pkm, pkm.GenNumber)); }
internal static int GetBaseSpecies(PKM pkm, IReadOnlyList <DexLevel> evos, int skipOption = 0) => GetBaseSpecies(pkm.Species, evos, skipOption);
private void showLegality(PKM pk, bool tabs, bool verbose, bool skipMoveRepop = false) { LegalityAnalysis la = new LegalityAnalysis(pk); if (!la.Parsed) { WinFormsUtil.Alert($"Checking legality of PK{pk.Format} files that originated from Gen{pk.GenNumber} is not supported."); return; } if (tabs) updateLegality(la, skipMoveRepop); WinFormsUtil.Alert(verbose ? la.VerboseReport : la.Report); }
private static bool GetChannelMatch(uint top, uint bot, uint[] IVs, out PIDIV pidiv, PKM pk) { var ver = pk.Version; if (ver is not((int)GameVersion.R or(int) GameVersion.S)) { return(GetNonMatch(out pidiv)); } var undo = top ^ 0x8000; if ((undo > 7 ? 0 : 1) != (bot ^ pk.SID ^ 40122)) { top = undo; } var channel = GetSeedsFromPIDEuclid(RNG.XDRNG, top, bot); foreach (var seed in channel) { var C = RNG.XDRNG.Advance(seed, 3); // held item // no checks, held item can be swapped var D = RNG.XDRNG.Next(C); // Version if ((D >> 31) + 1 != ver) // (0-Sapphire, 1-Ruby) { continue; } var E = RNG.XDRNG.Next(D); // OT Gender if (E >> 31 != pk.OT_Gender) { continue; } if (!RNG.XDRNG.GetSequentialIVsUInt32(E).SequenceEqual(IVs)) { continue; } if (seed >> 16 != pk.SID) { continue; } pidiv = new PIDIV { OriginSeed = RNG.XDRNG.Prev(seed), RNG = RNGType.XDRNG, Type = PIDType.Channel }; return(true); } return(GetNonMatch(out pidiv)); }
private void getQuickFiller(PictureBox pb, PKM pk = null) { if (!fieldsInitialized) return; pk = pk ?? preparePKM(false); // don't perform control loss click if (pb == dragout) mnuLQR.Enabled = pk.Species != 0; // Species var sprite = pk.Species != 0 ? pk.Sprite() : null; int slot = getSlot(pb); bool locked = slot < 30 && SAV.getIsSlotLocked(CB_BoxSelect.SelectedIndex, slot); bool team = slot < 30 && SAV.getIsTeamSet(CB_BoxSelect.SelectedIndex, slot); if (locked) sprite = ImageUtil.LayerImage(sprite, Resources.locked, 26, 0, 1); else if (team) sprite = ImageUtil.LayerImage(sprite, Resources.team, 21, 0, 1); pb.Image = sprite; if (pb.BackColor == Color.Red) pb.BackColor = Color.Transparent; }
private static bool GetBACDMatch(PKM pk, uint pid, uint[] IVs, out PIDIV pidiv) { var bot = GetIVChunk(IVs, 0); var top = GetIVChunk(IVs, 3); var reg = GetSeedsFromIVs(RNG.LCRNG, top, bot); PIDType type = PIDType.BACD_U; foreach (var seed in reg) { var B = seed; var A = RNG.LCRNG.Prev(B); var low = B >> 16; var PID = (A & 0xFFFF0000) | low; if (PID != pid) { uint idxor = (uint)(pk.TID ^ pk.SID); bool isShiny = (idxor ^ PID >> 16 ^ (PID & 0xFFFF)) < 8; if (!isShiny) { if (!pk.IsShiny) // check for nyx antishiny { if (!IsBACD_U_AX(idxor, pid, low, A, ref type)) { continue; } } else // check for force shiny pkm { if (!IsBACD_U_S(idxor, pid, low, ref A, ref type)) { continue; } } } else if (!IsBACD_U_AX(idxor, pid, low, A, ref type)) { if ((PID + 8 & 0xFFFFFFF8) != pid) { continue; } type = PIDType.BACD_U_A; } } var s = RNG.LCRNG.Prev(A); // Check for prior Restricted seed var sn = s; for (int i = 0; i < 3; i++, sn = RNG.LCRNG.Prev(sn)) { if ((sn & 0xFFFF0000) != 0) { continue; } // shift from unrestricted enum val to restricted enum val pidiv = new PIDIV { OriginSeed = sn, RNG = RNGType.LCRNG, Type = --type }; return(true); } // no restricted seed found, thus unrestricted pidiv = new PIDIV { OriginSeed = s, RNG = RNGType.LCRNG, Type = type }; return(true); } return(GetNonMatch(out pidiv)); }
public static string getShowdownText(PKM pkm) { if (pkm.Species == 0) return ""; string[] Forms = PKX.getFormList(pkm.Species, types, forms, new[] {"", "F", ""}, pkm.Format); ShowdownSet Set = new ShowdownSet { Nickname = pkm.Nickname, Species = pkm.Species, Item = pkm.HeldItem, Ability = pkm.Ability, EVs = pkm.EVs, IVs = pkm.IVs, Moves = pkm.Moves, Nature = pkm.Nature, Gender = new[] { "M", "F", "" }[pkm.Gender < 2 ? pkm.Gender : 2], Friendship = pkm.CurrentFriendship, Level = PKX.getLevel(pkm.Species, pkm.EXP), Shiny = pkm.IsShiny, Form = pkm.AltForm > 0 && pkm.AltForm < Forms.Length ? Forms[pkm.AltForm] : "", }; if (Set.Form == "F") Set.Gender = ""; return Set.getText(); }
private static PIDIV AnalyzeGB(PKM _) { // not implemented; correlation between IVs and RNG hasn't been converted to code. return(PIDIV.None); }
public virtual void setStoredSlot(PKM pkm, int offset, bool? trade = null, bool? dex = null) { if (pkm == null) return; if (pkm.GetType() != PKMType) throw new InvalidCastException($"PKM Format needs to be {PKMType} when setting to a {GetType().Name.Last()} Save File."); if (trade ?? SetUpdatePKM) setPKM(pkm); if (dex ?? SetUpdateDex) setDex(pkm); setData(pkm.EncryptedBoxData, offset); Edited = true; }
private static void SetMetData(PKM pk) { pk.Met_Level = EncounterSuggestion.GetSuggestedEncounterEggMetLevel(pk); pk.Met_Location = Math.Max(0, EncounterSuggestion.GetSuggestedEggMetLocation(pk)); }
public virtual void setSeen(PKM pkm, bool seen = true) { }
/// <summary> /// Checks the input <see cref="PKM"/> data for legality. This is the best method for checking with context, as some games do not have all Alternate Form data available. /// </summary> /// <param name="pk">Input data to check</param> /// <param name="table"><see cref="SaveFile"/> specific personal data</param> public LegalityAnalysis(PKM pk, PersonalTable table) : this(pk, table.GetFormeEntry(pk.Species, pk.AltForm)) { }
public override void setSeen(PKM pkm, bool seen = true) { if (pkm.Species == 0) return; if (pkm.Species > MaxSpeciesID) return; if (Version == GameVersion.Unknown) return; int bit = pkm.Species - 1; int ofs = bit >> 3; byte bitval = (byte)(1 << (bit & 7)); // Set the Seen Flag Data[PokedexSeenOffset + ofs] &= (byte)~bitval; if (seen) Data[PokedexSeenOffset + ofs] |= bitval; }
/// <summary> /// Checks the input <see cref="PKM"/> data for legality. /// </summary> /// <param name="pk">Input data to check</param> public LegalityAnalysis(PKM pk) : this(pk, pk.PersonalInfo) { }
protected override IEnumerable <EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable <EncounterSlot> slots, int minLevel) => slots;
private static IEnumerable <IEncounterable> GenerateRawEncounters12(PKM pkm, GameVersion game) { // Since encounter matching is super weak due to limited stored data in the structure // Calculate all 3 at the same time and pick the best result (by species). // Favor special event move gifts as Static Encounters when applicable var chain = EvolutionChain.GetOriginChain(pkm, game); var deferred = new List <IEncounterable>(); foreach (var t in GetValidEncounterTrades(pkm, chain, game)) { // some OTs are longer than the keyboard entry; don't defer these if (pkm.Format >= 7 && pkm.OT_Name.Length <= (pkm.Japanese || pkm.Korean ? 5 : 7)) { deferred.Add(t); continue; } yield return(t); } foreach (var s in GetValidStaticEncounter(pkm, chain, game)) { // Valid stadium and non-stadium encounters, return only non-stadium encounters, they are less restrictive switch (s.Version) { case GameVersion.Stadium: case GameVersion.Stadium2: deferred.Add(s); continue; case GameVersion.EventsGBGen2: if (!s.EggEncounter && !pkm.HasOriginalMetLocation) { continue; } if (pkm.Japanese) { deferred.Add(s); } continue; case GameVersion.C when pkm.Format == 2: // Crystal specific data needs to be present if (!s.EggEncounter && !pkm.HasOriginalMetLocation) { continue; } if (s.Species == 251 && ParseSettings.AllowGBCartEra) // no celebi, the GameVersion.EventsGBGen2 will pass thru { continue; } break; } yield return(s); } foreach (var e in GetValidWildEncounters12(pkm, chain, game)) { yield return(e); } if (GameVersion.GSC.Contains(game)) { foreach (var e in EncounterEggGenerator2.GenerateEggs(pkm, chain)) { yield return(e); } } foreach (var d in deferred) { yield return(d); } }
private void AddLine(PKM first, PKM second, string msg, CheckIdentifier i, Severity s = Severity.Invalid) {
public static void setPKMtoDestination(SaveFile SAV, PKM pk) { int o = slotDestinationOffset; if (!DestinationParty) { SAV.setStoredSlot(pk, o); return; } if (30 + SAV.PartyCount < slotDestinationSlotNumber) { o = SAV.getPartyOffset(SAV.PartyCount); slotDestinationSlotNumber = 30 + SAV.PartyCount; } if (pk.Stat_HPMax == 0) // Without Stats (Box/File) { pk.setStats(pk.getStats(SAV.Personal.getFormeEntry(pk.Species, pk.AltForm))); pk.Stat_Level = pk.CurrentLevel; } SAV.setPartySlot(pk, o); }
private void clickMetLocation(object sender, EventArgs e) { if (HaX) return; pkm = preparePKM(); var encounter = Legality.getSuggestedMetInfo(); if (encounter == null || encounter.Location < 0) { WinFormsUtil.Alert("Unable to provide a suggestion."); return; } int level = encounter.Level; int location = encounter.Location; int minlvl = Legal.getLowestLevel(pkm, encounter.Species); if (pkm.Met_Level == level && pkm.Met_Location == location && pkm.CurrentLevel >= minlvl) return; var met_list = GameInfo.getLocationList((GameVersion)pkm.Version, SAV.Generation, egg: false); var locstr = met_list.FirstOrDefault(loc => loc.Value == location)?.Text; string suggestion = $"Suggested:\nMet Location: {locstr}\nMet Level: {level}"; if (pkm.CurrentLevel < minlvl) suggestion += $"\nCurrent Level {minlvl}"; if (WinFormsUtil.Prompt(MessageBoxButtons.YesNo, suggestion) != DialogResult.Yes) return; TB_MetLevel.Text = level.ToString(); CB_MetLocation.SelectedValue = location; if (pkm.CurrentLevel < minlvl) TB_Level.Text = minlvl.ToString(); pkm = preparePKM(); updateLegality(); }
private void openSAV(SaveFile sav, string path) { if (sav == null || sav.Version == GameVersion.Invalid) { WinFormsUtil.Error("Invalid save file loaded. Aborting.", path); return; } if (!string.IsNullOrEmpty(path)) // If path is null, this is the default save { if (sav.RequiresMemeCrypto && !MemeCrypto.CanUseMemeCrypto()) { WinFormsUtil.Error("Your platform does not support the required cryptography components.", "In order to be able to save your changes, you must either upgrade to a newer version of Windows or disable FIPS compliance mode."); // Don't abort loading; user can still view save and fix checksum on another platform. } } // Finish setting up the save file. if (sav.IndeterminateGame && sav.Generation == 3) { // Hacky cheats invalidated the Game Code value. var drGame = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Unknown Gen3 Game Detected. Select Origins:", "Yes: Ruby / Sapphire" + Environment.NewLine + "No: Emerald" + Environment.NewLine + "Cancel: FireRed / LeafGreen"); switch (drGame) // Reset save file info { case DialogResult.Yes: sav = new SAV3(sav.BAK, GameVersion.RS); break; case DialogResult.No: sav = new SAV3(sav.BAK, GameVersion.E); break; case DialogResult.Cancel: sav = new SAV3(sav.BAK, GameVersion.FRLG); break; default: return; } } if (sav.IndeterminateLanguage) { // Japanese Save files are different. Get isJapanese var drJP = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, $"{sav.Version} Save File detected. Select language...", "Yes: International" + Environment.NewLine + "No: Japanese"); if (drJP == DialogResult.Cancel) return; sav.Japanese = drJP == DialogResult.No; } if (sav.IndeterminateSubVersion && sav.Version == GameVersion.FRLG) { var drFRLG = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, $"{sav.Version} detected. Select version...", "Yes: FireRed" + Environment.NewLine + "No: LeafGreen"); if (drFRLG == DialogResult.Cancel) return; sav.Personal = drFRLG == DialogResult.Yes ? PersonalTable.FR : PersonalTable.LG; } // clean fields PKM pk = preparePKM(); populateFields(SAV.BlankPKM); SAV = sav; string title = $"PKH{(HaX ? "a" : "e")}X ({Resources.ProgramVersion}) - " + $"SAV{SAV.Generation}: "; if (path != null) // Actual save file { SAV.FilePath = Path.GetDirectoryName(path); SAV.FileName = Path.GetExtension(path) == ".bak" ? Path.GetFileName(path).Split(new[] { " [" }, StringSplitOptions.None)[0] : Path.GetFileName(path); Text = title + $"{Path.GetFileNameWithoutExtension(Util.CleanFileName(SAV.BAKName))}"; // more descriptive // If backup folder exists, save a backup. string backupName = Path.Combine(BackupPath, Util.CleanFileName(SAV.BAKName)); if (SAV.Exportable && Directory.Exists(BackupPath) && !File.Exists(backupName)) File.WriteAllBytes(backupName, SAV.BAK); GB_SAVtools.Visible = true; } else // Blank save file { SAV.FilePath = null; SAV.FileName = "Blank Save File"; Text = title + $"{SAV.FileName} [{SAV.OT} ({SAV.Version})]"; GB_SAVtools.Visible = false; } Menu_ExportSAV.Enabled = B_VerifyCHK.Enabled = SAV.Exportable; // Close subforms that are save dependent Type[] f = { typeof(SAV_BoxViewer), typeof(f2_Text) }; foreach (var form in Application.OpenForms.Cast<Form>().Where(form => f.Contains(form.GetType())).ToArray()) form.Close(); setBoxNames(); // Display the Box Names if (SAV.HasBox) { int startBox = path == null ? 0 : SAV.CurrentBox; // FF if BattleBox if (startBox > SAV.BoxCount - 1) { tabBoxMulti.SelectedIndex = 1; CB_BoxSelect.SelectedIndex = 0; } else { tabBoxMulti.SelectedIndex = 0; CB_BoxSelect.SelectedIndex = startBox; } } setPKXBoxes(); // Reload all of the PKX Windows bool WindowTranslationRequired = false; // Hide content if not present in game. GB_SUBE.Visible = SAV.HasSUBE; PB_Locked.Visible = SAV.HasBattleBox && SAV.BattleBoxLocked; if (!SAV.HasBox && tabBoxMulti.TabPages.Contains(Tab_Box)) tabBoxMulti.TabPages.Remove(Tab_Box); else if (SAV.HasBox && !tabBoxMulti.TabPages.Contains(Tab_Box)) { tabBoxMulti.TabPages.Insert(0, Tab_Box); WindowTranslationRequired = true; } Menu_LoadBoxes.Enabled = Menu_DumpBoxes.Enabled = Menu_Report.Enabled = Menu_Modify.Enabled = B_SaveBoxBin.Enabled = SAV.HasBox; int BoxTab = tabBoxMulti.TabPages.IndexOf(Tab_Box); int PartyTab = tabBoxMulti.TabPages.IndexOf(Tab_PartyBattle); if (!SAV.HasParty && tabBoxMulti.TabPages.Contains(Tab_PartyBattle)) tabBoxMulti.TabPages.Remove(Tab_PartyBattle); else if (SAV.HasParty && !tabBoxMulti.TabPages.Contains(Tab_PartyBattle)) { int index = BoxTab; if (index < 0) index = -1; tabBoxMulti.TabPages.Insert(index + 1, Tab_PartyBattle); WindowTranslationRequired = true; } if (!SAV.HasDaycare && tabBoxMulti.TabPages.Contains(Tab_Other)) tabBoxMulti.TabPages.Remove(Tab_Other); else if (SAV.HasDaycare && !tabBoxMulti.TabPages.Contains(Tab_Other)) { int index = PartyTab; if (index < 0) index = BoxTab; if (index < 0) index = -1; tabBoxMulti.TabPages.Insert(index + 1, Tab_Other); WindowTranslationRequired = true; } if (path != null) // Actual save file { PAN_BattleBox.Visible = L_BattleBox.Visible = L_ReadOnlyPBB.Visible = SAV.HasBattleBox; GB_Daycare.Visible = SAV.HasDaycare; GB_Fused.Visible = SAV.HasFused; GB_GTS.Visible = SAV.HasGTS; B_OpenSecretBase.Enabled = SAV.HasSecretBase; B_OpenPokepuffs.Enabled = SAV.HasPuff; B_OpenPokeBeans.Enabled = SAV.Generation == 7; B_OpenZygardeCells.Enabled = SAV.Generation == 7; B_OUTPasserby.Enabled = SAV.HasPSS; B_OpenBoxLayout.Enabled = SAV.HasBoxWallpapers; B_OpenWondercards.Enabled = SAV.HasWondercards; B_OpenSuperTraining.Enabled = SAV.HasSuperTrain; B_OpenHallofFame.Enabled = SAV.HasHoF; B_OpenOPowers.Enabled = SAV.HasOPower; B_OpenPokedex.Enabled = SAV.HasPokeDex; B_OpenBerryField.Enabled = SAV.HasBerryField && SAV.XY; B_OpenPokeblocks.Enabled = SAV.HasPokeBlock; B_JPEG.Visible = SAV.HasJPEG; B_OpenEventFlags.Enabled = SAV.HasEvents; B_OpenLinkInfo.Enabled = SAV.HasLink; B_CGearSkin.Enabled = SAV.Generation == 5; B_OpenTrainerInfo.Enabled = B_OpenItemPouch.Enabled = SAV.HasParty; // Box RS } GB_SAVtools.Visible = (path != null) && FLP_SAVtools.Controls.Cast<Control>().Any(c => c.Enabled); foreach (Control c in FLP_SAVtools.Controls.Cast<Control>()) c.Visible = c.Enabled; // Generational Interface byte[] extraBytes = new byte[1]; Tip1.RemoveAll(); Tip2.RemoveAll(); Tip3.RemoveAll(); // TSV/PSV FLP_Country.Visible = FLP_SubRegion.Visible = FLP_3DSRegion.Visible = SAV.Generation >= 6; Label_EncryptionConstant.Visible = BTN_RerollEC.Visible = TB_EC.Visible = SAV.Generation >= 6; GB_nOT.Visible = GB_RelearnMoves.Visible = BTN_Medals.Visible = BTN_History.Visible = SAV.Generation >= 6; PB_Legal.Visible = PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible = SAV.Generation >= 6; PB_MarkPentagon.Visible = SAV.Generation >= 6; PB_MarkAlola.Visible = SAV.Generation >= 7; TB_Secure1.Visible = TB_Secure2.Visible = L_Secure1.Visible = L_Secure2.Visible = SAV.Exportable && SAV.Generation >= 6; TB_GameSync.Visible = L_GameSync.Visible = SAV.Exportable && SAV.Generation >= 6; FLP_NSparkle.Visible = L_NSparkle.Visible = CHK_NSparkle.Visible = SAV.Generation == 5; CB_Form.Visible = Label_Form.Visible = CHK_AsEgg.Visible = GB_EggConditions.Visible = PB_Mark5.Visible = PB_Mark6.Visible = SAV.Generation >= 4; DEV_Ability.Enabled = DEV_Ability.Visible = SAV.Generation > 3 && HaX; CB_Ability.Visible = !DEV_Ability.Enabled && SAV.Generation >= 3; FLP_Nature.Visible = SAV.Generation >= 3; FLP_Ability.Visible = SAV.Generation >= 3; FLP_Language.Visible = SAV.Generation >= 3; GB_ExtraBytes.Visible = GB_ExtraBytes.Enabled = SAV.Generation >= 3; GB_Markings.Visible = SAV.Generation >= 3; BTN_Ribbons.Visible = SAV.Generation >= 3; CB_HPType.Enabled = CB_Form.Enabled = SAV.Generation >= 3; BTN_RerollPID.Visible = Label_PID.Visible = TB_PID.Visible = Label_SID.Visible = TB_SID.Visible = SAV.Generation >= 3; FLP_FriendshipForm.Visible = SAV.Generation >= 2; FLP_HeldItem.Visible = SAV.Generation >= 2; CHK_IsEgg.Visible = Label_Gender.Visible = SAV.Generation >= 2; FLP_PKRS.Visible = FLP_EggPKRSRight.Visible = SAV.Generation >= 2; Label_OTGender.Visible = SAV.Generation >= 2; if (SAV.Generation == 1) Label_IsShiny.Visible = false; if (SAV.Version == GameVersion.BATREV) { L_SaveSlot.Visible = CB_SaveSlot.Visible = true; CB_SaveSlot.DisplayMember = "Text"; CB_SaveSlot.ValueMember = "Value"; CB_SaveSlot.DataSource = new BindingSource(((SAV4BR) SAV).SaveSlots.Select(i => new ComboItem { Text = ((SAV4BR) SAV).SaveNames[i], Value = i }).ToList(), null); CB_SaveSlot.SelectedValue = ((SAV4BR)SAV).CurrentSlot; } else L_SaveSlot.Visible = CB_SaveSlot.Visible = false; FLP_Purification.Visible = FLP_ShadowID.Visible = SAV.Version == GameVersion.COLO || SAV.Version == GameVersion.XD; NUD_ShadowID.Maximum = SAV.MaxShadowID; // HaX override, needs to be after DEV_Ability enabled assignment. TB_AbilityNumber.Visible = SAV.Generation >= 6 && DEV_Ability.Enabled; // Met Tab FLP_MetDate.Visible = SAV.Generation >= 4; FLP_Fateful.Visible = FLP_Ball.Visible = FLP_OriginGame.Visible = SAV.Generation >= 3; FLP_MetLocation.Visible = FLP_MetLevel.Visible = SAV.Generation >= 2; FLP_TimeOfDay.Visible = SAV.Generation == 2; // Stats FLP_StatsTotal.Visible = SAV.Generation >= 3; FLP_Characteristic.Visible = SAV.Generation >= 3; FLP_HPType.Visible = SAV.Generation >= 2; PAN_Contest.Visible = SAV.Generation >= 3; // Second daycare slot SlotPictureBoxes[43].Visible = SAV.Generation >= 2; if (sav.Generation == 1) { FLP_SpD.Visible = false; Label_SPA.Visible = false; Label_SPC.Visible = true; TB_HPIV.Enabled = false; MaskedTextBox[] evControls = { TB_SPAEV, TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPDEV }; foreach (var ctrl in evControls) { ctrl.Mask = "00000"; ctrl.Size = Stat_HP.Size; } } else if (sav.Generation == 2) { FLP_SpD.Visible = true; Label_SPA.Visible = true; Label_SPC.Visible = false; TB_SPDEV.Enabled = TB_SPDIV.Enabled = false; TB_HPIV.Enabled = false; MaskedTextBox[] evControls = { TB_SPAEV, TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPDEV }; foreach (var ctrl in evControls) { ctrl.Mask = "00000"; ctrl.Size = Stat_HP.Size; } } else { FLP_SpD.Visible = true; Label_SPA.Visible = true; Label_SPC.Visible = false; TB_SPDEV.Enabled = TB_SPDIV.Enabled = true; TB_HPIV.Enabled = true; MaskedTextBox[] evControls = { TB_SPAEV, TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPDEV }; foreach (var ctrl in evControls) { ctrl.Mask = "000"; ctrl.Size = TB_ExtraByte.Size; } } // Recenter PKM SubEditors FLP_PKMEditors.Location = new Point((Tab_OTMisc.Width - FLP_PKMEditors.Width) / 2, FLP_PKMEditors.Location.Y); bool init = fieldsInitialized; fieldsInitialized = fieldsLoaded = false; switch (SAV.Generation) { case 6: TB_GameSync.Enabled = SAV.GameSyncID != null; TB_GameSync.MaxLength = SAV.GameSyncIDSize; TB_GameSync.Text = (SAV.GameSyncID ?? 0.ToString()).PadLeft(SAV.GameSyncIDSize, '0'); TB_Secure1.Text = SAV.Secure1?.ToString("X16"); TB_Secure2.Text = SAV.Secure2?.ToString("X16"); break; case 7: TB_GameSync.Enabled = SAV.GameSyncID != null; TB_GameSync.MaxLength = SAV.GameSyncIDSize; TB_GameSync.Text = (SAV.GameSyncID ?? 0.ToString()).PadLeft(SAV.GameSyncIDSize, '0'); TB_Secure1.Text = SAV.Secure1?.ToString("X16"); TB_Secure2.Text = SAV.Secure2?.ToString("X16"); break; } pkm = pkm.GetType() != SAV.PKMType ? SAV.BlankPKM : pk; if (pkm.Format < 3) pkm = SAV.BlankPKM; populateFilteredDataSources(); populateFields(pkm); fieldsInitialized |= init; // SAV Specific Limits TB_OT.MaxLength = SAV.OTLength; TB_OTt2.MaxLength = SAV.OTLength; TB_Nickname.MaxLength = SAV.NickLength; // Hide Unused Tabs if (SAV.Generation == 1 && tabMain.TabPages.Contains(Tab_Met)) tabMain.TabPages.Remove(Tab_Met); else if (SAV.Generation != 1 && !tabMain.TabPages.Contains(Tab_Met)) { tabMain.TabPages.Insert(1, Tab_Met); WindowTranslationRequired = true; } // Common HaX Interface CHK_HackedStats.Enabled = CHK_HackedStats.Visible = MT_Level.Enabled = MT_Level.Visible = MT_Form.Enabled = MT_Form.Visible = HaX; TB_Level.Visible = !HaX; // Setup PKM Preparation/Extra Bytes setPKMFormatMode(SAV.Generation, SAV.Version); // pk2 save files do not have an Origin Game stored. Prompt the met location list to update. if (SAV.Generation == 2) updateOriginGame(null, null); // Refresh PK* conversion info PKMConverter.updateConfig(SAV.SubRegion, SAV.Country, SAV.ConsoleRegion, SAV.OT, SAV.Gender); if (WindowTranslationRequired) // force update -- re-added controls may be untranslated WinFormsUtil.TranslateInterface(this, curlanguage); // No changes made yet UndoStack.Clear(); Menu_Undo.Enabled = false; RedoStack.Clear(); Menu_Redo.Enabled = false; // Indicate audibly the save is loaded SystemSounds.Beep.Play(); }
public static string[] verifyPKMtoSAV(PKM pk) { // Check if PKM properties are outside of the valid range List<string> errata = new List<string>(); if (SAV.Generation > 1) { ushort held = (ushort)pk.HeldItem; if (held > GameInfo.Strings.itemlist.Length) errata.Add($"Item Index beyond range: {held}"); else if (held > SAV.MaxItemID) errata.Add($"Game can't obtain item: {GameInfo.Strings.itemlist[held]}"); else if (!pk.CanHoldItem(SAV.HeldItems)) errata.Add($"Game can't hold item: {GameInfo.Strings.itemlist[held]}"); } if (pk.Species > GameInfo.Strings.specieslist.Length) errata.Add($"Species Index beyond range: {pk.HeldItem}"); else if (SAV.MaxSpeciesID < pk.Species) errata.Add($"Game can't obtain species: {GameInfo.Strings.specieslist[pk.Species]}"); if (pk.Moves.Any(m => m > GameInfo.Strings.movelist.Length)) errata.Add($"Item Index beyond range: {string.Join(", ", pk.Moves.Where(m => m > GameInfo.Strings.movelist.Length).Select(m => m.ToString()))}"); else if (pk.Moves.Any(m => m > SAV.MaxMoveID)) errata.Add($"Game can't have move: {string.Join(", ", pk.Moves.Where(m => m > SAV.MaxMoveID).Select(m => GameInfo.Strings.movelist[m]))}"); if (pk.Ability > GameInfo.Strings.abilitylist.Length) errata.Add($"Ability Index beyond range: {pk.Ability}"); else if (pk.Ability > SAV.MaxAbilityID) errata.Add($"Game can't have ability: {GameInfo.Strings.abilitylist[pk.Ability]}"); return errata.ToArray(); }
protected override void setDex(PKM pkm) { if (pkm.Species == 0) return; if (pkm.Species > MaxSpeciesID) return; if (Version == GameVersion.Unknown) return; if (PokeDex < 0) return; const int brSize = 0x40; int bit = pkm.Species - 1; // Set the Species Owned Flag Data[PokeDex + brSize*0 + bit/8 + 0x4] |= (byte) (1 << (bit%8)); // Set the Species Seen Flag Data[PokeDex + brSize*1 + bit/8 + 0x4] |= (byte) (1 << (bit%8)); int FormOffset1 = PokeDex + 0x108; int PokeDexLanguageFlags = FormOffset1 + 0x20; // Formes : Castform & Cherrim do not have entries (Battle Only formes) // Lowest sub-value of formevalue is displayed, else is order of formes displayed. // Deoxys forms 1-2 are stored in the last byte of the first bitRegion. // Deoxys forms 3-4 are stored in the last byte of the second bitRegion. if (pkm.Species == 386) { uint val = (uint)(Data[PokeDex + 0x4 + 1*brSize - 1] | Data[PokeDex + 0x4 + 2*brSize - 1] << 8); int[] forms = getDexFormValues(val, 4, 4); checkInsertForm(ref forms, pkm.AltForm); uint newval = setDexFormValues(forms, 4, 4); Data[PokeDex + 0x4 + 1*brSize - 1] = (byte)(newval & 0xFF); Data[PokeDex + 0x4 + 2*brSize - 1] = (byte)((newval>>8) & 0xFF); } // After the BitRegions is 0x20 bytes for the rest of the formes. // Standard Forme Bytes (DP) // [Shellos-Gastrodon-Burmy-Wormadam],[Unown*0x1C] if (pkm.Species == 422) // Shellos { int[] forms = getDexFormValues(Data[FormOffset1 + 0], 2, 2); checkInsertForm(ref forms, pkm.AltForm); uint newval = setDexFormValues(forms, 2, 2); Data[FormOffset1 + 0] = (byte)newval; } if (pkm.Species == 423) // Gastrodon { int[] forms = getDexFormValues(Data[FormOffset1 + 1], 2, 2); checkInsertForm(ref forms, pkm.AltForm); uint newval = setDexFormValues(forms, 2, 2); Data[FormOffset1 + 1] = (byte)newval; } if (pkm.Species == 412) // Burmy { int[] forms = getDexFormValues(Data[FormOffset1 + 2], 2, 3); checkInsertForm(ref forms, pkm.AltForm); uint newval = setDexFormValues(forms, 2, 3); Data[FormOffset1 + 2] = (byte)newval; } if (pkm.Species == 413) // Wormadam { int[] forms = getDexFormValues(Data[FormOffset1 + 3], 2, 3); checkInsertForm(ref forms, pkm.AltForm); uint newval = setDexFormValues(forms, 2, 3); Data[FormOffset1 + 3] = (byte)newval; } if (pkm.Species == 201) // Unown { for (int i = 0; i < 0x1C; i++) { byte val = Data[FormOffset1 + 4 + i]; if (val == pkm.AltForm) break; // already set if (val != 0xFF) continue; // keep searching Data[FormOffset1 + 4 + i] = (byte)pkm.AltForm; break; // form now set } } // DP stops here. if (DP) return; // Set the Language int lang = pkm.Language - 1; if (lang > 5) lang = 0; // no KOR if (lang < 0) lang = 1; Data[PokeDexLanguageFlags + pkm.Species] |= (byte) (1 << lang); int FormOffset2 = PokeDexLanguageFlags + 0x210; // PtHGSS added more forms. // [Rotom*4-highest bits unused],[Shaymin],[Giratina],[Pichu-HGSS ONLY] if (pkm.Species == 479) // Rotom { int[] forms = getDexFormValues(BitConverter.ToUInt32(Data, FormOffset2), 3, 6); checkInsertForm(ref forms, pkm.AltForm); uint newval = setDexFormValues(forms, 3, 6); BitConverter.GetBytes(newval).CopyTo(Data, FormOffset2); } if (pkm.Species == 492) // Shaymin { int[] forms = getDexFormValues(Data[FormOffset2 + 4], 2, 2); uint newval = setDexFormValues(forms, 2, 2); Data[FormOffset1 + 3] = (byte)newval; } if (pkm.Species == 487) // Giratina { int[] forms = getDexFormValues(Data[FormOffset2 + 5], 2, 2); uint newval = setDexFormValues(forms, 2, 2); Data[FormOffset1 + 3] = (byte)newval; } if (pkm.Species == 172 && HGSS) // Pichu { int[] forms = getDexFormValues(Data[FormOffset2 + 6], 2, 3); uint newval = setDexFormValues(forms, 2, 3); Data[FormOffset1 + 3] = (byte)newval; } }
public static void setPKMtoSource(SaveFile SAV, PKM pk) { int o = slotSourceOffset; if (!SourceParty) { SAV.setStoredSlot(pk, o); return; } if (pk.Species == 0) // Empty Slot { SAV.deletePartySlot(slotSourceSlotNumber-30); return; } if (pk.Stat_HPMax == 0) // Without Stats (Box) { pk.setStats(pk.getStats(SAV.Personal.getFormeEntry(pk.Species, pk.AltForm))); pk.Stat_Level = pk.CurrentLevel; } SAV.setPartySlot(pk, o); }
internal static int GetEggHatchLevel(PKM pkm) => GetEggHatchLevel(pkm.Format);
// Misc Options private void clickShowdownImportPKM(object sender, EventArgs e) { if (!formInitialized) return; if (!Clipboard.ContainsText()) { WinFormsUtil.Alert("Clipboard does not contain text."); return; } // Get Simulator Data ShowdownSet Set = new ShowdownSet(Clipboard.GetText()); if (Set.Species < 0) { WinFormsUtil.Alert("Set data not found in clipboard."); return; } if (Set.Nickname != null && Set.Nickname.Length > SAV.NickLength) Set.Nickname = Set.Nickname.Substring(0, SAV.NickLength); if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Import this set?", Set.getText())) { return; } if (Set.InvalidLines.Any()) WinFormsUtil.Alert("Invalid lines detected:", string.Join(Environment.NewLine, Set.InvalidLines)); // Set Species & Nickname CB_Species.SelectedValue = Set.Species; CHK_Nicknamed.Checked = Set.Nickname != null; if (Set.Nickname != null) TB_Nickname.Text = Set.Nickname; if (Set.Gender != null) { int Gender = PKX.getGender(Set.Gender); Label_Gender.Text = gendersymbols[Gender]; Label_Gender.ForeColor = Gender == 2 ? Label_Species.ForeColor : (Gender == 1 ? Color.Red : Color.Blue); } // Set Form string[] formStrings = PKX.getFormList(Set.Species, Util.getTypesList("en"), Util.getFormsList("en"), gendersymbols, SAV.Generation); int form = 0; for (int i = 0; i < formStrings.Length; i++) if (formStrings[i].Contains(Set.Form ?? "")) { form = i; break; } CB_Form.SelectedIndex = Math.Min(CB_Form.Items.Count-1, form); // Set Ability int[] abilities = SAV.Personal.getAbilities(Set.Species, form); int ability = Array.IndexOf(abilities, Set.Ability); if (ability < 0) ability = 0; CB_Ability.SelectedIndex = ability; ComboBox[] m = {CB_Move1, CB_Move2, CB_Move3, CB_Move4}; for (int i = 0; i < 4; i++) m[i].SelectedValue = Set.Moves[i]; // Set Item and Nature CB_HeldItem.SelectedValue = Set.Item < 0 ? 0 : Set.Item; CB_Nature.SelectedValue = Set.Nature < 0 ? 0 : Set.Nature; // Set IVs TB_HPIV.Text = Set.IVs[0].ToString(); TB_ATKIV.Text = Set.IVs[1].ToString(); TB_DEFIV.Text = Set.IVs[2].ToString(); TB_SPAIV.Text = Set.IVs[4].ToString(); TB_SPDIV.Text = Set.IVs[5].ToString(); TB_SPEIV.Text = Set.IVs[3].ToString(); // Set EVs TB_HPEV.Text = Set.EVs[0].ToString(); TB_ATKEV.Text = Set.EVs[1].ToString(); TB_DEFEV.Text = Set.EVs[2].ToString(); TB_SPAEV.Text = Set.EVs[4].ToString(); TB_SPDEV.Text = Set.EVs[5].ToString(); TB_SPEEV.Text = Set.EVs[3].ToString(); // Set Level and Friendship TB_Level.Text = Set.Level.ToString(); TB_Friendship.Text = Set.Friendship.ToString(); // Reset IV/EVs BTN_RerollPID.PerformClick(); BTN_RerollEC.PerformClick(); ComboBox[] p = {CB_PPu1, CB_PPu2, CB_PPu3, CB_PPu4}; for (int i = 0; i < 4; i++) p[i].SelectedIndex = m[i].SelectedIndex != 0 ? 3 : 0; // max PP if (Set.Shiny) BTN_Shinytize.PerformClick(); pkm = preparePKM(); updateLegality(); }
private static IEnumerable <EncounterArea> getEncounterAreas(PKM pkm) { return(getEncounterSlots(pkm).Where(l => l.Location == pkm.Met_Location)); }
public static PKM convertToFormat(PKM pk, Type PKMType, out string comment) { if (pk == null || pk.Species == 0) { comment = "Null input. Aborting."; return null; } Type fromType = pk.GetType(); int fromFormat = int.Parse(fromType.Name.Last().ToString()); int toFormat = int.Parse(PKMType.Name.Last().ToString()); Console.WriteLine($"Trying to convert {fromType.Name} to {PKMType.Name}."); PKM pkm = null; if (fromType == PKMType) { comment = "No need to convert, current format matches requested format."; return pk; } if (fromFormat <= toFormat || fromFormat == 2) { pkm = pk.Clone(); if (pkm.IsEgg) // force hatch { pkm.IsEgg = false; if (pkm.AO) pkm.Met_Location = 318; // Battle Resort else if (pkm.XY) pkm.Met_Location = 38; // Route 7 else if (pkm.Gen5) pkm.Met_Location = 16; // Route 16 else pkm.Met_Location = 30001; // Pokétransfer } switch (fromType.Name) { case nameof(PK1): if (toFormat == 2) { pkm = PKMType == typeof (PK2) ? ((PK1) pk).convertToPK2() : null; break; } if (toFormat == 7) pkm = null; // pkm.convertPK1toPK7(); break; case nameof(PK2): if (PKMType == typeof (PK1)) { if (pk.Species > 151) { comment = $"Cannot convert a {PKX.getSpeciesName(pkm.Species, ((PK2)pkm).Japanese ? 1 : 2)} to {PKMType.Name}"; return null; } pkm = ((PK2) pk).convertToPK1(); } else pkm = null; break; case nameof(CK3): case nameof(XK3): // interconverting C/XD needs to visit main series format // ends up stripping purification/shadow etc stats pkm = pkm.convertToPK3(); goto case nameof(PK3); // fall through case nameof(PK3): if (toFormat == 3) // Gen3 Inter-trading { switch (PKMType.Name) { case nameof(CK3): pkm = pkm.convertToCK3(); break; case nameof(XK3): pkm = pkm.convertToXK3(); break; case nameof(PK3): pkm = pkm.convertToPK3(); break; // already converted, instantly returns default: throw new FormatException(); } break; } if (fromType.Name != nameof(PK3)) pkm = pkm.convertToPK3(); pkm = ((PK3)pkm).convertToPK4(); if (toFormat == 4) break; goto case nameof(PK4); case nameof(BK4): pkm = ((BK4)pkm).convertToPK4(); if (toFormat == 4) break; goto case nameof(PK4); case nameof(PK4): if (PKMType == typeof(BK4)) { pkm = ((PK4)pkm).convertToBK4(); break; } pkm = ((PK4)pkm).convertToPK5(); if (toFormat == 5) break; goto case nameof(PK5); case nameof(PK5): pkm = ((PK5)pkm).convertToPK6(); if (toFormat == 6) break; goto case nameof(PK6); case nameof(PK6): pkm = new PK7(pkm.Data, pkm.Identifier); if (toFormat == 7) break; goto case nameof(PK7); case nameof(PK7): break; } } comment = pkm == null ? $"Cannot convert a {fromType.Name} to a {PKMType.Name}." : $"Converted from {fromType.Name} to {PKMType.Name}."; return pkm; }
private static IEnumerable <EncounterSlot> getValidEncounterSlots(PKM pkm, EncounterArea loc, bool DexNav, bool ignoreLevel = false) { const int fluteBoost = 4; const int dexnavBoost = 30; int df = DexNav ? fluteBoost : 0; int dn = DexNav ? fluteBoost + dexnavBoost : 0; List <EncounterSlot> slotdata = new List <EncounterSlot>(); // Get Valid levels IEnumerable <DexLevel> vs = getValidPreEvolutions(pkm); // Get slots where pokemon can exist IEnumerable <EncounterSlot> slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin - df) || ignoreLevel); // Filter for Met Level int lvl = pkm.Met_Level; var encounterSlots = slots.Where(slot => slot.LevelMin - df <= lvl && lvl <= slot.LevelMax + (slot.AllowDexNav ? dn : df) || ignoreLevel).ToList(); // Pressure Slot EncounterSlot slotMax = encounterSlots.OrderByDescending(slot => slot.LevelMax).FirstOrDefault(); if (slotMax != null) { slotMax = new EncounterSlot(slotMax) { Pressure = true, Form = pkm.AltForm } } ; if (!DexNav) { // Filter for Form Specific slotdata.AddRange(WildForms.Contains(pkm.Species) ? encounterSlots.Where(slot => slot.Form == pkm.AltForm) : encounterSlots); if (slotMax != null) { slotdata.Add(slotMax); } return(slotdata); } List <EncounterSlot> eslots = encounterSlots.Where(slot => !WildForms.Contains(pkm.Species) || slot.Form == pkm.AltForm).ToList(); if (slotMax != null) { eslots.Add(slotMax); } foreach (EncounterSlot s in eslots) { bool nav = s.AllowDexNav && (pkm.RelearnMove1 != 0 || pkm.AbilityNumber == 4); EncounterSlot slot = new EncounterSlot(s) { DexNav = nav }; if (slot.LevelMin > lvl) { slot.WhiteFlute = true; } if (slot.LevelMax + 1 <= lvl && lvl <= slot.LevelMax + fluteBoost) { slot.BlackFlute = true; } if (slot.LevelMax != lvl && slot.AllowDexNav) { slot.DexNav = true; } slotdata.Add(slot); } return(slotdata); }
protected override void setDex(PKM pkm) { if (pkm.Species == 0) return; if (pkm.Species > MaxSpeciesID) return; if (Version == GameVersion.Unknown) return; if (BlockOfs.Any(z => z < 0)) return; int bit = pkm.Species - 1; int ofs = bit/8; byte bitval = (byte)(1 << (bit%8)); // Set the Captured Flag Data[BlockOfs[0] + 0x28 + ofs] |= bitval; // Set the Seen Flag Data[BlockOfs[0] + 0x5C + ofs] |= bitval; // Set the two other Seen flags (mirrored) switch (Version) { case GameVersion.RS: Data[BlockOfs[1] + 0x938 + ofs] |= bitval; Data[BlockOfs[4] + 0xC0C + ofs] |= bitval; break; case GameVersion.E: Data[BlockOfs[1] + 0x988 + ofs] |= bitval; Data[BlockOfs[4] + 0xCA4 + ofs] |= bitval; break; case GameVersion.FRLG: Data[BlockOfs[1] + 0x5F8 + ofs] |= bitval; Data[BlockOfs[4] + 0xB98 + ofs] |= bitval; break; } }
private static IEnumerable <EncounterStatic> getStatic(PKM pkm, IEnumerable <EncounterStatic> table, int lvl = -1) { IEnumerable <DexLevel> dl = getValidPreEvolutions(pkm, lvl); return(table.Where(e => dl.Any(d => d.Species == e.Species))); }
// Pokédex public override bool getSeen(PKM pkm) { if (pkm.Species == 0) return false; if (pkm.Species > MaxSpeciesID) return false; if (Version == GameVersion.Unknown) return false; int bit = pkm.Species - 1; int ofs = bit >> 3; byte bitval = (byte)(1 << (bit & 7)); // Get the Seen Flag return (Data[(Japanese ? 0x25B1 : 0x25B6) + ofs] & bitval) != 0; }
private static IEnumerable <int> getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, int Generation, bool MoveReminder) { List <int> r = new List <int>(); var ver = Version; switch (Generation) { case 6: switch (ver) { case GameVersion.Any: // Start at the top, hit every table case GameVersion.X: case GameVersion.Y: case GameVersion.XY: { int index = PersonalTable.XY.getFormeIndex(species, form); PersonalInfo pi = PersonalTable.XY.getFormeEntry(species, form); if (LVL) { r.AddRange(LevelUpXY[index].getMoves(lvl)); } if (moveTutor) { r.AddRange(getTutorMoves(pkm, species, form, specialTutors)); } if (Machine) { r.AddRange(TMHM_XY.Where((t, m) => pi.TMHM[m])); } if (ver == GameVersion.Any) // Fall Through { goto case GameVersion.ORAS; } break; } case GameVersion.AS: case GameVersion.OR: case GameVersion.ORAS: { int index = PersonalTable.AO.getFormeIndex(species, form); PersonalInfo pi = PersonalTable.AO.getFormeEntry(species, form); if (LVL) { r.AddRange(LevelUpAO[index].getMoves(lvl)); } if (moveTutor) { r.AddRange(getTutorMoves(pkm, species, form, specialTutors)); } if (Machine) { r.AddRange(TMHM_AO.Where((t, m) => pi.TMHM[m])); } break; } } break; case 7: switch (ver) { case GameVersion.Any: case GameVersion.SN: case GameVersion.MN: case GameVersion.SM: { int index = PersonalTable.SM.getFormeIndex(species, form); PersonalInfo pi = PersonalTable.SM.getFormeEntry(species, form); if (MoveReminder) { lvl = 100; // Move reminder can teach any level in movepool now! } if (LVL) { r.AddRange(LevelUpSM[index].getMoves(lvl)); } if (moveTutor) { r.AddRange(getTutorMoves(pkm, species, form, specialTutors)); } if (Machine) { r.AddRange(TMHM_SM.Where((t, m) => pi.TMHM[m])); } break; } } break; default: return(r); } return(r); }
public void setPartySlot(PKM pkm, int offset, bool? trade = null, bool? dex = null) { if (pkm == null) return; if (pkm.GetType() != PKMType) throw new InvalidCastException($"PKM Format needs to be {PKMType} when setting to a Gen{Generation} Save File."); if (trade ?? SetUpdatePKM) setPKM(pkm); if (dex ?? SetUpdateDex) setDex(pkm); for (int i = 0; i < 6; i++) if (getPartyOffset(i) == offset) if (PartyCount <= i) PartyCount = i + 1; setData(pkm.EncryptedPartyData, offset); Edited = true; }
internal static EncounterTrade getValidIngameTrade(PKM pkm) { if (!pkm.WasIngameTrade) { return(null); } int lang = pkm.Language; if (lang == 0 || lang == 6) { return(null); } // Get valid pre-evolutions IEnumerable <DexLevel> p = getValidPreEvolutions(pkm); EncounterTrade[] table = null; if (pkm.XY) { table = TradeGift_XY; } if (pkm.AO) { table = TradeGift_AO; } if (pkm.SM) { table = TradeGift_SM; } EncounterTrade z = table?.FirstOrDefault(f => p.Any(r => r.Species == f.Species)); if (z == null) { return(null); } for (int i = 0; i < 6; i++) { if (z.IVs[i] != -1 && z.IVs[i] != pkm.IVs[i]) { return(null); } } if (z.Shiny ^ pkm.IsShiny) // Are PIDs static? { return(null); } if (z.TID != pkm.TID) { return(null); } if (z.SID != pkm.SID) { return(null); } if (z.Location != pkm.Met_Location) { return(null); } if (z.Level != pkm.Met_Level) { return(null); } if (z.Nature != Nature.Random && (int)z.Nature != pkm.Nature) { return(null); } if (z.Gender != pkm.Gender) { return(null); } if (z.OTGender != -1 && z.OTGender != pkm.OT_Gender) { return(null); } // if (z.Ability == 4 ^ pkm.AbilityNumber == 4) // defer to Ability // return null; return(z); }
protected virtual void setPKM(PKM pkm) { }
private static IEnumerable <MysteryGift> getMatchingWC7(PKM pkm, IEnumerable <MysteryGift> DB) { List <MysteryGift> validWC7 = new List <MysteryGift>(); if (DB == null) { return(validWC7); } var vs = getValidPreEvolutions(pkm).ToArray(); foreach (WC7 wc in DB.OfType <WC7>().Where(wc => vs.Any(dl => dl.Species == wc.Species))) { if (pkm.Egg_Location == 0) // Not Egg { if (wc.OTGender != 3) { if (wc.SID != pkm.SID) { continue; } if (wc.TID != pkm.TID) { continue; } if (wc.OTGender != pkm.OT_Gender) { continue; } } if (!string.IsNullOrEmpty(wc.OT) && wc.OT != pkm.OT_Name) { continue; } if (wc.OriginGame != 0 && wc.OriginGame != pkm.Version) { continue; } if (wc.EncryptionConstant != 0 && wc.EncryptionConstant != pkm.EncryptionConstant) { continue; } if (wc.Language != 0 && wc.Language != pkm.Language) { continue; } } if (wc.Form != pkm.AltForm && vs.All(dl => !FormChange.Contains(dl.Species))) { continue; } if (wc.MetLocation != pkm.Met_Location) { continue; } if (wc.EggLocation != pkm.Egg_Location) { continue; } if (wc.MetLevel != pkm.Met_Level) { continue; } if (wc.Ball != pkm.Ball) { continue; } if (wc.OTGender < 3 && wc.OTGender != pkm.OT_Gender) { continue; } if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) { continue; } if (wc.Gender != 3 && wc.Gender != pkm.Gender) { continue; } if (wc.CNT_Cool > pkm.CNT_Cool) { continue; } if (wc.CNT_Beauty > pkm.CNT_Beauty) { continue; } if (wc.CNT_Cute > pkm.CNT_Cute) { continue; } if (wc.CNT_Smart > pkm.CNT_Smart) { continue; } if (wc.CNT_Tough > pkm.CNT_Tough) { continue; } if (wc.CNT_Sheen > pkm.CNT_Sheen) { continue; } if (wc.PIDType == 2 && !pkm.IsShiny) { continue; } if (wc.PIDType == 3 && pkm.IsShiny) { continue; } if ((pkm.SID << 16 | pkm.TID) == 0x79F57B49) // Greninja WC has variant PID and can arrive @ 36 or 37 { if (!pkm.IsShiny) { validWC7.Add(wc); } continue; } if (wc.PIDType == 0 && pkm.PID != wc.PID) { continue; } // Some checks are best performed separately as they are caused by users screwing up valid data. // if (!wc.RelearnMoves.SequenceEqual(pkm.RelearnMoves)) continue; // Defer to relearn legality // if (wc.OT.Length > 0 && pkm.CurrentHandler != 1) continue; // Defer to ownership legality // if (wc.OT.Length > 0 && pkm.OT_Friendship != PKX.getBaseFriendship(pkm.Species)) continue; // Friendship // if (wc.Level > pkm.CurrentLevel) continue; // Defer to level legality // RIBBONS: Defer to ribbon legality validWC7.Add(wc); } return(validWC7); }
public virtual bool getCaught(PKM pkm) { throw new NotImplementedException(); }
internal static bool getHasEvolved(PKM pkm) { return(getValidPreEvolutions(pkm).Count() > 1); }
public virtual void setCaught(PKM pkm, bool caught = true) { }
internal static EncounterStatic getStaticLocation(PKM pkm) { return(getStaticEncounters(pkm).FirstOrDefault()); }
public override bool getCaught(PKM pkm) { if (pkm.Species == 0) return false; if (pkm.Species > MaxSpeciesID) return false; if (Version == GameVersion.Unknown) return false; int bit = pkm.Species - 1; int ofs = bit >> 3; byte bitval = (byte)(1 << (bit & 7)); // Get the Caught Flag return (Data[PokedexCaughtOffset + ofs] & bitval) != 0; }
internal static bool getCanRelearnMove(PKM pkm, int move, GameVersion version = GameVersion.Any) { return(getValidMoves(pkm, version, getValidPreEvolutions(pkm), LVL: true, Relearn: true).Contains(move)); }
public override void setCaught(PKM pkm, bool caught = true) { if (pkm.Species == 0) return; if (pkm.Species > MaxSpeciesID) return; if (Version == GameVersion.Unknown) return; int bit = pkm.Species - 1; int ofs = bit >> 3; byte bitval = (byte)(1 << (bit & 7)); // Set the Captured Flag Data[PokedexCaughtOffset + ofs] &= (byte)~bitval; if (caught) { Data[PokedexCaughtOffset + ofs] |= bitval; if (pkm.Species == 201) // Unown { // Give all Unown caught to prevent a crash on pokedex view for (int i = 1; i <= 26; i++) { Data[PokedexSeenOffset + 0x1F + i] = (byte)i; } } } }
internal static bool getCanLearnMove(PKM pkm, int move, GameVersion version = GameVersion.Any) { return(getValidMoves(pkm, version, getValidPreEvolutions(pkm), Tutor: true, Machine: true).Contains(move)); }