internal 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 "PK1": if (toFormat == 2) { pkm = PKMType == typeof (PK2) ? ((PK1) pk).convertToPK2() : null; break; } if (toFormat == 7) pkm = null; // pkm.convertPK1toPK7(); break; case "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 "CK3": case "XK3": // interconverting C/XD needs to visit main series format // ends up stripping purification/shadow etc stats pkm = pkm.convertToPK3(); goto case "PK3"; // fall through case "PK3": if (toFormat == 3) // Gen3 Inter-trading { switch (PKMType.Name) { case "CK3": pkm = pkm.convertToCK3(); break; case "XK3": pkm = pkm.convertToXK3(); break; case "PK3": pkm = pkm.convertToPK3(); break; // already converted, instantly returns default: throw new FormatException(); } break; } if (fromType.Name != "PK3") pkm = pkm.convertToPK3(); pkm = ((PK3)pkm).convertToPK4(); if (toFormat == 4) { if (PKMType == typeof (BK4)) pkm = ((PK4) pkm).convertToBK4(); break; } pkm = ((PK4)pkm).convertToPK5(); if (toFormat == 5) break; pkm = ((PK5)pkm).convertToPK6(); if (toFormat == 6) break; pkm = new PK7(pkm.Data, pkm.Identifier); break; case "PK4": if (PKMType == typeof(BK4)) { pkm = ((PK4)pkm).convertToBK4(); break; } pkm = ((PK4)pkm).convertToPK5(); if (toFormat == 5) break; pkm = ((PK5)pkm).convertToPK6(); if (toFormat == 6) break; pkm = new PK7(pkm.Data, pkm.Identifier); break; case "BK4": pkm = ((BK4)pkm).convertToPK4(); if (toFormat == 4) break; pkm = ((PK4)pkm).convertToPK5(); if (toFormat == 5) break; pkm = ((PK5)pkm).convertToPK6(); if (toFormat == 6) break; pkm = new PK7(pkm.Data, pkm.Identifier); break; case "PK5": pkm = ((PK5)pkm).convertToPK6(); break; case "PK6": pkm = new PK7(pkm.Data, pkm.Identifier); break; } } comment = pkm == null ? $"Cannot convert a {fromType.Name} to a {PKMType.Name}." : $"Converted from {fromType.Name} to {PKMType.Name}."; return pkm; }
/// <summary> /// Creates an instance of <see cref="PKM"/> from the given data. /// </summary> /// <param name="data">Raw data of the Pokemon file.</param> /// <param name="ident">Optional identifier for the Pokemon. Usually the full path of the source file.</param> /// <returns>An instance of <see cref="PKM"/> created from the given <paramref name="data"/>, or null if <paramref name="data"/> is invalid.</returns> public static PKM getPKMfromBytes(byte[] data, string ident = null) { checkEncrypted(ref data); switch (getPKMDataFormat(data)) { case 1: var PL1 = new PokemonList1(data, PokemonList1.CapacityType.Single, data.Length == PKX.SIZE_1JLIST); if (ident != null) PL1[0].Identifier = ident; return PL1[0]; case 2: var PL2 = new PokemonList2(data, PokemonList2.CapacityType.Single, data.Length == PKX.SIZE_2JLIST); if (ident != null) PL2[0].Identifier = ident; return PL2[0]; case 3: switch (data.Length) { case PKX.SIZE_3CSTORED: return new CK3(data, ident); case PKX.SIZE_3XSTORED: return new XK3(data, ident); default: return new PK3(data, ident); } case 4: var pk = new PK4(data, ident); if (!pk.Valid || pk.Sanity != 0) { var bk = new BK4(data, ident); if (bk.Valid) return bk; } return pk; case 5: return new PK5(data, ident); case 6: PKM pkx = new PK6(data, ident); if (pkx.SM) pkx = new PK7(data, ident); return pkx; default: return null; } }
public override PKM convertToPKM(SaveFile SAV) { if (!IsPokémon) return null; int currentLevel = Level > 0 ? Level : (int)(Util.rnd32()%100 + 1); int metLevel = MetLevel > 0 ? MetLevel : currentLevel; PK7 pk = new PK7 { Species = Species, HeldItem = HeldItem, TID = TID, SID = SID, Met_Level = metLevel, Nature = Nature != 0xFF ? Nature : (int)(Util.rnd32() % 25), Gender = PersonalTable.AO[Species].Gender == 255 ? 2 : (Gender != 3 ? Gender : PersonalTable.AO[Species].RandomGender), AltForm = Form, EncryptionConstant = EncryptionConstant == 0 ? Util.rnd32() : EncryptionConstant, Version = OriginGame == 0 ? SAV.Game : OriginGame, Language = Language == 0 ? SAV.Language : Language, Ball = Ball, Country = SAV.Country, Region = SAV.SubRegion, ConsoleRegion = SAV.ConsoleRegion, Move1 = Move1, Move2 = Move2, Move3 = Move3, Move4 = Move4, RelearnMove1 = RelearnMove1, RelearnMove2 = RelearnMove2, RelearnMove3 = RelearnMove3, RelearnMove4 = RelearnMove4, Met_Location = MetLocation, Egg_Location = EggLocation, CNT_Cool = CNT_Cool, CNT_Beauty = CNT_Beauty, CNT_Cute = CNT_Cute, CNT_Smart = CNT_Smart, CNT_Tough = CNT_Tough, CNT_Sheen = CNT_Sheen, OT_Name = OT.Length > 0 ? OT : SAV.OT, OT_Gender = OTGender != 3 ? OTGender % 2 : SAV.Gender, HT_Name = OT.Length > 0 ? SAV.OT : "", HT_Gender = OT.Length > 0 ? SAV.Gender : 0, CurrentHandler = OT.Length > 0 ? 1 : 0, EXP = PKX.getEXP(currentLevel, Species), // Ribbons RibbonCountry = RibbonCountry, RibbonNational = RibbonNational, RibbonEarth = RibbonEarth, RibbonWorld = RibbonWorld, RibbonClassic = RibbonClassic, RibbonPremier = RibbonPremier, RibbonEvent = RibbonEvent, RibbonBirthday = RibbonBirthday, RibbonSpecial = RibbonSpecial, RibbonSouvenir = RibbonSouvenir, RibbonWishing = RibbonWishing, RibbonChampionBattle = RibbonChampionBattle, RibbonChampionRegional = RibbonChampionRegional, RibbonChampionNational = RibbonChampionNational, RibbonChampionWorld = RibbonChampionWorld, OT_Friendship = PersonalTable.AO[Species].BaseFriendship, OT_Intensity = OT_Intensity, OT_Memory = OT_Memory, OT_TextVar = OT_TextVar, OT_Feeling = OT_Feeling, FatefulEncounter = true, }; pk.Move1_PP = pk.getMovePP(Move1, 0); pk.Move2_PP = pk.getMovePP(Move2, 0); pk.Move3_PP = pk.getMovePP(Move3, 0); pk.Move4_PP = pk.getMovePP(Move4, 0); if (Date.HasValue) { pk.MetDate = Date.Value; } else { // No datetime set, typical for wc6full // Set it to now, instead of zeroing it out. pk.MetDate = DateTime.Now; } if (pk.CurrentHandler == 0) // OT { pk.OT_Memory = 3; pk.OT_TextVar = 9; pk.OT_Intensity = 1; pk.OT_Feeling = Util.rand.Next(0, 9); } else { pk.HT_Memory = 3; pk.HT_TextVar = 9; pk.HT_Intensity = 1; pk.HT_Feeling = Util.rand.Next(0, 9); pk.HT_Friendship = pk.OT_Friendship; } pk.IsNicknamed = IsNicknamed; pk.Nickname = IsNicknamed ? Nickname : PKX.getSpeciesName(Species, pk.Language); // More 'complex' logic to determine final values // Dumb way to generate random IVs. int[] finalIVs = new int[6]; switch (IVs[0]) { case 0xFE: finalIVs[0] = 31; do { // 31 HP IV, 2 other 31s for (int i = 1; i < 6; i++) finalIVs[i] = IVs[i] > 31 ? (int)(Util.rnd32() & 0x1F) : IVs[i]; } while (finalIVs.Count(r => r == 31) < 3); // 31 + 2*31 break; case 0xFD: do { // 2 other 31s for (int i = 0; i < 6; i++) finalIVs[i] = IVs[i] > 31 ? (int)(Util.rnd32() & 0x1F) : IVs[i]; } while (finalIVs.Count(r => r == 31) < 2); // 2*31 break; default: // Random IVs for (int i = 0; i < 6; i++) finalIVs[i] = IVs[i] > 31 ? (int)(Util.rnd32() & 0x1F) : IVs[i]; break; } pk.IVs = finalIVs; int av = 0; switch (AbilityType) { case 00: // 0 - 0 case 01: // 1 - 1 case 02: // 2 - H av = AbilityType; break; case 03: // 0/1 case 04: // 0/1/H av = (int)(Util.rnd32()%(AbilityType - 1)); break; } pk.Ability = PersonalTable.SM.getAbilities(Species, pk.AltForm)[av]; pk.AbilityNumber = 1 << av; switch (PIDType) { case 00: // Specified pk.PID = PID; break; case 01: // Random pk.PID = Util.rnd32(); break; case 02: // Random Shiny pk.PID = Util.rnd32(); pk.PID = (uint)(((TID ^ SID ^ (pk.PID & 0xFFFF)) << 16) + (pk.PID & 0xFFFF)); break; case 03: // Random Nonshiny do { pk.PID = Util.rnd32(); } while ((uint)(((TID ^ SID ^ (pk.PID & 0xFFFF)) << 16) + (pk.PID & 0xFFFF)) < 16); break; } if (IsEgg) { pk.IsEgg = true; pk.EggMetDate = Date; } pk.RefreshChecksum(); return pk; }