diff --git a/PKHeX.Core/Legality/Encounters/Data/Encounters5.cs b/PKHeX.Core/Legality/Encounters/Data/Encounters5.cs index 73bcf49aa..1e5bdc1f7 100644 --- a/PKHeX.Core/Legality/Encounters/Data/Encounters5.cs +++ b/PKHeX.Core/Legality/Encounters/Data/Encounters5.cs @@ -678,6 +678,7 @@ private static void MarkG5Slots(ref EncounterArea[] Areas) internal const int YancyTID = 10303; internal const int CurtisTID = 54118; + internal static readonly EncounterTrade[] TradeGift_B2W2_YancyCurtis = { // player is male @@ -707,8 +708,10 @@ private static void MarkG5Slots(ref EncounterArea[] Areas) new EncounterTrade { Species = 327, Level = 50, Ability = 4, TID = 54118, SID = 00000, OTGender = 0,}, new EncounterTrade { Species = 175, Level = 50, Ability = 4, TID = 54118, SID = 00000, OTGender = 0,}, }; + internal static readonly string[] TradeOT_B2W2_F = {null, "ルリ", "Yancy", "Brenda", "Lilì", "Sabine", null, "Belinda", "루리"}; internal static readonly string[] TradeOT_B2W2_M = {null, "テツ", "Curtis", "Julien", "Dadi", "Markus", null, "Julián", "철권"}; + internal static readonly string[][] TradeBW = { new string[0], // 0 - None @@ -721,6 +724,7 @@ private static void MarkG5Slots(ref EncounterArea[] Areas) Util.GetStringList("tradebw", "es"), // 7 Util.GetStringList("tradebw", "ko"), // 8 }; + internal static readonly string[][] TradeB2W2 = { new string[0], // 0 - None @@ -733,6 +737,7 @@ private static void MarkG5Slots(ref EncounterArea[] Areas) Util.GetStringList("tradeb2w2", "es"), // 7 Util.GetStringList("tradeb2w2", "ko"), // 8 }; + internal static readonly EncounterTrade[] TradeGift_B2W2 = TradeGift_B2W2_Regular.Concat(TradeGift_B2W2_YancyCurtis).ToArray(); #endregion diff --git a/PKHeX.Core/Legality/Encounters/Data/EncountersWC3.cs b/PKHeX.Core/Legality/Encounters/Data/EncountersWC3.cs index a72122e73..effbf0487 100644 --- a/PKHeX.Core/Legality/Encounters/Data/EncountersWC3.cs +++ b/PKHeX.Core/Legality/Encounters/Data/EncountersWC3.cs @@ -21,6 +21,7 @@ internal static class EncountersWC3 new WC3 { Species = 251, Level = 10, TID = 31121, OT_Gender = 1, OT_Name = "AGATE", CardTitle = "Agate Celebi", Method = PIDType.CXD, Shiny = Shiny.Never, Language = (int)LanguageID.English, NotDistributed = true }, new WC3 { Species = 025, Level = 10, TID = 31121, OT_Gender = 0, OT_Name = "COLOS", CardTitle = "Colosseum Pikachu", Method = PIDType.CXD, Shiny = Shiny.Never, Language = (int)LanguageID.English, NotDistributed = true }, }; + private static IEnumerable GetIngameCXDData() { var langs = new[]{LanguageID.Japanese, LanguageID.English, LanguageID.French, LanguageID.Italian, LanguageID.German, LanguageID.Spanish}; @@ -43,6 +44,7 @@ IEnumerable GetIngame(int l) }; } } + internal static readonly MysteryGift[] Encounter_Event3 = Encounter_Event3_Special.Concat(GetIngameCXDData()).ToArray(); internal static readonly MysteryGift[] Encounter_Event3_FRLG = diff --git a/PKHeX.Core/Legality/Encounters/Generator/EncounterLinkGenerator.cs b/PKHeX.Core/Legality/Encounters/Generator/EncounterLinkGenerator.cs index 4cc2e5133..e25c12916 100644 --- a/PKHeX.Core/Legality/Encounters/Generator/EncounterLinkGenerator.cs +++ b/PKHeX.Core/Legality/Encounters/Generator/EncounterLinkGenerator.cs @@ -11,12 +11,14 @@ public static IEnumerable GetPossible(PKM pkm) return Enumerable.Empty(); return Encounters6.LinkGifts6.Where(g => g.Species == pkm.Species); } + public static IEnumerable GetPossible(PKM pkm, IReadOnlyList vs) { if (!pkm.Gen6) return Enumerable.Empty(); return Encounters6.LinkGifts6.Where(g => vs.Any(z => z.Species == g.Species)); } + public static IEnumerable GetValidLinkGifts(PKM pkm) { return GetPossible(pkm).Where(g => g.Level == pkm.Met_Level); diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs index 8a99861a3..3078db5c5 100644 --- a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs +++ b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs @@ -297,7 +297,7 @@ private static void ParseMovesByGeneration(PKM pkm, CheckMoveResult[] res, int g // This pokemon could only have 3 moves from preevolutions that are not the move used to evolved // including special and eggs moves before realearn generations if (Legal.SpeciesEvolutionWithMove.Contains(pkm.Species)) - ParseEvolutionLevelupMove(pkm, res, learnInfo.Source.CurrentMoves, learnInfo.IncenseMoves, info); + ParseEvolutionLevelupMove(pkm, res, learnInfo.Source.CurrentMoves, info); } private static void ParseMovesByGeneration(PKM pkm, IList res, int gen, LegalInfo info, LearnInfo learnInfo) @@ -638,7 +638,7 @@ private static void ParseShedinjaEvolveMoves(PKM pkm, IList res } } - private static void ParseEvolutionLevelupMove(PKM pkm, IList res, int[] moves, List IncenseMovesLearned, LegalInfo info) + private static void ParseEvolutionLevelupMove(PKM pkm, IList res, int[] moves, LegalInfo info) { // Ignore if there is an invalid move or an empty move, this validation is only for 4 non-empty moves that are all valid, but invalid as a 4 combination // Ignore Mr. Mime and Sudowodoo from generations 1 to 3, they cant be evolved from Bonsly or Munchlax @@ -882,6 +882,7 @@ private static int[] GetGenMovesOrderVC(PKM pkm) private static readonly int[] G2 = {2}; private static readonly int[] G12 = {1, 2}; + private static int[] GetGenMovesCheckOrderGB(PKM pkm, int originalGeneration) { if (originalGeneration == 2) diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet1.cs b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet1.cs index ffd3775a2..0e4732ac3 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet1.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet1.cs @@ -42,6 +42,7 @@ private static EvolutionMethod GetMethod(byte[] data, ref int offset) } return null; } + public static List GetArray(byte[] data, int maxSpecies) { var evos = new List(); diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet2.cs b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet2.cs index d547c57cc..09f1a4b32 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet2.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet2.cs @@ -26,6 +26,7 @@ private static EvolutionMethod GetMethod(byte[] data, ref int offset) } return null; } + public static List GetArray(byte[] data, int maxSpecies) { var evos = new List(); diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet3.cs b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet3.cs index e17f728a8..ea21ca0da 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet3.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet3.cs @@ -40,6 +40,7 @@ private static EvolutionMethod GetMethod(byte[] data, int offset) } return null; } + public static List GetArray(byte[] data) { EvolutionSet[] evos = new EvolutionSet[Legal.MaxSpeciesID_3 + 1]; diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet4.cs b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet4.cs index fc9283ab3..23109060f 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet4.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet4.cs @@ -35,6 +35,7 @@ private static EvolutionMethod GetMethod(byte[] data, int offset) evo.Level = 0; return evo; } + public static List GetArray(byte[] data) { var evos = new List(); diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet5.cs b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet5.cs index 749ebba63..f74239235 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet5.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet5.cs @@ -31,6 +31,7 @@ private static EvolutionMethod GetMethod(byte[] data, int offset) evo.Level = 0; return evo; } + public static List GetArray(byte[] data) { var evos = new List(); diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet6.cs b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet6.cs index 45ca21bca..dba261c28 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet6.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet6.cs @@ -10,6 +10,7 @@ public sealed class EvolutionSet6 : EvolutionSet { private static readonly HashSet argEvos = new HashSet {6, 8, 16, 17, 18, 19, 20, 21, 22, 29}; private const int SIZE = 6; + public EvolutionSet6(byte[] data) { PossibleEvolutions = new EvolutionMethod[data.Length / SIZE]; diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet7.cs b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet7.cs index c17696f95..d994b063d 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet7.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionSets/EvolutionSet7.cs @@ -8,6 +8,7 @@ namespace PKHeX.Core public sealed class EvolutionSet7 : EvolutionSet { private const int SIZE = 8; + public EvolutionSet7(byte[] data) { PossibleEvolutions = new EvolutionMethod[data.Length / SIZE]; diff --git a/PKHeX.Core/Legality/RNG/Frame/Frame.cs b/PKHeX.Core/Legality/RNG/Frame/Frame.cs index ba2bd3fc2..51d10728d 100644 --- a/PKHeX.Core/Legality/RNG/Frame/Frame.cs +++ b/PKHeX.Core/Legality/RNG/Frame/Frame.cs @@ -20,6 +20,7 @@ public class Frame /// RNG Call Value for the Level Calc /// public uint RandLevel { get; set; } + /// /// RNG Call Value for the Encounter Slot Calc /// diff --git a/PKHeX.Core/Legality/RNG/Frame/FrameFinder.cs b/PKHeX.Core/Legality/RNG/Frame/FrameFinder.cs index f87f71a08..62b5737c1 100644 --- a/PKHeX.Core/Legality/RNG/Frame/FrameFinder.cs +++ b/PKHeX.Core/Legality/RNG/Frame/FrameFinder.cs @@ -75,6 +75,7 @@ private static IEnumerable RefineFrames3(IEnumerable frames, Frame yield return frame; } } + private static IEnumerable GenerateLeadSpecificFrames3(Frame f, FrameGenerator info) { // Check leads -- none in list if leads are not allowed @@ -177,6 +178,7 @@ private static IEnumerable RefineFrames4(IEnumerable frames, Frame yield return frame; } } + private static IEnumerable GenerateLeadSpecificFrames4(Frame f, FrameGenerator info) { LeadRequired lead; @@ -300,6 +302,7 @@ private static IEnumerable FilterNatureSync(IEnumerable seeds, } } } + private static bool IsValidPokeBlockNature(uint seed, uint nature, out uint natureOrigin) { if (nature % 6 == 0) // neutral diff --git a/PKHeX.Core/Legality/RNG/Frame/FrameGenerator.cs b/PKHeX.Core/Legality/RNG/Frame/FrameGenerator.cs index 3acc647b6..f4e16cf0b 100644 --- a/PKHeX.Core/Legality/RNG/Frame/FrameGenerator.cs +++ b/PKHeX.Core/Legality/RNG/Frame/FrameGenerator.cs @@ -14,6 +14,7 @@ public class FrameGenerator public Frame GetFrame(uint seed, LeadRequired lead) => new Frame(seed, FrameType, RNG, lead); public Frame GetFrame(uint seed, LeadRequired lead, uint esv, uint origin) => GetFrame(seed, lead, esv, esv, origin); + public Frame GetFrame(uint seed, LeadRequired lead, uint esv, uint lvl, uint origin) => new Frame(seed, FrameType, RNG, lead) { RandESV = esv, diff --git a/PKHeX.Core/Legality/RNG/Frame/Pokeblock.cs b/PKHeX.Core/Legality/RNG/Frame/Pokeblock.cs index 8f685ade1..831122eab 100644 --- a/PKHeX.Core/Legality/RNG/Frame/Pokeblock.cs +++ b/PKHeX.Core/Legality/RNG/Frame/Pokeblock.cs @@ -4,6 +4,7 @@ public static class Pokeblock { public static Flavor GetLikedBlockFlavor(uint nature) => (Flavor)(nature/5); public static Flavor GetDislikedBlockFlavor(uint nature) => (Flavor)(nature%5); + public enum Flavor { Spicy, diff --git a/PKHeX.Core/Legality/RNG/Frame/SeedInfo.cs b/PKHeX.Core/Legality/RNG/Frame/SeedInfo.cs index c8976703a..cb6e5313d 100644 --- a/PKHeX.Core/Legality/RNG/Frame/SeedInfo.cs +++ b/PKHeX.Core/Legality/RNG/Frame/SeedInfo.cs @@ -81,6 +81,7 @@ public static IEnumerable GetSeedsUntilUnownForm(PIDIV pidiv, FrameGen yield return new SeedInfo { Seed = s1 }; } } + private static LockInfo VerifyPIDCriteria(uint pid, FrameGenerator info) { // Nature locks are always a given diff --git a/PKHeX.Core/Legality/RNG/Frame/SlotRange.cs b/PKHeX.Core/Legality/RNG/Frame/SlotRange.cs index 266e6a095..d9c5ad8a2 100644 --- a/PKHeX.Core/Legality/RNG/Frame/SlotRange.cs +++ b/PKHeX.Core/Legality/RNG/Frame/SlotRange.cs @@ -56,6 +56,7 @@ private static int HSlot(SlotType type, uint rand) return CalcSlot(ESV, H_Regular); } } + private static int KSlot(SlotType type, uint rand) { var ESV = rand % 100; @@ -84,6 +85,7 @@ private static int KSlot(SlotType type, uint rand) return CalcSlot(ESV, H_Regular); } } + private static int JSlot(SlotType type, uint rand) { uint ESV = rand / 656; @@ -145,6 +147,7 @@ public static int GetLevel(EncounterSlot slot, LeadRequired lead, uint lvlrand) return slot.LevelMin + adjust; } + public static bool GetIsEncounterable(EncounterSlot slot, FrameType frameType, int rand, LeadRequired lead) { if (slot.Type.IsSweetScentType()) @@ -152,6 +155,7 @@ public static bool GetIsEncounterable(EncounterSlot slot, FrameType frameType, i return true; // todo //return GetCanEncounter(slot, frameType, rand, lead); } + private static bool GetCanEncounter(EncounterSlot slot, FrameType frameType, int rand, LeadRequired lead) { int proc = frameType == FrameType.MethodJ ? rand / 656 : rand % 100; diff --git a/PKHeX.Core/Legality/RNG/Locks/LockFinder.cs b/PKHeX.Core/Legality/RNG/Locks/LockFinder.cs index 57ef431b1..f9b88d788 100644 --- a/PKHeX.Core/Legality/RNG/Locks/LockFinder.cs +++ b/PKHeX.Core/Legality/RNG/Locks/LockFinder.cs @@ -69,12 +69,14 @@ private static IEnumerable FindPossibleLockFrames(FrameCache cache, i return GetComplexLockFrame(cache, ctr, l, prior); } + private static IEnumerable GetSingleLockFrame(FrameCache cache, int ctr, NPCLock l) { uint pid = cache[ctr + 1] << 16 | cache[ctr]; if (MatchesLock(l, pid, PKX.GetGenderFromPID(l.Species, pid))) yield return new SeedFrame { FrameID = ctr + 6, PID = pid }; } + private static IEnumerable GetComplexLockFrame(FrameCache cache, int ctr, NPCLock l, NPCLock prior) { // Since the prior(next) lock is generated 7+2*n frames after, the worst case break is 7 frames after the PID. @@ -116,6 +118,7 @@ private static bool VerifyNPC(FrameCache cache, int ctr, IEnumerable PIDs, // Helpers private static bool IsShiny(uint TID, uint SID, uint PID) => (TID ^ SID ^ (PID >> 16) ^ (PID & 0xFFFF)) < 8; private static bool IsShiny(int TID, int SID, uint PID) => (TID ^ SID ^ (PID >> 16) ^ (PID & 0xFFFF)) < 8; + private static bool MatchesLock(NPCLock k, uint PID, int Gender) { if (k.Nature != null && k.Nature != PID % 25) @@ -133,6 +136,7 @@ public static bool IsXDStarterValid(uint seed, int TID, int SID) var TIDf = RNG.XDRNG.Prev(SIDf); return SIDf >> 16 == SID && TIDf >> 16 == TID; } + public static bool IsColoStarterValid(int species, ref uint seed, int TID, int SID, uint pkPID, uint IV1, uint IV2) { // reverse the seed the bare minimum @@ -191,6 +195,7 @@ private static PIDIVGroup GenerateValidColoStarterPID(ref uint uSeed, int TID, i return group; } + private static uint GenerateStarterPID(ref uint uSeed, int TID, int SID) { uint PID; diff --git a/PKHeX.Core/Legality/Tables.cs b/PKHeX.Core/Legality/Tables.cs index b1ee1b603..9f4673d3f 100644 --- a/PKHeX.Core/Legality/Tables.cs +++ b/PKHeX.Core/Legality/Tables.cs @@ -6,22 +6,26 @@ namespace PKHeX.Core public static partial class Legal { public static readonly HashSet Empty = new HashSet(); + public static readonly int[] Items_Ball = { 000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 492, 493, 494, 495, 496, 497, 498, 499, 576, 851 }; + public static readonly int[] Gen4EncounterTypes = { 1, 2, 4, 5, 7, 9, 10, 12, 23, 24 }; public static readonly HashSet LightBall = new HashSet { 25, 26, 172 }; public static readonly int[] Fossils = { 138, 140, 142, 345, 347, 408, 410, 564, 566, 696, 698 }; public static readonly int[] RotomMoves = { 0, 315, 056, 059, 403, 437 }; + public static readonly HashSet WildForms = new HashSet { 422, 423, // Shellos 550, // Basculin 669, 670, 671 // Flabébé }; + public static readonly HashSet SplitBreed = new HashSet { // Incense @@ -35,6 +39,7 @@ public static partial class Legal 315, 407, // Roselia 358, // Chimecho }; + /// /// Species that show their default Species sprite regardless of current /// @@ -47,6 +52,7 @@ public static partial class Legal 773, // Silvally 778, // Mimikyu }; + /// /// Species that show a specific Sprite /// @@ -57,6 +63,7 @@ public static partial class Legal 593, // Jellicent 668, // Pyroar }; + public static readonly HashSet FormChange = new HashSet // Pokémon that can change form and retain it { 386, // Deoxys @@ -79,6 +86,7 @@ public static partial class Legal 800, // Necrozma }; + public static readonly HashSet FormChangeMoves = new HashSet { 386, // Deoxys @@ -86,6 +94,7 @@ public static partial class Legal 492, // Shaymin 720, // Hoopa }; + public static readonly HashSet BreedMaleOnly = new HashSet { 128, // Tauros @@ -239,6 +248,7 @@ public static partial class Legal 746, // Wishiwashi 778, // Mimikyu }; + public static readonly HashSet BattleMegas = new HashSet { // XY @@ -259,6 +269,7 @@ public static partial class Legal // USUM 800, // Ultra Necrozma }; + public static readonly HashSet BattlePrimals = new HashSet { 382, 383 }; public static readonly HashSet Z_Moves = new HashSet @@ -280,6 +291,7 @@ public static partial class Legal 647, 648, 649, 716, 717, 718, 719, 720, 721, 789, 790, 791, 792, 800, 801, 802, 807 }; + public static readonly HashSet SubLegends = new HashSet { 144, 145, 146, 243, 244, 245, 377, 378, 379, 380, 381, @@ -310,6 +322,7 @@ public static partial class Legal 700, // Sylveon (Eevee with Fairy Move) 763, // Tsareena (Steenee with Stomp) }; + internal static readonly int[] FairyMoves = { 186, // Sweet Kiss @@ -394,6 +407,7 @@ public static partial class Legal // Tsareena (Steenee with Stomp) new [] { false, false, false, false, false, false, false, false }, }; + internal static readonly HashSet MixedGenderBreeding = new HashSet { 29, // Nidoran♀ @@ -401,6 +415,7 @@ public static partial class Legal 313, // Volbeat 314, // Illumise }; + internal static readonly HashSet FixedGenderFromBiGender = new HashSet { 290, // Nincada @@ -443,10 +458,12 @@ public static partial class Legal (int) LanguageID.Italian, (int) LanguageID.Korean // check Korean for the VC case, never possible to match string outside of this case }; + public static readonly int[] Languages_3 = { (int) LanguageID.Japanese, (int) LanguageID.English, (int) LanguageID.French, (int) LanguageID.German, (int) LanguageID.Spanish, (int) LanguageID.Italian, }; + public static readonly int[] Languages_46 = Languages_GB; public static readonly int[] Languages_7 = Languages_46.Concat(new[] { (int)LanguageID.ChineseS, (int)LanguageID.ChineseT }).ToArray(); diff --git a/PKHeX.Core/Legality/Tables2.cs b/PKHeX.Core/Legality/Tables2.cs index da4c54fbe..c2501c10c 100644 --- a/PKHeX.Core/Legality/Tables2.cs +++ b/PKHeX.Core/Legality/Tables2.cs @@ -9,6 +9,7 @@ public static partial class Legal internal const int MaxMoveID_2 = 251; internal const int MaxItemID_2 = 255; internal const int MaxAbilityID_2 = 0; + /// /// Generation 2 -> Generation 7 Transfer Location (Johto) /// @@ -17,13 +18,17 @@ public static partial class Legal internal static readonly ushort[] Pouch_Items_GSC = { 3, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 51, 52, 53, 57, 60, 62, 63, 64, 65, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95, 96, 97, 98, 99, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 117, 118, 119, 121, 122, 123, 124, 125, 126, 131, 132, 138, 139, 140, 143, 144, 146, 150, 151, 152, 156, 158, 163, 167, 168, 169, 170, 172, 173, 174, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189 }; + internal static readonly ushort[] Pouch_Ball_GSC = { 1, 2, 4, 5, 157, 159, 160, 161, 164, 165, 166 }; + internal static readonly ushort[] Pouch_Key_GS = { 7, 54, 55, 58, 59, 61, 66, 67, 68, 69, 71, 127, 128, 130, 133, 134, 175, 178 }; + internal static readonly ushort[] Pouch_Key_C = Pouch_Key_GS.Concat(new ushort[]{70, 115, 116, 129}).ToArray(); + internal static readonly ushort[] Pouch_TMHM_GSC = { 191, 192, 193, 194, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249 }; @@ -40,6 +45,7 @@ public static partial class Legal 10, 05, 10, 20, 20, 40, 15, 10, 20, 20, 25, 05, 15, 10, 05, 20, 15, 20, 25, 20, 05, 30, 05, 10, 20, 40, 05, 20, 40, 20, 15, 35, 10, 05, 05, 05, 15, 05, 20, 05, 05, 15, 20, 10, 05, 05, 15, 15, 15, 15, 10, 00, 00, 00, 00 }; + internal static readonly int[] TMHM_GSC = { 223, 029, 174, 205, 046, 092, 192, 249, 244, 237, @@ -50,6 +56,7 @@ public static partial class Legal 015, 019, 057, 070, 148, 250, 127 }; + internal static readonly int[] Tutors_GSC = {53, 85, 58}; // Flamethrower, Thunderbolt & Ice Beam internal static readonly int[] WildPokeBalls2 = { 4 }; @@ -57,11 +64,14 @@ public static partial class Legal { 424,429,430,461,462,463,464,465,466,467,468,469,470,471,472,473,474,700 }; + internal static readonly int[] UnreleasedItems_2 = { // todo }; + internal static readonly bool[] ReleasedHeldItems_2 = Enumerable.Range(0, MaxItemID_2+1).Select(i => HeldItems_GSC.Contains((ushort)i) && !UnreleasedItems_2.Contains(i)).ToArray(); + internal static readonly HashSet TransferSpeciesDefaultAbility_2 = new HashSet { 92, 93, 94, 109, 110, 151, 200, 201, 251, diff --git a/PKHeX.Core/Legality/Tables3.cs b/PKHeX.Core/Legality/Tables3.cs index e7b42cf43..4ace809b9 100644 --- a/PKHeX.Core/Legality/Tables3.cs +++ b/PKHeX.Core/Legality/Tables3.cs @@ -14,6 +14,7 @@ public static partial class Legal internal const int MaxAbilityID_3 = 77; internal const int MaxBallID_3 = 0xC; internal const int MaxGameID_3 = 15; // CXD + /// /// Generation 3 -> Generation 4 Transfer Location (Pal Park) /// @@ -30,9 +31,11 @@ public static partial class Legal internal static readonly ushort[] Pouch_Items_RS = { 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 83, 84, 85, 86, 93, 94, 95, 96, 97, 98, 103, 104, 106, 107, 108, 109, 110, 111, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 254, 255, 256, 257, 258 }; + internal static readonly ushort[] Pouch_Key_RS = { 259, 260, 261, 262, 263, 264, 265, 266, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288 }; + internal static readonly ushort[] Pouch_TM_RS = { 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, }; @@ -40,12 +43,15 @@ public static partial class Legal public static readonly ushort[] Pouch_HM_RS = { 339, 340, 341, 342, 343, 344, 345, 346 }; + internal static readonly ushort[] Pouch_Berries_RS = { 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175 }; + internal static readonly ushort[] Pouch_Ball_RS = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + internal static readonly ushort[] Pouch_Key_FRLG = Pouch_Key_RS.Concat(new ushort[] { 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374 }).ToArray(); internal static readonly ushort[] Pouch_Key_E = Pouch_Key_FRLG.Concat(new ushort[] { 375, 376 }).ToArray(); @@ -69,6 +75,7 @@ public static partial class Legal internal static readonly ushort[] Pouch_Cologne_COLO = {543, 544, 545}; internal static readonly ushort[] Pouch_Items_COLO = Pouch_Items_RS.Concat(new ushort[] {537}).ToArray(); // Time Flute internal static readonly ushort[] HeldItems_COLO = new ushort[1].Concat(Pouch_Items_COLO).Concat(Pouch_Ball_RS).Concat(Pouch_Berries_RS).Concat(Pouch_TM_RS).ToArray(); + internal static readonly ushort[] Pouch_Key_COLO = { 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, @@ -81,6 +88,7 @@ public static partial class Legal internal static readonly ushort[] Pouch_Cologne_XD = {513, 514, 515}; internal static readonly ushort[] Pouch_Items_XD = Pouch_Items_RS.Concat(new ushort[] {511}).ToArray(); // Poké Snack internal static readonly ushort[] HeldItems_XD = new ushort[1].Concat(Pouch_Items_XD).Concat(Pouch_Ball_RS).Concat(Pouch_Berries_RS).Concat(Pouch_TM_RS).ToArray(); + internal static readonly ushort[] Pouch_Key_XD = { 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, @@ -88,6 +96,7 @@ public static partial class Legal 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533 }; + internal static readonly ushort[] Pouch_Disc_XD = { 534, 535, 536, 537, 538, 539, @@ -98,6 +107,7 @@ public static partial class Legal 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593 }; + internal static readonly HashSet WildPokeBalls3 = new HashSet { 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12}; internal static readonly HashSet FutureEvolutionsGen3 = new HashSet @@ -111,11 +121,14 @@ public static partial class Legal // Yanmega Leafeon Glaceon Mamoswine Gliscor Probopass 424, 461, 462, 463, 465, 469, 470, 471, 472, 473, 476 }; + internal static readonly int[] UnreleasedItems_3 = { 005, // Safari Ball }; + internal static readonly bool[] ReleasedHeldItems_3 = Enumerable.Range(0, MaxItemID_3+1).Select(i => HeldItems_RS.Contains((ushort)i) && !UnreleasedItems_3.Contains(i)).ToArray(); + internal static readonly HashSet EReaderBerriesNames_USA = new HashSet { // USA Series 1 @@ -126,6 +139,7 @@ public static partial class Legal "CHILAN", "NUTPEA", }; + internal static readonly HashSet EReaderBerriesNames_JP = new HashSet { // JP Series 1 @@ -144,6 +158,7 @@ public static partial class Legal "ニニク", // NINIKU "トポ" // TOPO }; + internal static readonly int[] TM_3 = { 264, 337, 352, 347, 046, 092, 258, 339, 331, 237, @@ -152,8 +167,10 @@ public static partial class Legal 280, 104, 115, 351, 053, 188, 201, 126, 317, 332, 259, 263, 290, 156, 213, 168, 211, 285, 289, 315, }; + internal static readonly HashSet HM_3 = new HashSet { 15, 19, 57, 70, 148, 249, 127, 291}; internal static readonly int[] TypeTutor3 = {338, 307, 308}; + internal static readonly int[] Tutor_3Mew = { 185, // Feint Attack @@ -163,6 +180,7 @@ public static partial class Legal 272, // Role Play 192, // Zap Cannon }; + internal static readonly int[][] Tutor_Frontier = { new[] {135, 069, 138, 005, 025, 034, 157, 068, 086, 014}, @@ -230,6 +248,7 @@ public static partial class Legal 253, //Ingame egg gift 255 // event/pokemon box }; + internal static readonly HashSet ValidEggMet_FRLG = new HashSet { 146, //Four Island @@ -258,6 +277,7 @@ public static partial class Legal 164, 165, 166, 167, 168, 169, 170, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196 }; + internal static readonly HashSet ValidMet_E = new HashSet(ValidMet_RS.Concat(new[] { 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, diff --git a/PKHeX.Core/Legality/Tables4.cs b/PKHeX.Core/Legality/Tables4.cs index 4e72eb920..53d221ff0 100644 --- a/PKHeX.Core/Legality/Tables4.cs +++ b/PKHeX.Core/Legality/Tables4.cs @@ -13,14 +13,19 @@ public static partial class Legal internal const int MaxAbilityID_4 = 123; internal const int MaxBallID_4 = 0x18; internal const int MaxGameID_4 = 15; // CXD + /// Generation 4 -> Generation 5 Transfer Location (Poké Transporter) public const int Transfer4 = 30001; + /// Generation 4 -> Generation 5 Transfer Location (Crown Celebi - Event not activated in Gen 5) public const int Transfer4_CelebiUnused = 30010; + /// Generation 4 -> Generation 5 Transfer Location (Crown Celebi - Event activated in Gen 5) public const int Transfer4_CelebiUsed = 30011; + /// Generation 4 -> Generation 5 Transfer Location (Crown Beast - Event not activated in Gen 5) public const int Transfer4_CrownUnused = 30012; + /// Generation 4 -> Generation 5 Transfer Location (Crown Beast - Event activated in Gen 5) public const int Transfer4_CrownUsed = 30013; @@ -38,6 +43,7 @@ public static partial class Legal 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, }; + internal static readonly int[] Met_HGSS_Hatch = Met_HGSS_0.Skip(1).ToArray(); // except 0 internal static readonly int[] Met_HGSS_2 = @@ -59,27 +65,35 @@ public static partial class Legal internal static readonly ushort[] Pouch_Items_DP = { 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 135, 136, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327 }; + internal static readonly ushort[] Pouch_Key_DP = { 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464 }; + internal static readonly ushort[] Pouch_TMHM_DP = { 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427 }; + internal static readonly ushort[] Pouch_Mail_DP = { 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148 }; + internal static readonly ushort[] Pouch_Medicine_DP = { 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54 }; + internal static readonly ushort[] Pouch_Berries_DP = { 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212 }; + internal static readonly ushort[] Pouch_Ball_DP = { 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + internal static readonly ushort[] Pouch_Battle_DP = { 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67 }; + internal static readonly ushort[] HeldItems_DP = new ushort[1].Concat(Pouch_Items_DP).Concat(Pouch_Mail_DP).Concat(Pouch_Medicine_DP).Concat(Pouch_Berries_DP).Concat(Pouch_Ball_DP).Concat(Pouch_TMHM_DP.Take(Pouch_TMHM_DP.Length - 8)).ToArray(); #endregion @@ -87,9 +101,11 @@ public static partial class Legal internal static readonly ushort[] Pouch_Items_Pt = { 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 135, 136, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327 }; + internal static readonly ushort[] Pouch_Key_Pt = { 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467 }; + internal static readonly ushort[] Pouch_TMHM_Pt = Pouch_TMHM_DP; internal static readonly ushort[] Pouch_Mail_Pt = Pouch_Mail_DP; internal static readonly ushort[] Pouch_Medicine_Pt = Pouch_Medicine_DP; @@ -102,16 +118,20 @@ public static partial class Legal #region HGSS internal static readonly ushort[] Pouch_Items_HGSS = Pouch_Items_Pt; + internal static readonly ushort[] Pouch_Key_HGSS = { 434, 435, 437, 444, 445, 446, 447, 450, 456, 464, 465, 466, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 501, 502, 503, 504, 532, 533, 534, 535, 536 }; + internal static readonly ushort[] Pouch_TMHM_HGSS = Pouch_TMHM_DP; internal static readonly ushort[] Pouch_Mail_HGSS = Pouch_Mail_DP; internal static readonly ushort[] Pouch_Medicine_HGSS = Pouch_Medicine_DP; internal static readonly ushort[] Pouch_Berries_HGSS = Pouch_Berries_DP; + internal static readonly ushort[] Pouch_Ball_HGSS = { 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 492, 493, 494, 495, 496, 497, 498, 499, 500 }; + internal static readonly ushort[] Pouch_Battle_HGSS = Pouch_Battle_DP; internal static readonly ushort[] HeldItems_HGSS = new ushort[1].Concat(Pouch_Items_HGSS).Concat(Pouch_Mail_HGSS).Concat(Pouch_Medicine_HGSS).Concat(Pouch_Berries_HGSS).Concat(Pouch_Ball_Pt).Concat(Pouch_TMHM_HGSS.Take(Pouch_TMHM_HGSS.Length - 8)).ToArray(); @@ -161,11 +181,13 @@ public static partial class Legal 10, 15, 20, 15, 10, 10, 10, 20, 05, 30, 05, 10, 15, 10, 10, 05, 20, 30, 10, 30, 15, 15, 15, 15, 30, 10, 20, 15, 10, 10, 20, 15, 05, 05, 15, 15, 05, 10, 05, 20, 05, 15, 20, 05, 20, 20, 20, 20, 10, 20, 10, 15, 20, 15, 10, 10, 05, 10, 05, 05, 10, 05, 05, 10, 05, 05, 05, }; + internal static readonly HashSet WildPokeBalls4_DPPt = new HashSet { 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // Cherish ball not usable }; + internal static readonly HashSet WildPokeBalls4_HGSS = new HashSet { 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -178,6 +200,7 @@ public static partial class Legal { 700 }; + internal static readonly HashSet UnreleasedItems_4 = new HashSet { 005, // Safari Ball @@ -186,6 +209,7 @@ public static partial class Legal 499, // Sport Ball 500, // Park Ball }; + internal static readonly bool[] ReleasedHeldItems_4 = Enumerable.Range(0, MaxItemID_4_HGSS+1).Select(i => HeldItems_HGSS.Contains((ushort)i) && !UnreleasedItems_4.Contains(i)).ToArray(); internal static readonly HashSet CrownBeasts = new HashSet { 251, 243, 244, 245 }; @@ -233,10 +257,12 @@ public static partial class Legal 081, 082, 083, 084, 087, 088, 089, 090, 091, 092, 093, 094, 095, 096, 097, 098, 099, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, }; + internal static readonly HashSet ValidMet_Pt = new HashSet(ValidMet_DP.Concat(new[] { 63, 79, 85, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, })); + internal static readonly HashSet ValidMet_HGSS = new HashSet { 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, @@ -246,10 +272,12 @@ public static partial class Legal 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 234, //233: Pokéwalker }; + internal static readonly HashSet GiftEggLocation4 = new HashSet { 2009, 2010, 2011, 2013, 2014 }; + internal static readonly HashSet EggLocations4 = new HashSet { 2000, 2002, 2009, 2010, 2011, 2013, 2014 diff --git a/PKHeX.Core/Legality/Tables5.cs b/PKHeX.Core/Legality/Tables5.cs index 11587e10f..c5fdd81c8 100644 --- a/PKHeX.Core/Legality/Tables5.cs +++ b/PKHeX.Core/Legality/Tables5.cs @@ -51,23 +51,29 @@ public static partial class Legal internal static readonly ushort[] Pouch_Items_BW = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 116, 117, 118, 119, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 492, 493, 494, 495, 496, 497, 498, 499, 500, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 571, 572, 573, 575, 576, 577, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, }; + internal static readonly ushort[] Pouch_Key_BW = { 437, 442, 447, 450, 465, 466, 471, 504, 533, 574, 578, 579, 616, 617, 621, 623, 624, 625, 626, }; + internal static readonly ushort[] Pouch_TMHM_BW = { 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 618, 619, 620, 420, 421, 422, 423, 424, 425 }; + internal static readonly ushort[] Pouch_Medicine_BW = { 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 134, 504, 565, 566, 567, 568, 569, 570, 591 }; + internal static readonly ushort[] Pouch_Berries_BW = { 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212 }; + internal static readonly ushort[] HeldItems_BW = new ushort[1].Concat(Pouch_Items_BW).Concat(Pouch_Medicine_BW).Concat(Pouch_Berries_BW).ToArray(); internal static readonly ushort[] Pouch_Key_B2W2 = { 437, 442, 447, 450, 453, 458, 465, 466, 471, 504, 578, 616, 617, 621, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, }; + internal static readonly int[] TMHM_BW = { 468, 337, 473, 347, 046, 092, 258, 339, 474, 237, @@ -100,6 +106,7 @@ public static partial class Legal 15, 15, 15, 15, 10, 10, 10, 10, 10, 15, 15, 15, 15, 05, 05, 15, 05, 10, 10, 10, 20, 20, 20, 10, 10, 30, 15, 15, 10, 15, 25, 10, 20, 10, 10, 10, 20, 10, 10, 10, 10, 10, 15, 15, 05, 05, 10, 10, 10, 05, 05, 10, 05, 05, 15, 10, 05, 05, 05, }; + internal static readonly HashSet WildPokeBalls5 = new HashSet { 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, @@ -107,12 +114,14 @@ public static partial class Legal // HGSS balls not usable // Dream ball not usable in wild }; + internal static readonly HashSet DreamWorldBalls = new HashSet (WildPokeBalls5.Concat(new[] { 25 })); internal static readonly int[] FutureEvolutionsGen5 = { 700 }; + internal static readonly HashSet UnreleasedItems_5 = new HashSet { 005, // Safari Ball @@ -133,7 +142,9 @@ public static partial class Legal 500, // Park Ball 576, // Dream Ball }; + internal static readonly bool[] ReleasedHeldItems_5 = Enumerable.Range(0, MaxItemID_5_B2W2 + 1).Select(i => HeldItems_BW.Contains((ushort)i) && !UnreleasedItems_5.Contains(i)).ToArray(); + internal static readonly int[][] Tutors_B2W2 = { new[] { 450, 343, 162, 530, 324, 442, 402, 529, 340, 067, 441, 253, 009, 007, 008 }, // Driftveil City @@ -152,6 +163,7 @@ public static partial class Legal 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, }; + internal static readonly HashSet ValidMet_B2W2 = new HashSet { 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016, 017, 018, 019, 020, @@ -163,6 +175,7 @@ public static partial class Legal 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 139, 140, //138 --- 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, }; + internal static readonly HashSet EggLocations5 = new HashSet { 30002, // Link Trade (NPC) diff --git a/PKHeX.Core/Legality/Tables6.cs b/PKHeX.Core/Legality/Tables6.cs index 47d3b5e26..bb2a41fa7 100644 --- a/PKHeX.Core/Legality/Tables6.cs +++ b/PKHeX.Core/Legality/Tables6.cs @@ -229,6 +229,7 @@ public static partial class Legal #endregion internal static readonly int[] EggLocations6 = {60002, 30002}; + internal static readonly HashSet ValidMet_XY = new HashSet { 006, 008, 009, 010, 012, 013, 014, 016, 017, 018, 020, 021, 022, 024, 026, 028, 029, 030, 032, 034, 035, 036, @@ -237,6 +238,7 @@ public static partial class Legal 100, 101, 102, 103, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 135, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168 }; + internal static readonly HashSet ValidMet_AO = new HashSet { 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, @@ -245,6 +247,7 @@ public static partial class Legal 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, 320, 322, 324, 326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 350, 352, 354 }; + internal static readonly HashSet FriendSafari = new HashSet { 190, 206, 216, 506, 294, 352, 531, 572, 113, 132, 133, 235, @@ -266,6 +269,7 @@ public static partial class Legal 082, 303, 597, 205, 227, 375, 600, 437, 530, 707, 098, 224, 400, 515, 008, 130, 195, 419, 061, 184, 657 }; + internal static readonly int[] CosplayPikachuMoves = { 309, 556, 577, 604, 560, 0 }; internal static readonly HashSet WildPokeballs6 = new HashSet {0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; @@ -292,6 +296,7 @@ public static partial class Legal 313, // Via Illumise }; + internal static readonly HashSet Inherit_Safari = new HashSet { 016, 019, 020, 021, 022, 023, 024, 025, 027, 029, 035, 039, 041, @@ -319,6 +324,7 @@ public static partial class Legal 287, // Via Vigoroth }; + internal static readonly HashSet Inherit_Dream = new HashSet { 010, 013, 016, 019, 021, 023, 027, 029, 037, 041, 043, 046, 048, 050, 052, 054, 056, 058, 060, 063, 066, 069, @@ -348,6 +354,7 @@ public static partial class Legal // Via Incense Breeding 298, 360, 406, 433, 438, 439, 440, 446, 458, }; + internal static readonly HashSet Ban_DreamHidden = new HashSet { 311, // Plusle @@ -359,6 +366,7 @@ public static partial class Legal 356, // Dusclops 477, // Dusknoir }; + internal static readonly HashSet Ban_Gen3Ball = new HashSet { 252, 255, 258, //1 - Treeko, Torchic, Mudkip @@ -372,6 +380,7 @@ public static partial class Legal 497, 500, 503, //3 566, 567, 696, 697, 698, 699 // Fossil Only obtain }; + internal static readonly HashSet Ban_Gen3BallHidden = new HashSet { // can have HA and can be in gen 3 ball as eggs but can not at same time. @@ -387,6 +396,7 @@ public static partial class Legal 710 + (3 << 11), //Pumpkaboo-Super 711 + (3 << 11), //Gourgeist-Super }; + internal static readonly HashSet Ban_Gen4Ball_6 = new HashSet { 152, 155, 158, //1 - Chikorita, Cyndaquil, Totodile @@ -428,6 +438,7 @@ public static partial class Legal 05, 10, 05, 05, 15, 10, 05, 05, 05, 10, 10, 10, 10, 20, 25, 10, 20, 30, 25, 20, 20, 15, 20, 15, 20, 20, 10, 10, 10, 10, 10, 20, 10, 30, 15, 10, 10, 10, 20, 20, 05, 05, 05, 20, 10, 10, 20, 15, 20, 20, 10, 20, 30, 10, 10, 40, 40, 30, 20, 40, 20, 20, 10, 10, 10, 10, 05, 10, 10, 05, 05, }; + internal static readonly int[] UnreleasedItems_6 = { 005, // Safari Ball @@ -466,6 +477,7 @@ public static partial class Legal 590, // Relic Crown 715, // Fairy Gem }; + internal static readonly bool[] ReleasedHeldItems_6 = Enumerable.Range(0, MaxItemID_6_AO+1).Select(i => HeldItem_AO.Contains((ushort)i) && !UnreleasedItems_6.Contains(i)).ToArray(); } } diff --git a/PKHeX.Core/Legality/Tables7.cs b/PKHeX.Core/Legality/Tables7.cs index b3118066d..0120ec3d2 100644 --- a/PKHeX.Core/Legality/Tables7.cs +++ b/PKHeX.Core/Legality/Tables7.cs @@ -64,6 +64,7 @@ public static partial class Legal 477, 502, 432, 710, 707, 675, 673 }; + internal static readonly ushort[] Pouch_Regular_SM = // 00 { 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 082, 083, 084, 085, 086, 087, @@ -82,14 +83,17 @@ public static partial class Legal 761, 762, 763, 764, 767, 768, 769, 770, 795, 796, 844, 849, 853, 854, 855, 856, 879, 880, 881, 882, 883, 884, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, }; + internal static readonly ushort[] Pouch_Ball_SM = { // 08 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 492, 493, 494, 495, 496, 497, 498, 576, 851 }; + internal static readonly ushort[] Pouch_Battle_SM = { // 16 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 577, 846, }; + internal static readonly ushort[] Pouch_Items_SM = Pouch_Regular_SM.Concat(Pouch_Ball_SM).Concat(Pouch_Battle_SM).ToArray(); internal static readonly ushort[] Pouch_Key_SM = { @@ -97,13 +101,16 @@ public static partial class Legal 705, 706, 765, 773, 797, 841, 842, 843, 845, 847, 850, 857, 858, 860, }; + internal static readonly ushort[] Pouch_Key_USUM = Pouch_Key_SM.Concat(new ushort[] { 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 440, }).ToArray(); + public static readonly ushort[] Pouch_Roto_USUM = { 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959 }; + internal static readonly ushort[] Pouch_TMHM_SM = { // 02 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, @@ -112,30 +119,38 @@ public static partial class Legal 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 618, 619, 620, 690, 691, 692, 693, 694, }; + internal static readonly ushort[] Pouch_Medicine_SM = { // 32 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 65, 66, 67, 134, 504, 565, 566, 567, 568, 569, 570, 591, 645, 708, 709, 852, }; + internal static readonly ushort[] Pouch_Berries_SM = { 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 686, 687, 688, }; + internal static readonly ushort[] Pouch_ZCrystal_SM = { // Bead 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, }; + internal static readonly ushort[] Pouch_ZCrystalHeld_SM = { // Piece 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 798, 799, 800, 801, 802, 803, 804, 805, 806, 836 }; + internal static readonly ushort[] Pouch_ZCrystal_USUM = Pouch_ZCrystal_SM.Concat(new ushort[] { // Bead 927, 928, 929, 930, 931, 932 }).ToArray(); + internal static readonly ushort[] Pouch_ZCrystalHeld_USUM = Pouch_ZCrystalHeld_SM.Concat(new ushort[] { // Piece 921, 922, 923, 924, 925, 926 }).ToArray(); + public static readonly Dictionary ZCrystalDictionary = Pouch_ZCrystal_USUM .Zip(Pouch_ZCrystalHeld_USUM, (k, v) => new { Key = (int)k, Value = (int)v }) .ToDictionary(x => x.Key, x => x.Value); + internal static readonly ushort[] HeldItems_SM = new ushort[1].Concat(Pouch_Items_SM).Concat(Pouch_Berries_SM).Concat(Pouch_Medicine_SM).Concat(Pouch_ZCrystalHeld_SM).ToArray(); internal static readonly ushort[] HeldItems_USUM = new ushort[1].Concat(Pouch_Items_SM).Concat(Pouch_Berries_SM).Concat(Pouch_Medicine_SM).Concat(Pouch_ZCrystalHeld_USUM).Concat(Pouch_Roto_USUM).ToArray(); @@ -144,6 +159,7 @@ public static partial class Legal 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, // Johto Balls 0x1A, // Beast }; + internal static readonly HashSet AlolanOriginForms = new HashSet { 019, // Rattata @@ -162,12 +178,14 @@ public static partial class Legal 088, // Grimer 089, // Muk }; + internal static readonly HashSet AlolanVariantEvolutions12 = new HashSet { 026, // Raichu 103, // Exeggutor 105, // Marowak }; + internal static readonly HashSet EvolveToAlolanForms = new HashSet(AlolanVariantEvolutions12.Concat(AlolanOriginForms)); public static readonly HashSet PastGenAlolanNatives = new HashSet @@ -216,6 +234,7 @@ public static partial class Legal 100, 101 // Voltorb & Electrode }; + public static readonly HashSet PastGenAlolanNativesUncapturable = new HashSet { 142, // Aerodacyl @@ -281,6 +300,7 @@ public static partial class Legal 656, 657, 658, // Greninja 653, 654, 655, // Delphox }; + internal static readonly HashSet Inherit_Apricorn6 = new HashSet { 010, 013, 016, 019, 021, 023, 025, 027, 029, 035, 037, 039, 041, @@ -308,6 +328,7 @@ public static partial class Legal 173, // Via Clefairy 174, // Via Jigglypuff }; + internal static readonly HashSet AlolanCaptureOffspring = new HashSet { 010, 019, 021, 025, 027, 035, 037, 039, 041, 046, @@ -342,7 +363,9 @@ public static partial class Legal // Static Encounters 100, }; + internal static readonly HashSet AlolanCaptureNoHeavyBall = new HashSet { 374, 785, 786, 787, 788}; // Beldum & Tapus + internal static readonly HashSet Inherit_ApricornMale7 = new HashSet { 100, // Voltorb @@ -352,7 +375,9 @@ public static partial class Legal // Others are capturable in the Alola region // Magnemite, Staryu, Tauros }; + internal static readonly HashSet Inherit_Apricorn7 = new HashSet (Inherit_Apricorn6.Concat(Inherit_ApricornMale7).Concat(PastGenAlolanScans).Concat(AlolanCaptureOffspring).Distinct()); + internal static readonly HashSet Inherit_SafariMale = new HashSet { 128, // Tauros @@ -364,6 +389,7 @@ public static partial class Legal 374, // Beldum 436, // Bronzor }; + internal static readonly HashSet Inherit_DreamMale = new HashSet { // Starting with Gen7, Males pass Ball via breeding with Ditto. @@ -392,16 +418,19 @@ public static partial class Legal 599, // Klink 622, // Golett }; + internal static readonly HashSet Ban_Gen3Ball_7 = new HashSet { 489, // Phione 566, 567, 696, 697, 698, 699 // Fossil Only obtain }; + internal static readonly HashSet Ban_Gen4Ball_7 = new HashSet { 489, // Phione 566, 567, 696, 697, 698, 699 // Fossil Only obtain }; + internal static readonly HashSet Ban_SafariBallHidden_7 = new HashSet { 029, 030, 031, 032, 033, 034, // Nidos @@ -442,6 +471,7 @@ public static partial class Legal 105, // Marowak (Normal, Alolan, Totem) 778, // Mimikyu (Normal, Busted, Totem, Totem_Busted) }; + internal static readonly HashSet Totem_SM = new HashSet { 020, // Raticate @@ -453,6 +483,7 @@ public static partial class Legal 778, // Mimikyu 784, // Kommo-o }; + internal static readonly HashSet Totem_USUM = new HashSet { 020, // Raticate @@ -470,6 +501,7 @@ public static partial class Legal }; internal static readonly int[] EggLocations7 = {60002, 30002}; + internal static readonly HashSet ValidMet_SM = new HashSet { 006, 008, 010, 012, 014, 016, 018, 020, 022, 024, 026, 028, 030, 032, 034, 036, 038, 040, 042, 044, 046, 048, @@ -479,6 +511,7 @@ public static partial class Legal 30016 // Poké Pelago }; + internal static readonly HashSet ValidMet_USUM = new HashSet(ValidMet_SM) { // 194, 195, 196, 197, // Unobtainable new Locations diff --git a/PKHeX.Core/PKM/BK4.cs b/PKHeX.Core/PKM/BK4.cs index aca2a8fd5..623bd2530 100644 --- a/PKHeX.Core/PKM/BK4.cs +++ b/PKHeX.Core/PKM/BK4.cs @@ -10,6 +10,7 @@ public sealed class BK4 : _K4 { 0x42, 0x43, 0x5E, 0x63, 0x64, 0x65, 0x66, 0x67, 0x87 }; + public override int SIZE_PARTY => PKX.SIZE_4STORED; public override int SIZE_STORED => PKX.SIZE_4STORED; public override int Format => 4; @@ -17,7 +18,7 @@ public sealed class BK4 : _K4 public override byte[] DecryptedBoxData => EncryptedBoxData; - public override bool Valid => ChecksumValid || Sanity == 0 && Species <= MaxSpeciesID; + public override bool Valid => ChecksumValid || (Sanity == 0 && Species <= MaxSpeciesID); public BK4(byte[] decryptedData = null, string ident = null) { @@ -31,12 +32,14 @@ public BK4(byte[] decryptedData = null, string ident = null) Sanity = 0x4000; SetStats(GetStats(PersonalInfo)); } + public BK4() { Data = new byte[SIZE_PARTY]; Sanity = 0x4000; SetStats(GetStats(PersonalInfo)); } + public override PKM Clone() => new BK4((byte[])Encrypt().Clone(), Identifier); public string GetString(int Offset, int Count) => StringConverter.GetBEString4(Data, Offset, Count); @@ -52,11 +55,13 @@ public BK4() public override int HeldItem { get => BigEndian.ToUInt16(Data, 0x0A); set => BigEndian.GetBytes((ushort)value).CopyTo(Data, 0x0A); } public override int SID { get => BigEndian.ToUInt16(Data, 0x0C); set => BigEndian.GetBytes((ushort)value).CopyTo(Data, 0x0C); } public override int TID { get => BigEndian.ToUInt16(Data, 0x0E); set => BigEndian.GetBytes((ushort)value).CopyTo(Data, 0x0E); } + public override uint EXP { get => BigEndian.ToUInt32(Data, 0x10); set => BigEndian.GetBytes(value).CopyTo(Data, 0x10); } + public override int OT_Friendship { get => Data[0x14]; set => Data[0x14] = (byte)value; } public override int Ability { get => Data[0x15]; set => Data[0x15] = (byte)value; } public override int MarkValue { get => Data[0x16]; protected set => Data[0x16] = (byte)value; } @@ -78,38 +83,38 @@ public override uint EXP private byte RIB2 { get => Data[0x25]; set => Data[0x25] = value; } // Unova 1 private byte RIB1 { get => Data[0x26]; set => Data[0x26] = value; } // Sinnoh 2 private byte RIB0 { get => Data[0x27]; set => Data[0x27] = value; } // Sinnoh 1 - public override bool RibbonChampionSinnoh { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)(RIB0 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonAbility { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)(RIB0 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonAbilityGreat { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)(RIB0 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonAbilityDouble { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)(RIB0 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonAbilityMulti { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)(RIB0 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonAbilityPair { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)(RIB0 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonAbilityWorld { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)(RIB0 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonAlert { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)(RIB0 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonShock { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)(RIB1 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonDowncast { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)(RIB1 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonCareless { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)(RIB1 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonRelax { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)(RIB1 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonSnooze { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)(RIB1 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonSmile { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)(RIB1 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonGorgeous { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)(RIB1 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonRoyal { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)(RIB1 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)(RIB2 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonFootprint { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)(RIB2 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonRecord { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)(RIB2 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonEvent { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)(RIB2 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonLegend { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)(RIB2 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonChampionWorld { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)(RIB2 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonBirthday { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)(RIB2 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonSpecial { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)(RIB2 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonSouvenir { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)(RIB3 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonWishing { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)(RIB3 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)(RIB3 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)(RIB3 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RIB3_4 { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)(RIB3 & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public override bool RIB3_5 { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)(RIB3 & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public override bool RIB3_6 { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)(RIB3 & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public override bool RIB3_7 { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)(RIB3 & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused + public override bool RibbonChampionSinnoh { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)((RIB0 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonAbility { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)((RIB0 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonAbilityGreat { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)((RIB0 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonAbilityDouble { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)((RIB0 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonAbilityMulti { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)((RIB0 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonAbilityPair { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)((RIB0 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonAbilityWorld { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)((RIB0 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonAlert { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)((RIB0 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonShock { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)((RIB1 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonDowncast { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)((RIB1 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonCareless { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)((RIB1 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonRelax { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)((RIB1 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonSnooze { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)((RIB1 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonSmile { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)((RIB1 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonGorgeous { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)((RIB1 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonRoyal { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)((RIB1 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)((RIB2 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonFootprint { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)((RIB2 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonRecord { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)((RIB2 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonEvent { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)((RIB2 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonLegend { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)((RIB2 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonChampionWorld { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)((RIB2 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonBirthday { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)((RIB2 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonSpecial { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)((RIB2 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonSouvenir { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)((RIB3 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonWishing { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)((RIB3 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)((RIB3 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)((RIB3 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RIB3_4 { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)((RIB3 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public override bool RIB3_5 { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)((RIB3 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public override bool RIB3_6 { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)((RIB3 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public override bool RIB3_7 { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)((RIB3 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused #endregion #region Block B @@ -139,42 +144,42 @@ public override uint EXP private byte RIB6 { get => Data[0x3D]; set => Data[0x3D] = value; } // Hoenn 2a private byte RIB5 { get => Data[0x3E]; set => Data[0x3E] = value; } // Hoenn 1b private byte RIB4 { get => Data[0x3F]; set => Data[0x3F] = value; } // Hoenn 1a - public override bool RibbonG3Cool { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)(RIB4 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG3CoolSuper { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)(RIB4 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG3CoolHyper { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)(RIB4 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG3CoolMaster { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)(RIB4 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonG3Beauty { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)(RIB4 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonG3BeautySuper { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)(RIB4 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonG3BeautyHyper { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)(RIB4 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonG3BeautyMaster { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)(RIB4 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonG3Cute { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)(RIB5 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG3CuteSuper { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)(RIB5 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG3CuteHyper { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)(RIB5 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG3CuteMaster { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)(RIB5 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonG3Smart { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)(RIB5 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonG3SmartSuper { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)(RIB5 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonG3SmartHyper { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)(RIB5 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonG3SmartMaster { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)(RIB5 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonG3Tough { get => (RIB6 & (1 << 0)) == 1 << 0; set => RIB6 = (byte)(RIB6 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG3ToughSuper { get => (RIB6 & (1 << 1)) == 1 << 1; set => RIB6 = (byte)(RIB6 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG3ToughHyper { get => (RIB6 & (1 << 2)) == 1 << 2; set => RIB6 = (byte)(RIB6 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG3ToughMaster { get => (RIB6 & (1 << 3)) == 1 << 3; set => RIB6 = (byte)(RIB6 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonChampionG3Hoenn { get => (RIB6 & (1 << 4)) == 1 << 4; set => RIB6 = (byte)(RIB6 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonWinning { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)(RIB6 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonVictory { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)(RIB6 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonArtist { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)(RIB6 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonEffort { get => (RIB7 & (1 << 0)) == 1 << 0; set => RIB7 = (byte)(RIB7 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonChampionBattle { get => (RIB7 & (1 << 1)) == 1 << 1; set => RIB7 = (byte)(RIB7 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonChampionRegional { get => (RIB7 & (1 << 2)) == 1 << 2; set => RIB7 = (byte)(RIB7 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonChampionNational { get => (RIB7 & (1 << 3)) == 1 << 3; set => RIB7 = (byte)(RIB7 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonCountry { get => (RIB7 & (1 << 4)) == 1 << 4; set => RIB7 = (byte)(RIB7 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonNational { get => (RIB7 & (1 << 5)) == 1 << 5; set => RIB7 = (byte)(RIB7 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonEarth { get => (RIB7 & (1 << 6)) == 1 << 6; set => RIB7 = (byte)(RIB7 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonWorld { get => (RIB7 & (1 << 7)) == 1 << 7; set => RIB7 = (byte)(RIB7 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public override bool RibbonG3Cool { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)((RIB4 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG3CoolSuper { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)((RIB4 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG3CoolHyper { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)((RIB4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG3CoolMaster { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)((RIB4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonG3Beauty { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)((RIB4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonG3BeautySuper { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonG3BeautyHyper { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonG3BeautyMaster { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)((RIB4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonG3Cute { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)((RIB5 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG3CuteSuper { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)((RIB5 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG3CuteHyper { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)((RIB5 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG3CuteMaster { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)((RIB5 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonG3Smart { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)((RIB5 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonG3SmartSuper { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)((RIB5 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonG3SmartHyper { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)((RIB5 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonG3SmartMaster { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)((RIB5 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonG3Tough { get => (RIB6 & (1 << 0)) == 1 << 0; set => RIB6 = (byte)((RIB6 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG3ToughSuper { get => (RIB6 & (1 << 1)) == 1 << 1; set => RIB6 = (byte)((RIB6 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG3ToughHyper { get => (RIB6 & (1 << 2)) == 1 << 2; set => RIB6 = (byte)((RIB6 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG3ToughMaster { get => (RIB6 & (1 << 3)) == 1 << 3; set => RIB6 = (byte)((RIB6 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonChampionG3Hoenn { get => (RIB6 & (1 << 4)) == 1 << 4; set => RIB6 = (byte)((RIB6 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonWinning { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)((RIB6 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonVictory { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)((RIB6 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonArtist { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)((RIB6 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonEffort { get => (RIB7 & (1 << 0)) == 1 << 0; set => RIB7 = (byte)((RIB7 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonChampionBattle { get => (RIB7 & (1 << 1)) == 1 << 1; set => RIB7 = (byte)((RIB7 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonChampionRegional { get => (RIB7 & (1 << 2)) == 1 << 2; set => RIB7 = (byte)((RIB7 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonChampionNational { get => (RIB7 & (1 << 3)) == 1 << 3; set => RIB7 = (byte)((RIB7 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonCountry { get => (RIB7 & (1 << 4)) == 1 << 4; set => RIB7 = (byte)((RIB7 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonNational { get => (RIB7 & (1 << 5)) == 1 << 5; set => RIB7 = (byte)((RIB7 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonEarth { get => (RIB7 & (1 << 6)) == 1 << 6; set => RIB7 = (byte)((RIB7 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonWorld { get => (RIB7 & (1 << 7)) == 1 << 7; set => RIB7 = (byte)((RIB7 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } - public override bool FatefulEncounter { get => (Data[0x40] & 0x80) == 0x80; set => Data[0x40] = (byte)(Data[0x40] & ~0x80 | (value ? 0x80 : 0)); } - public override int Gender { get => (Data[0x40] >> 5) & 0x3; set => Data[0x40] = (byte)(Data[0x40] & ~0x60 | ((value & 3) << 5)); } - public override int AltForm { get => Data[0x40] & 0x1F; set => Data[0x40] = (byte)(Data[0x40] & ~0x1F | (value & 0x1F)); } + public override bool FatefulEncounter { get => (Data[0x40] & 0x80) == 0x80; set => Data[0x40] = (byte)((Data[0x40] & ~0x80) | (value ? 0x80 : 0)); } + public override int Gender { get => (Data[0x40] >> 5) & 0x3; set => Data[0x40] = (byte)((Data[0x40] & ~0x60) | ((value & 3) << 5)); } + public override int AltForm { get => Data[0x40] & 0x1F; set => Data[0x40] = (byte)((Data[0x40] & ~0x1F) | (value & 0x1F)); } public override int ShinyLeaf { get => Data[0x41]; set => Data[0x41] = (byte)value; } // 0x43-0x47 Unused #endregion @@ -187,38 +192,38 @@ public override uint EXP private byte RIB9 { get => Data[0x61]; set => Data[0x61] = value; } // Sinnoh 4 private byte RIBA { get => Data[0x62]; set => Data[0x62] = value; } // Sinnoh 5 private byte RIBB { get => Data[0x63]; set => Data[0x63] = value; } // Sinnoh 6 - public override bool RibbonG4Cool { get => (RIB8 & (1 << 0)) == 1 << 0; set => RIB8 = (byte)(RIB8 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG4CoolGreat { get => (RIB8 & (1 << 1)) == 1 << 1; set => RIB8 = (byte)(RIB8 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG4CoolUltra { get => (RIB8 & (1 << 2)) == 1 << 2; set => RIB8 = (byte)(RIB8 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG4CoolMaster { get => (RIB8 & (1 << 3)) == 1 << 3; set => RIB8 = (byte)(RIB8 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonG4Beauty { get => (RIB8 & (1 << 4)) == 1 << 4; set => RIB8 = (byte)(RIB8 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonG4BeautyGreat { get => (RIB8 & (1 << 5)) == 1 << 5; set => RIB8 = (byte)(RIB8 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonG4BeautyUltra { get => (RIB8 & (1 << 6)) == 1 << 6; set => RIB8 = (byte)(RIB8 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonG4BeautyMaster { get => (RIB8 & (1 << 7)) == 1 << 7; set => RIB8 = (byte)(RIB8 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonG4Cute { get => (RIB9 & (1 << 0)) == 1 << 0; set => RIB9 = (byte)(RIB9 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG4CuteGreat { get => (RIB9 & (1 << 1)) == 1 << 1; set => RIB9 = (byte)(RIB9 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG4CuteUltra { get => (RIB9 & (1 << 2)) == 1 << 2; set => RIB9 = (byte)(RIB9 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG4CuteMaster { get => (RIB9 & (1 << 3)) == 1 << 3; set => RIB9 = (byte)(RIB9 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonG4Smart { get => (RIB9 & (1 << 4)) == 1 << 4; set => RIB9 = (byte)(RIB9 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonG4SmartGreat { get => (RIB9 & (1 << 5)) == 1 << 5; set => RIB9 = (byte)(RIB9 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonG4SmartUltra { get => (RIB9 & (1 << 6)) == 1 << 6; set => RIB9 = (byte)(RIB9 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonG4SmartMaster { get => (RIB9 & (1 << 7)) == 1 << 7; set => RIB9 = (byte)(RIB9 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonG4Tough { get => (RIBA & (1 << 0)) == 1 << 0; set => RIBA = (byte)(RIBA & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG4ToughGreat { get => (RIBA & (1 << 1)) == 1 << 1; set => RIBA = (byte)(RIBA & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG4ToughUltra { get => (RIBA & (1 << 2)) == 1 << 2; set => RIBA = (byte)(RIBA & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG4ToughMaster { get => (RIBA & (1 << 3)) == 1 << 3; set => RIBA = (byte)(RIBA & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RIBA_4 { get => (RIBA & (1 << 4)) == 1 << 4; set => RIBA = (byte)(RIBA & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public override bool RIBA_5 { get => (RIBA & (1 << 5)) == 1 << 5; set => RIBA = (byte)(RIBA & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public override bool RIBA_6 { get => (RIBA & (1 << 6)) == 1 << 6; set => RIBA = (byte)(RIBA & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public override bool RIBA_7 { get => (RIBA & (1 << 7)) == 1 << 7; set => RIBA = (byte)(RIBA & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused - public override bool RIBB_0 { get => (RIBB & (1 << 0)) == 1 << 0; set => RIBB = (byte)(RIBB & ~(1 << 0) | (value ? 1 << 0 : 0)); } // Unused - public override bool RIBB_1 { get => (RIBB & (1 << 1)) == 1 << 1; set => RIBB = (byte)(RIBB & ~(1 << 1) | (value ? 1 << 1 : 0)); } // Unused - public override bool RIBB_2 { get => (RIBB & (1 << 2)) == 1 << 2; set => RIBB = (byte)(RIBB & ~(1 << 2) | (value ? 1 << 2 : 0)); } // Unused - public override bool RIBB_3 { get => (RIBB & (1 << 3)) == 1 << 3; set => RIBB = (byte)(RIBB & ~(1 << 3) | (value ? 1 << 3 : 0)); } // Unused - public override bool RIBB_4 { get => (RIBB & (1 << 4)) == 1 << 4; set => RIBB = (byte)(RIBB & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public override bool RIBB_5 { get => (RIBB & (1 << 5)) == 1 << 5; set => RIBB = (byte)(RIBB & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public override bool RIBB_6 { get => (RIBB & (1 << 6)) == 1 << 6; set => RIBB = (byte)(RIBB & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public override bool RIBB_7 { get => (RIBB & (1 << 7)) == 1 << 7; set => RIBB = (byte)(RIBB & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused + public override bool RibbonG4Cool { get => (RIB8 & (1 << 0)) == 1 << 0; set => RIB8 = (byte)((RIB8 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG4CoolGreat { get => (RIB8 & (1 << 1)) == 1 << 1; set => RIB8 = (byte)((RIB8 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG4CoolUltra { get => (RIB8 & (1 << 2)) == 1 << 2; set => RIB8 = (byte)((RIB8 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG4CoolMaster { get => (RIB8 & (1 << 3)) == 1 << 3; set => RIB8 = (byte)((RIB8 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonG4Beauty { get => (RIB8 & (1 << 4)) == 1 << 4; set => RIB8 = (byte)((RIB8 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonG4BeautyGreat { get => (RIB8 & (1 << 5)) == 1 << 5; set => RIB8 = (byte)((RIB8 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonG4BeautyUltra { get => (RIB8 & (1 << 6)) == 1 << 6; set => RIB8 = (byte)((RIB8 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonG4BeautyMaster { get => (RIB8 & (1 << 7)) == 1 << 7; set => RIB8 = (byte)((RIB8 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonG4Cute { get => (RIB9 & (1 << 0)) == 1 << 0; set => RIB9 = (byte)((RIB9 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG4CuteGreat { get => (RIB9 & (1 << 1)) == 1 << 1; set => RIB9 = (byte)((RIB9 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG4CuteUltra { get => (RIB9 & (1 << 2)) == 1 << 2; set => RIB9 = (byte)((RIB9 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG4CuteMaster { get => (RIB9 & (1 << 3)) == 1 << 3; set => RIB9 = (byte)((RIB9 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonG4Smart { get => (RIB9 & (1 << 4)) == 1 << 4; set => RIB9 = (byte)((RIB9 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonG4SmartGreat { get => (RIB9 & (1 << 5)) == 1 << 5; set => RIB9 = (byte)((RIB9 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonG4SmartUltra { get => (RIB9 & (1 << 6)) == 1 << 6; set => RIB9 = (byte)((RIB9 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonG4SmartMaster { get => (RIB9 & (1 << 7)) == 1 << 7; set => RIB9 = (byte)((RIB9 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonG4Tough { get => (RIBA & (1 << 0)) == 1 << 0; set => RIBA = (byte)((RIBA & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG4ToughGreat { get => (RIBA & (1 << 1)) == 1 << 1; set => RIBA = (byte)((RIBA & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG4ToughUltra { get => (RIBA & (1 << 2)) == 1 << 2; set => RIBA = (byte)((RIBA & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG4ToughMaster { get => (RIBA & (1 << 3)) == 1 << 3; set => RIBA = (byte)((RIBA & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RIBA_4 { get => (RIBA & (1 << 4)) == 1 << 4; set => RIBA = (byte)((RIBA & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public override bool RIBA_5 { get => (RIBA & (1 << 5)) == 1 << 5; set => RIBA = (byte)((RIBA & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public override bool RIBA_6 { get => (RIBA & (1 << 6)) == 1 << 6; set => RIBA = (byte)((RIBA & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public override bool RIBA_7 { get => (RIBA & (1 << 7)) == 1 << 7; set => RIBA = (byte)((RIBA & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused + public override bool RIBB_0 { get => (RIBB & (1 << 0)) == 1 << 0; set => RIBB = (byte)((RIBB & ~(1 << 0)) | (value ? 1 << 0 : 0)); } // Unused + public override bool RIBB_1 { get => (RIBB & (1 << 1)) == 1 << 1; set => RIBB = (byte)((RIBB & ~(1 << 1)) | (value ? 1 << 1 : 0)); } // Unused + public override bool RIBB_2 { get => (RIBB & (1 << 2)) == 1 << 2; set => RIBB = (byte)((RIBB & ~(1 << 2)) | (value ? 1 << 2 : 0)); } // Unused + public override bool RIBB_3 { get => (RIBB & (1 << 3)) == 1 << 3; set => RIBB = (byte)((RIBB & ~(1 << 3)) | (value ? 1 << 3 : 0)); } // Unused + public override bool RIBB_4 { get => (RIBB & (1 << 4)) == 1 << 4; set => RIBB = (byte)((RIBB & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public override bool RIBB_5 { get => (RIBB & (1 << 5)) == 1 << 5; set => RIBB = (byte)((RIBB & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public override bool RIBB_6 { get => (RIBB & (1 << 6)) == 1 << 6; set => RIBB = (byte)((RIBB & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public override bool RIBB_7 { get => (RIBB & (1 << 7)) == 1 << 7; set => RIBB = (byte)((RIBB & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused // 0x64-0x67 Unused #endregion @@ -247,7 +252,7 @@ public override int Egg_Location BigEndian.GetBytes((ushort)0).CopyTo(Data, 0x44); BigEndian.GetBytes((ushort)0).CopyTo(Data, 0x7E); } - else if (value < 2000 && value > 111 || value < 3000 && value > 2010) + else if ((value < 2000 && value > 111) || (value < 3000 && value > 2010)) { // Met location not in DP, set to Faraway Place BigEndian.GetBytes((ushort)value).CopyTo(Data, 0x44); @@ -261,6 +266,7 @@ public override int Egg_Location } } } + public override int Met_Location { get @@ -277,7 +283,7 @@ public override int Met_Location BigEndian.GetBytes((ushort)0).CopyTo(Data, 0x46); BigEndian.GetBytes((ushort)0).CopyTo(Data, 0x80); } - else if (value < 2000 && value > 111 || value < 3000 && value > 2010) + else if ((value < 2000 && value > 111) || (value < 3000 && value > 2010)) { // Met location not in DP, set to Faraway Place BigEndian.GetBytes((ushort)value).CopyTo(Data, 0x46); @@ -291,9 +297,11 @@ public override int Met_Location } } } + private byte PKRS { get => Data[0x82]; set => Data[0x82] = value; } - public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)(PKRS & ~0xF | value); } - public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)(PKRS & 0xF | (value << 4)); } + public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)((PKRS & ~0xF) | value); } + public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)((PKRS & 0xF) | (value << 4)); } + public override int Ball { get => Math.Max(Data[0x86], Data[0x83]); @@ -316,8 +324,9 @@ public override int Ball Data[0x86] = 0; // Unused } } + public override int Met_Level { get => Data[0x84] >> 1; set => Data[0x84] = (byte)((Data[0x84] & 0x1) | value << 1); } - public override int OT_Gender { get => Data[0x84] & 1; set => Data[0x84] = (byte)((Data[0x84] & ~0x1) | value & 1); } + public override int OT_Gender { get => Data[0x84] & 1; set => Data[0x84] = (byte)((Data[0x84] & ~0x1) | (value & 1)); } public override int EncounterType { get => Data[0x85]; set => Data[0x85] = (byte)value; } // Unused 0x87 #endregion diff --git a/PKHeX.Core/PKM/CK3.cs b/PKHeX.Core/PKM/CK3.cs index 4a8f808c1..a23afb751 100644 --- a/PKHeX.Core/PKM/CK3.cs +++ b/PKHeX.Core/PKM/CK3.cs @@ -13,6 +13,7 @@ public sealed class CK3 : _K3, IShadowPKM 0xE4, 0xE5, 0xE6, 0xE7, 0xCE, // 0xFC onwards unused? }; + public override int SIZE_PARTY => PKX.SIZE_3CSTORED; public override int SIZE_STORED => PKX.SIZE_3CSTORED; public override int Format => 3; @@ -23,6 +24,7 @@ public CK3(byte[] decryptedData = null, string ident = null) Data = decryptedData ?? new byte[SIZE_PARTY]; Identifier = ident; } + public CK3() => Data = new byte[SIZE_PARTY]; public override PKM Clone() => new CK3((byte[])Data.Clone(), Identifier); @@ -92,18 +94,23 @@ public CK3(byte[] decryptedData = null, string ident = null) public override int EV_HP { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0x98)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0x98); } + public override int EV_ATK { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0x9A)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0x9A); } + public override int EV_DEF { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0x9C)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0x9C); } + public override int EV_SPA { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0x9E)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0x9E); } + public override int EV_SPD { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0xA0)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0xA0); } + public override int EV_SPE { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0xA2)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0xA2); } @@ -112,18 +119,23 @@ public CK3(byte[] decryptedData = null, string ident = null) public override int IV_HP { get => Math.Min((ushort)31, BigEndian.ToUInt16(Data, 0xA4)); set => BigEndian.GetBytes((ushort)(value & 0x1F)).CopyTo(Data, 0xA4); } + public override int IV_ATK { get => Math.Min((ushort)31, BigEndian.ToUInt16(Data, 0xA6)); set => BigEndian.GetBytes((ushort)(value & 0x1F)).CopyTo(Data, 0xA6); } + public override int IV_DEF { get => Math.Min((ushort)31, BigEndian.ToUInt16(Data, 0xA8)); set => BigEndian.GetBytes((ushort)(value & 0x1F)).CopyTo(Data, 0xA8); } + public override int IV_SPA { get => Math.Min((ushort)31, BigEndian.ToUInt16(Data, 0xAA)); set => BigEndian.GetBytes((ushort)(value & 0x1F)).CopyTo(Data, 0xAA); } + public override int IV_SPD { get => Math.Min((ushort)31, BigEndian.ToUInt16(Data, 0xAC)); set => BigEndian.GetBytes((ushort)(value & 0x1F)).CopyTo(Data, 0xAC); } + public override int IV_SPE { get => Math.Min((ushort)31, BigEndian.ToUInt16(Data, 0xAE)); set => BigEndian.GetBytes((ushort)(value & 0x1F)).CopyTo(Data, 0xAE); } @@ -156,10 +168,10 @@ public CK3(byte[] decryptedData = null, string ident = null) public override bool RibbonNational { get => Data[0xC6] == 1; set => Data[0xC6] = (byte)(value ? 1 : 0); } public override bool RibbonEarth { get => Data[0xC7] == 1; set => Data[0xC7] = (byte)(value ? 1 : 0); } public override bool RibbonWorld { get => Data[0xC8] == 1; set => Data[0xC8] = (byte)(value ? 1 : 0); } - public override bool Unused1 { get => ((Data[0xC9] >> 0) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~1 | (value ? 1 : 0)); } - public override bool Unused2 { get => ((Data[0xC9] >> 1) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~2 | (value ? 2 : 0)); } - public override bool Unused3 { get => ((Data[0xC9] >> 2) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~4 | (value ? 4 : 0)); } - public override bool Unused4 { get => ((Data[0xC9] >> 3) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~8 | (value ? 8 : 0)); } + public override bool Unused1 { get => ((Data[0xC9] >> 0) & 1) == 1; set => Data[0xC9] = (byte)((Data[0xC9] & ~1) | (value ? 1 : 0)); } + public override bool Unused2 { get => ((Data[0xC9] >> 1) & 1) == 1; set => Data[0xC9] = (byte)((Data[0xC9] & ~2) | (value ? 2 : 0)); } + public override bool Unused3 { get => ((Data[0xC9] >> 2) & 1) == 1; set => Data[0xC9] = (byte)((Data[0xC9] & ~4) | (value ? 4 : 0)); } + public override bool Unused4 { get => ((Data[0xC9] >> 3) & 1) == 1; set => Data[0xC9] = (byte)((Data[0xC9] & ~8) | (value ? 8 : 0)); } public override int PKRS_Strain { get => Data[0xCA] & 0xF; set => Data[0xCA] = (byte)(value & 0xF); } public override bool IsEgg { get => Data[0xCB] == 1; set => Data[0xCB] = (byte)(value ? 1 : 0); } @@ -178,6 +190,7 @@ protected override byte[] Encrypt() { return (byte[])Data.Clone(); } + public PK3 ConvertToPK3() { var pk = ConvertTo(); diff --git a/PKHeX.Core/PKM/PK3.cs b/PKHeX.Core/PKM/PK3.cs index e42a0adc2..2233a8168 100644 --- a/PKHeX.Core/PKM/PK3.cs +++ b/PKHeX.Core/PKM/PK3.cs @@ -9,6 +9,7 @@ public sealed class PK3 : _K3 { 0x2A, 0x2B }; + public override int SIZE_PARTY => PKX.SIZE_3PARTY; public override int SIZE_STORED => PKX.SIZE_3STORED; public override int Format => 3; @@ -22,6 +23,7 @@ public PK3(byte[] decryptedData = null, string ident = null) if (Data.Length != SIZE_PARTY) Array.Resize(ref Data, SIZE_PARTY); } + public PK3() => Data = new byte[SIZE_PARTY]; public override PKM Clone() => new PK3((byte[])Data.Clone(), Identifier); @@ -33,15 +35,15 @@ public PK3(byte[] decryptedData = null, string ident = null) public override byte[] OT_Trash { get => GetData(0x14, 7); set { if (value?.Length == 7) value.CopyTo(Data, 0x14); } } // At top for System.Reflection execution order hack - public override bool IsEgg { get => egg; set => egg = value; } - public override int Language { get => lang; set => lang = value; } + public override bool IsEgg { get => EggFlag; set => EggFlag = value; } + public override int Language { get => LangID; set => LangID = value; } // 0x20 Intro public override uint PID { get => BitConverter.ToUInt32(Data, 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, 0x00); } public override int TID { get => BitConverter.ToUInt16(Data, 0x04); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x04); } public override int SID { get => BitConverter.ToUInt16(Data, 0x06); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x06); } public override string Nickname { get => GetString(0x08, 10); set => SetString(IsEgg ? "タマゴ" : value, 10).CopyTo(Data, 0x08); } - private int lang{ get => BitConverter.ToUInt16(Data, 0x12) & 0xFF; set => BitConverter.GetBytes((ushort)(IsEgg ? 0x601 : value | 0x200)).CopyTo(Data, 0x12); } + private int LangID { get => BitConverter.ToUInt16(Data, 0x12) & 0xFF; set => BitConverter.GetBytes((ushort)(IsEgg ? 0x601 : value | 0x200)).CopyTo(Data, 0x12); } public override string OT_Name { get => GetString(0x14, 7); set => SetString(value, 7).CopyTo(Data, 0x14); } public override int MarkValue { get => SwapBits(Data[0x1B], 1, 2); protected set => Data[0x1B] = (byte)SwapBits(value, 1, 2); } public override ushort Checksum { get => BitConverter.ToUInt16(Data, 0x1C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x1C); } @@ -91,15 +93,15 @@ public PK3(byte[] decryptedData = null, string ident = null) #region Block D private byte PKRS { get => Data[0x44]; set => Data[0x44] = value; } - public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)(PKRS & ~0xF | value); } - public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)(PKRS & 0xF | value << 4); } + public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)((PKRS & ~0xF) | value); } + public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)((PKRS & 0xF) | value << 4); } public override int Met_Location { get => Data[0x45]; set => Data[0x45] = (byte)value; } // Origins private ushort Origins { get => BitConverter.ToUInt16(Data, 0x46); set => BitConverter.GetBytes(value).CopyTo(Data, 0x46); } public override int Met_Level { get => Origins & 0x7F; set => Origins = (ushort)((Origins & ~0x7F) | value); } public override int Version { get => (Origins >> 7) & 0xF; set => Origins = (ushort)((Origins & ~0x780) | ((value & 0xF) << 7)); } public override int Ball { get => (Origins >> 11) & 0xF; set => Origins = (ushort)((Origins & ~0x7800) | ((value & 0xF) << 11)); } - public override int OT_Gender { get => (Origins >> 15) & 1; set => Origins = (ushort)(Origins & ~(1 << 15) | ((value & 1) << 15)); } + public override int OT_Gender { get => (Origins >> 15) & 1; set => Origins = (ushort)((Origins & ~(1 << 15)) | ((value & 1) << 15)); } public uint IV32 { get => BitConverter.ToUInt32(Data, 0x48); set => BitConverter.GetBytes(value).CopyTo(Data, 0x48); } public override int IV_HP { get => (int)(IV32 >> 00) & 0x1F; set => IV32 = (uint)((IV32 & ~(0x1F << 00)) | (uint)((value > 31 ? 31 : value) << 00)); } @@ -108,7 +110,7 @@ public PK3(byte[] decryptedData = null, string ident = null) public override int IV_SPE { get => (int)(IV32 >> 15) & 0x1F; set => IV32 = (uint)((IV32 & ~(0x1F << 15)) | (uint)((value > 31 ? 31 : value) << 15)); } public override int IV_SPA { get => (int)(IV32 >> 20) & 0x1F; set => IV32 = (uint)((IV32 & ~(0x1F << 20)) | (uint)((value > 31 ? 31 : value) << 20)); } public override int IV_SPD { get => (int)(IV32 >> 25) & 0x1F; set => IV32 = (uint)((IV32 & ~(0x1F << 25)) | (uint)((value > 31 ? 31 : value) << 25)); } - private bool egg { get => ((IV32 >> 30) & 1) == 1; set => IV32 = (uint)((IV32 & ~0x40000000) | (uint)(value ? 0x40000000 : 0)); } + private bool EggFlag { get => ((IV32 >> 30) & 1) == 1; set => IV32 = (uint)((IV32 & ~0x40000000) | (uint)(value ? 0x40000000 : 0)); } public override bool AbilityBit { get => IV32 >> 31 == 1; set => IV32 = (IV32 & 0x7FFFFFFF) | (uint)(value ? 1 << 31 : 0); } private uint RIB0 { get => BitConverter.ToUInt32(Data, 0x4C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x4C); } @@ -117,22 +119,22 @@ public PK3(byte[] decryptedData = null, string ident = null) public override int RibbonCountG3Cute { get => (int)(RIB0 >> 06) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 06)) | (uint)(value & 7) << 06); } public override int RibbonCountG3Smart { get => (int)(RIB0 >> 09) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 09)) | (uint)(value & 7) << 09); } public override int RibbonCountG3Tough { get => (int)(RIB0 >> 12) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 12)) | (uint)(value & 7) << 12); } - public override bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 15)) == 1 << 15; set => RIB0 = (uint)(RIB0 & ~(1 << 15) | (uint)(value ? 1 << 15 : 0)); } - public override bool RibbonWinning { get => (RIB0 & (1 << 16)) == 1 << 16; set => RIB0 = (uint)(RIB0 & ~(1 << 16) | (uint)(value ? 1 << 16 : 0)); } - public override bool RibbonVictory { get => (RIB0 & (1 << 17)) == 1 << 17; set => RIB0 = (uint)(RIB0 & ~(1 << 17) | (uint)(value ? 1 << 17 : 0)); } - public override bool RibbonArtist { get => (RIB0 & (1 << 18)) == 1 << 18; set => RIB0 = (uint)(RIB0 & ~(1 << 18) | (uint)(value ? 1 << 18 : 0)); } - public override bool RibbonEffort { get => (RIB0 & (1 << 19)) == 1 << 19; set => RIB0 = (uint)(RIB0 & ~(1 << 19) | (uint)(value ? 1 << 19 : 0)); } - public override bool RibbonChampionBattle { get => (RIB0 & (1 << 20)) == 1 << 20; set => RIB0 = (uint)(RIB0 & ~(1 << 20) | (uint)(value ? 1 << 20 : 0)); } - public override bool RibbonChampionRegional { get => (RIB0 & (1 << 21)) == 1 << 21; set => RIB0 = (uint)(RIB0 & ~(1 << 21) | (uint)(value ? 1 << 21 : 0)); } - public override bool RibbonChampionNational { get => (RIB0 & (1 << 22)) == 1 << 22; set => RIB0 = (uint)(RIB0 & ~(1 << 22) | (uint)(value ? 1 << 22 : 0)); } - public override bool RibbonCountry { get => (RIB0 & (1 << 23)) == 1 << 23; set => RIB0 = (uint)(RIB0 & ~(1 << 23) | (uint)(value ? 1 << 23 : 0)); } - public override bool RibbonNational { get => (RIB0 & (1 << 24)) == 1 << 24; set => RIB0 = (uint)(RIB0 & ~(1 << 24) | (uint)(value ? 1 << 24 : 0)); } - public override bool RibbonEarth { get => (RIB0 & (1 << 25)) == 1 << 25; set => RIB0 = (uint)(RIB0 & ~(1 << 25) | (uint)(value ? 1 << 25 : 0)); } - public override bool RibbonWorld { get => (RIB0 & (1 << 26)) == 1 << 26; set => RIB0 = (uint)(RIB0 & ~(1 << 26) | (uint)(value ? 1 << 26 : 0)); } - public override bool Unused1 { get => (RIB0 & (1 << 27)) == 1 << 27; set => RIB0 = (uint)(RIB0 & ~(1 << 27) | (uint)(value ? 1 << 27 : 0)); } - public override bool Unused2 { get => (RIB0 & (1 << 28)) == 1 << 28; set => RIB0 = (uint)(RIB0 & ~(1 << 28) | (uint)(value ? 1 << 28 : 0)); } - public override bool Unused3 { get => (RIB0 & (1 << 29)) == 1 << 29; set => RIB0 = (uint)(RIB0 & ~(1 << 29) | (uint)(value ? 1 << 29 : 0)); } - public override bool Unused4 { get => (RIB0 & (1 << 30)) == 1 << 30; set => RIB0 = (uint)(RIB0 & ~(1 << 30) | (uint)(value ? 1 << 30 : 0)); } + public override bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 15)) == 1 << 15; set => RIB0 = (uint)((RIB0 & ~(1 << 15)) | (uint)(value ? 1 << 15 : 0)); } + public override bool RibbonWinning { get => (RIB0 & (1 << 16)) == 1 << 16; set => RIB0 = (uint)((RIB0 & ~(1 << 16)) | (uint)(value ? 1 << 16 : 0)); } + public override bool RibbonVictory { get => (RIB0 & (1 << 17)) == 1 << 17; set => RIB0 = (uint)((RIB0 & ~(1 << 17)) | (uint)(value ? 1 << 17 : 0)); } + public override bool RibbonArtist { get => (RIB0 & (1 << 18)) == 1 << 18; set => RIB0 = (uint)((RIB0 & ~(1 << 18)) | (uint)(value ? 1 << 18 : 0)); } + public override bool RibbonEffort { get => (RIB0 & (1 << 19)) == 1 << 19; set => RIB0 = (uint)((RIB0 & ~(1 << 19)) | (uint)(value ? 1 << 19 : 0)); } + public override bool RibbonChampionBattle { get => (RIB0 & (1 << 20)) == 1 << 20; set => RIB0 = (uint)((RIB0 & ~(1 << 20)) | (uint)(value ? 1 << 20 : 0)); } + public override bool RibbonChampionRegional { get => (RIB0 & (1 << 21)) == 1 << 21; set => RIB0 = (uint)((RIB0 & ~(1 << 21)) | (uint)(value ? 1 << 21 : 0)); } + public override bool RibbonChampionNational { get => (RIB0 & (1 << 22)) == 1 << 22; set => RIB0 = (uint)((RIB0 & ~(1 << 22)) | (uint)(value ? 1 << 22 : 0)); } + public override bool RibbonCountry { get => (RIB0 & (1 << 23)) == 1 << 23; set => RIB0 = (uint)((RIB0 & ~(1 << 23)) | (uint)(value ? 1 << 23 : 0)); } + public override bool RibbonNational { get => (RIB0 & (1 << 24)) == 1 << 24; set => RIB0 = (uint)((RIB0 & ~(1 << 24)) | (uint)(value ? 1 << 24 : 0)); } + public override bool RibbonEarth { get => (RIB0 & (1 << 25)) == 1 << 25; set => RIB0 = (uint)((RIB0 & ~(1 << 25)) | (uint)(value ? 1 << 25 : 0)); } + public override bool RibbonWorld { get => (RIB0 & (1 << 26)) == 1 << 26; set => RIB0 = (uint)((RIB0 & ~(1 << 26)) | (uint)(value ? 1 << 26 : 0)); } + public override bool Unused1 { get => (RIB0 & (1 << 27)) == 1 << 27; set => RIB0 = (uint)((RIB0 & ~(1 << 27)) | (uint)(value ? 1 << 27 : 0)); } + public override bool Unused2 { get => (RIB0 & (1 << 28)) == 1 << 28; set => RIB0 = (uint)((RIB0 & ~(1 << 28)) | (uint)(value ? 1 << 28 : 0)); } + public override bool Unused3 { get => (RIB0 & (1 << 29)) == 1 << 29; set => RIB0 = (uint)((RIB0 & ~(1 << 29)) | (uint)(value ? 1 << 29 : 0)); } + public override bool Unused4 { get => (RIB0 & (1 << 30)) == 1 << 30; set => RIB0 = (uint)((RIB0 & ~(1 << 30)) | (uint)(value ? 1 << 30 : 0)); } public override bool FatefulEncounter { get => RIB0 >> 31 == 1; set => RIB0 = (RIB0 & ~(1 << 31)) | (uint)(value ? 1 << 31 : 0); } #endregion @@ -154,6 +156,7 @@ protected override byte[] Encrypt() RefreshChecksum(); return PKX.EncryptArray3(Data); } + public PK4 ConvertToPK4() { DateTime moment = DateTime.Now; @@ -273,8 +276,11 @@ public PK4 ConvertToPK4() // Remove HM moves int[] newMoves = pk4.Moves; for (int i = 0; i < 4; i++) + { if (Legal.HM_3.Contains(newMoves[i])) newMoves[i] = 0; + } + pk4.Moves = newMoves; pk4.FixMoves(); @@ -289,6 +295,7 @@ public XK3 ConvertToXK3() pk.Stat_Level = pk.CurrentLevel; return pk; } + public CK3 ConvertToCK3() { var pk = ConvertTo(); diff --git a/PKHeX.Core/PKM/PK4.cs b/PKHeX.Core/PKM/PK4.cs index b1e7be558..5435a1d6a 100644 --- a/PKHeX.Core/PKM/PK4.cs +++ b/PKHeX.Core/PKM/PK4.cs @@ -10,6 +10,7 @@ public sealed class PK4 : _K4 { 0x42, 0x43, 0x5E, 0x63, 0x64, 0x65, 0x66, 0x67, 0x87 }; + public override int SIZE_PARTY => PKX.SIZE_4PARTY; public override int SIZE_STORED => PKX.SIZE_4STORED; public override int Format => 4; @@ -23,6 +24,7 @@ public PK4(byte[] decryptedData = null, string ident = null) if (Data.Length != SIZE_PARTY) Array.Resize(ref Data, SIZE_PARTY); } + public PK4() => Data = new byte[SIZE_PARTY]; public override PKM Clone() => new PK4((byte[])Data.Clone(), Identifier); @@ -61,38 +63,38 @@ public PK4(byte[] decryptedData = null, string ident = null) private byte RIB1 { get => Data[0x25]; set => Data[0x25] = value; } // Sinnoh 2 private byte RIB2 { get => Data[0x26]; set => Data[0x26] = value; } // Unova 1 private byte RIB3 { get => Data[0x27]; set => Data[0x27] = value; } // Unova 2 - public override bool RibbonChampionSinnoh { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)(RIB0 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonAbility { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)(RIB0 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonAbilityGreat { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)(RIB0 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonAbilityDouble { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)(RIB0 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonAbilityMulti { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)(RIB0 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonAbilityPair { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)(RIB0 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonAbilityWorld { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)(RIB0 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonAlert { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)(RIB0 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonShock { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)(RIB1 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonDowncast { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)(RIB1 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonCareless { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)(RIB1 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonRelax { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)(RIB1 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonSnooze { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)(RIB1 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonSmile { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)(RIB1 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonGorgeous { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)(RIB1 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonRoyal { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)(RIB1 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)(RIB2 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonFootprint { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)(RIB2 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonRecord { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)(RIB2 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonEvent { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)(RIB2 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonLegend { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)(RIB2 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonChampionWorld { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)(RIB2 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonBirthday { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)(RIB2 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonSpecial { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)(RIB2 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonSouvenir { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)(RIB3 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonWishing { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)(RIB3 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)(RIB3 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)(RIB3 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RIB3_4 { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)(RIB3 & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public override bool RIB3_5 { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)(RIB3 & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public override bool RIB3_6 { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)(RIB3 & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public override bool RIB3_7 { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)(RIB3 & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused + public override bool RibbonChampionSinnoh { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)((RIB0 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonAbility { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)((RIB0 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonAbilityGreat { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)((RIB0 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonAbilityDouble { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)((RIB0 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonAbilityMulti { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)((RIB0 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonAbilityPair { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)((RIB0 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonAbilityWorld { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)((RIB0 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonAlert { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)((RIB0 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonShock { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)((RIB1 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonDowncast { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)((RIB1 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonCareless { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)((RIB1 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonRelax { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)((RIB1 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonSnooze { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)((RIB1 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonSmile { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)((RIB1 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonGorgeous { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)((RIB1 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonRoyal { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)((RIB1 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)((RIB2 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonFootprint { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)((RIB2 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonRecord { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)((RIB2 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonEvent { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)((RIB2 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonLegend { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)((RIB2 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonChampionWorld { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)((RIB2 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonBirthday { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)((RIB2 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonSpecial { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)((RIB2 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonSouvenir { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)((RIB3 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonWishing { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)((RIB3 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)((RIB3 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)((RIB3 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RIB3_4 { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)((RIB3 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public override bool RIB3_5 { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)((RIB3 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public override bool RIB3_6 { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)((RIB3 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public override bool RIB3_7 { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)((RIB3 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused #endregion #region Block B @@ -122,42 +124,42 @@ public PK4(byte[] decryptedData = null, string ident = null) private byte RIB5 { get => Data[0x3D]; set => Data[0x3D] = value; } // Hoenn 1b private byte RIB6 { get => Data[0x3E]; set => Data[0x3E] = value; } // Hoenn 2a private byte RIB7 { get => Data[0x3F]; set => Data[0x3F] = value; } // Hoenn 2b - public override bool RibbonG3Cool { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)(RIB4 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG3CoolSuper { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)(RIB4 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG3CoolHyper { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)(RIB4 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG3CoolMaster { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)(RIB4 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonG3Beauty { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)(RIB4 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonG3BeautySuper { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)(RIB4 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonG3BeautyHyper { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)(RIB4 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonG3BeautyMaster { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)(RIB4 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonG3Cute { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)(RIB5 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG3CuteSuper { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)(RIB5 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG3CuteHyper { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)(RIB5 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG3CuteMaster { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)(RIB5 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonG3Smart { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)(RIB5 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonG3SmartSuper { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)(RIB5 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonG3SmartHyper { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)(RIB5 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonG3SmartMaster { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)(RIB5 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonG3Tough { get => (RIB6 & (1 << 0)) == 1 << 0; set => RIB6 = (byte)(RIB6 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG3ToughSuper { get => (RIB6 & (1 << 1)) == 1 << 1; set => RIB6 = (byte)(RIB6 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG3ToughHyper { get => (RIB6 & (1 << 2)) == 1 << 2; set => RIB6 = (byte)(RIB6 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG3ToughMaster { get => (RIB6 & (1 << 3)) == 1 << 3; set => RIB6 = (byte)(RIB6 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonChampionG3Hoenn { get => (RIB6 & (1 << 4)) == 1 << 4; set => RIB6 = (byte)(RIB6 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonWinning { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)(RIB6 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonVictory { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)(RIB6 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonArtist { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)(RIB6 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonEffort { get => (RIB7 & (1 << 0)) == 1 << 0; set => RIB7 = (byte)(RIB7 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonChampionBattle { get => (RIB7 & (1 << 1)) == 1 << 1; set => RIB7 = (byte)(RIB7 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonChampionRegional { get => (RIB7 & (1 << 2)) == 1 << 2; set => RIB7 = (byte)(RIB7 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonChampionNational { get => (RIB7 & (1 << 3)) == 1 << 3; set => RIB7 = (byte)(RIB7 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonCountry { get => (RIB7 & (1 << 4)) == 1 << 4; set => RIB7 = (byte)(RIB7 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonNational { get => (RIB7 & (1 << 5)) == 1 << 5; set => RIB7 = (byte)(RIB7 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonEarth { get => (RIB7 & (1 << 6)) == 1 << 6; set => RIB7 = (byte)(RIB7 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonWorld { get => (RIB7 & (1 << 7)) == 1 << 7; set => RIB7 = (byte)(RIB7 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public override bool RibbonG3Cool { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)((RIB4 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG3CoolSuper { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)((RIB4 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG3CoolHyper { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)((RIB4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG3CoolMaster { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)((RIB4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonG3Beauty { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)((RIB4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonG3BeautySuper { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonG3BeautyHyper { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonG3BeautyMaster { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)((RIB4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonG3Cute { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)((RIB5 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG3CuteSuper { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)((RIB5 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG3CuteHyper { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)((RIB5 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG3CuteMaster { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)((RIB5 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonG3Smart { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)((RIB5 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonG3SmartSuper { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)((RIB5 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonG3SmartHyper { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)((RIB5 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonG3SmartMaster { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)((RIB5 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonG3Tough { get => (RIB6 & (1 << 0)) == 1 << 0; set => RIB6 = (byte)((RIB6 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG3ToughSuper { get => (RIB6 & (1 << 1)) == 1 << 1; set => RIB6 = (byte)((RIB6 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG3ToughHyper { get => (RIB6 & (1 << 2)) == 1 << 2; set => RIB6 = (byte)((RIB6 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG3ToughMaster { get => (RIB6 & (1 << 3)) == 1 << 3; set => RIB6 = (byte)((RIB6 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonChampionG3Hoenn { get => (RIB6 & (1 << 4)) == 1 << 4; set => RIB6 = (byte)((RIB6 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonWinning { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)((RIB6 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonVictory { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)((RIB6 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonArtist { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)((RIB6 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonEffort { get => (RIB7 & (1 << 0)) == 1 << 0; set => RIB7 = (byte)((RIB7 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonChampionBattle { get => (RIB7 & (1 << 1)) == 1 << 1; set => RIB7 = (byte)((RIB7 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonChampionRegional { get => (RIB7 & (1 << 2)) == 1 << 2; set => RIB7 = (byte)((RIB7 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonChampionNational { get => (RIB7 & (1 << 3)) == 1 << 3; set => RIB7 = (byte)((RIB7 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonCountry { get => (RIB7 & (1 << 4)) == 1 << 4; set => RIB7 = (byte)((RIB7 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonNational { get => (RIB7 & (1 << 5)) == 1 << 5; set => RIB7 = (byte)((RIB7 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonEarth { get => (RIB7 & (1 << 6)) == 1 << 6; set => RIB7 = (byte)((RIB7 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonWorld { get => (RIB7 & (1 << 7)) == 1 << 7; set => RIB7 = (byte)((RIB7 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } - public override bool FatefulEncounter { get => (Data[0x40] & 1) == 1; set => Data[0x40] = (byte)(Data[0x40] & ~0x01 | (value ? 1 : 0)); } - public override int Gender { get => (Data[0x40] >> 1) & 0x3; set => Data[0x40] = (byte)(Data[0x40] & ~0x06 | (value << 1)); } - public override int AltForm { get => Data[0x40] >> 3; set => Data[0x40] = (byte)(Data[0x40] & 0x07 | (value << 3)); } + public override bool FatefulEncounter { get => (Data[0x40] & 1) == 1; set => Data[0x40] = (byte)((Data[0x40] & ~0x01) | (value ? 1 : 0)); } + public override int Gender { get => (Data[0x40] >> 1) & 0x3; set => Data[0x40] = (byte)((Data[0x40] & ~0x06) | (value << 1)); } + public override int AltForm { get => Data[0x40] >> 3; set => Data[0x40] = (byte)((Data[0x40] & 0x07) | (value << 3)); } public override int ShinyLeaf { get => Data[0x41]; set => Data[0x41] = (byte) value; } // 0x43-0x47 Unused #endregion @@ -170,38 +172,38 @@ public PK4(byte[] decryptedData = null, string ident = null) private byte RIB9 { get => Data[0x61]; set => Data[0x61] = value; } // Sinnoh 4 private byte RIBA { get => Data[0x62]; set => Data[0x62] = value; } // Sinnoh 5 private byte RIBB { get => Data[0x63]; set => Data[0x63] = value; } // Sinnoh 6 - public override bool RibbonG4Cool { get => (RIB8 & (1 << 0)) == 1 << 0; set => RIB8 = (byte)(RIB8 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG4CoolGreat { get => (RIB8 & (1 << 1)) == 1 << 1; set => RIB8 = (byte)(RIB8 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG4CoolUltra { get => (RIB8 & (1 << 2)) == 1 << 2; set => RIB8 = (byte)(RIB8 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG4CoolMaster { get => (RIB8 & (1 << 3)) == 1 << 3; set => RIB8 = (byte)(RIB8 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonG4Beauty { get => (RIB8 & (1 << 4)) == 1 << 4; set => RIB8 = (byte)(RIB8 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonG4BeautyGreat { get => (RIB8 & (1 << 5)) == 1 << 5; set => RIB8 = (byte)(RIB8 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonG4BeautyUltra { get => (RIB8 & (1 << 6)) == 1 << 6; set => RIB8 = (byte)(RIB8 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonG4BeautyMaster { get => (RIB8 & (1 << 7)) == 1 << 7; set => RIB8 = (byte)(RIB8 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonG4Cute { get => (RIB9 & (1 << 0)) == 1 << 0; set => RIB9 = (byte)(RIB9 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG4CuteGreat { get => (RIB9 & (1 << 1)) == 1 << 1; set => RIB9 = (byte)(RIB9 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG4CuteUltra { get => (RIB9 & (1 << 2)) == 1 << 2; set => RIB9 = (byte)(RIB9 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG4CuteMaster { get => (RIB9 & (1 << 3)) == 1 << 3; set => RIB9 = (byte)(RIB9 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RibbonG4Smart { get => (RIB9 & (1 << 4)) == 1 << 4; set => RIB9 = (byte)(RIB9 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public override bool RibbonG4SmartGreat { get => (RIB9 & (1 << 5)) == 1 << 5; set => RIB9 = (byte)(RIB9 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public override bool RibbonG4SmartUltra { get => (RIB9 & (1 << 6)) == 1 << 6; set => RIB9 = (byte)(RIB9 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public override bool RibbonG4SmartMaster { get => (RIB9 & (1 << 7)) == 1 << 7; set => RIB9 = (byte)(RIB9 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public override bool RibbonG4Tough { get => (RIBA & (1 << 0)) == 1 << 0; set => RIBA = (byte)(RIBA & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public override bool RibbonG4ToughGreat { get => (RIBA & (1 << 1)) == 1 << 1; set => RIBA = (byte)(RIBA & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public override bool RibbonG4ToughUltra { get => (RIBA & (1 << 2)) == 1 << 2; set => RIBA = (byte)(RIBA & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public override bool RibbonG4ToughMaster { get => (RIBA & (1 << 3)) == 1 << 3; set => RIBA = (byte)(RIBA & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public override bool RIBA_4 { get => (RIBA & (1 << 4)) == 1 << 4; set => RIBA = (byte)(RIBA & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public override bool RIBA_5 { get => (RIBA & (1 << 5)) == 1 << 5; set => RIBA = (byte)(RIBA & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public override bool RIBA_6 { get => (RIBA & (1 << 6)) == 1 << 6; set => RIBA = (byte)(RIBA & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public override bool RIBA_7 { get => (RIBA & (1 << 7)) == 1 << 7; set => RIBA = (byte)(RIBA & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused - public override bool RIBB_0 { get => (RIBB & (1 << 0)) == 1 << 0; set => RIBB = (byte)(RIBB & ~(1 << 0) | (value ? 1 << 0 : 0)); } // Unused - public override bool RIBB_1 { get => (RIBB & (1 << 1)) == 1 << 1; set => RIBB = (byte)(RIBB & ~(1 << 1) | (value ? 1 << 1 : 0)); } // Unused - public override bool RIBB_2 { get => (RIBB & (1 << 2)) == 1 << 2; set => RIBB = (byte)(RIBB & ~(1 << 2) | (value ? 1 << 2 : 0)); } // Unused - public override bool RIBB_3 { get => (RIBB & (1 << 3)) == 1 << 3; set => RIBB = (byte)(RIBB & ~(1 << 3) | (value ? 1 << 3 : 0)); } // Unused - public override bool RIBB_4 { get => (RIBB & (1 << 4)) == 1 << 4; set => RIBB = (byte)(RIBB & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public override bool RIBB_5 { get => (RIBB & (1 << 5)) == 1 << 5; set => RIBB = (byte)(RIBB & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public override bool RIBB_6 { get => (RIBB & (1 << 6)) == 1 << 6; set => RIBB = (byte)(RIBB & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public override bool RIBB_7 { get => (RIBB & (1 << 7)) == 1 << 7; set => RIBB = (byte)(RIBB & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused + public override bool RibbonG4Cool { get => (RIB8 & (1 << 0)) == 1 << 0; set => RIB8 = (byte)((RIB8 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG4CoolGreat { get => (RIB8 & (1 << 1)) == 1 << 1; set => RIB8 = (byte)((RIB8 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG4CoolUltra { get => (RIB8 & (1 << 2)) == 1 << 2; set => RIB8 = (byte)((RIB8 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG4CoolMaster { get => (RIB8 & (1 << 3)) == 1 << 3; set => RIB8 = (byte)((RIB8 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonG4Beauty { get => (RIB8 & (1 << 4)) == 1 << 4; set => RIB8 = (byte)((RIB8 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonG4BeautyGreat { get => (RIB8 & (1 << 5)) == 1 << 5; set => RIB8 = (byte)((RIB8 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonG4BeautyUltra { get => (RIB8 & (1 << 6)) == 1 << 6; set => RIB8 = (byte)((RIB8 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonG4BeautyMaster { get => (RIB8 & (1 << 7)) == 1 << 7; set => RIB8 = (byte)((RIB8 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonG4Cute { get => (RIB9 & (1 << 0)) == 1 << 0; set => RIB9 = (byte)((RIB9 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG4CuteGreat { get => (RIB9 & (1 << 1)) == 1 << 1; set => RIB9 = (byte)((RIB9 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG4CuteUltra { get => (RIB9 & (1 << 2)) == 1 << 2; set => RIB9 = (byte)((RIB9 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG4CuteMaster { get => (RIB9 & (1 << 3)) == 1 << 3; set => RIB9 = (byte)((RIB9 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RibbonG4Smart { get => (RIB9 & (1 << 4)) == 1 << 4; set => RIB9 = (byte)((RIB9 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public override bool RibbonG4SmartGreat { get => (RIB9 & (1 << 5)) == 1 << 5; set => RIB9 = (byte)((RIB9 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public override bool RibbonG4SmartUltra { get => (RIB9 & (1 << 6)) == 1 << 6; set => RIB9 = (byte)((RIB9 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public override bool RibbonG4SmartMaster { get => (RIB9 & (1 << 7)) == 1 << 7; set => RIB9 = (byte)((RIB9 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public override bool RibbonG4Tough { get => (RIBA & (1 << 0)) == 1 << 0; set => RIBA = (byte)((RIBA & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public override bool RibbonG4ToughGreat { get => (RIBA & (1 << 1)) == 1 << 1; set => RIBA = (byte)((RIBA & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public override bool RibbonG4ToughUltra { get => (RIBA & (1 << 2)) == 1 << 2; set => RIBA = (byte)((RIBA & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public override bool RibbonG4ToughMaster { get => (RIBA & (1 << 3)) == 1 << 3; set => RIBA = (byte)((RIBA & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public override bool RIBA_4 { get => (RIBA & (1 << 4)) == 1 << 4; set => RIBA = (byte)((RIBA & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public override bool RIBA_5 { get => (RIBA & (1 << 5)) == 1 << 5; set => RIBA = (byte)((RIBA & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public override bool RIBA_6 { get => (RIBA & (1 << 6)) == 1 << 6; set => RIBA = (byte)((RIBA & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public override bool RIBA_7 { get => (RIBA & (1 << 7)) == 1 << 7; set => RIBA = (byte)((RIBA & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused + public override bool RIBB_0 { get => (RIBB & (1 << 0)) == 1 << 0; set => RIBB = (byte)((RIBB & ~(1 << 0)) | (value ? 1 << 0 : 0)); } // Unused + public override bool RIBB_1 { get => (RIBB & (1 << 1)) == 1 << 1; set => RIBB = (byte)((RIBB & ~(1 << 1)) | (value ? 1 << 1 : 0)); } // Unused + public override bool RIBB_2 { get => (RIBB & (1 << 2)) == 1 << 2; set => RIBB = (byte)((RIBB & ~(1 << 2)) | (value ? 1 << 2 : 0)); } // Unused + public override bool RIBB_3 { get => (RIBB & (1 << 3)) == 1 << 3; set => RIBB = (byte)((RIBB & ~(1 << 3)) | (value ? 1 << 3 : 0)); } // Unused + public override bool RIBB_4 { get => (RIBB & (1 << 4)) == 1 << 4; set => RIBB = (byte)((RIBB & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public override bool RIBB_5 { get => (RIBB & (1 << 5)) == 1 << 5; set => RIBB = (byte)((RIBB & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public override bool RIBB_6 { get => (RIBB & (1 << 6)) == 1 << 6; set => RIBB = (byte)((RIBB & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public override bool RIBB_7 { get => (RIBB & (1 << 7)) == 1 << 7; set => RIBB = (byte)((RIBB & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused // 0x64-0x67 Unused #endregion @@ -230,7 +232,7 @@ public override int Egg_Location BitConverter.GetBytes((ushort)0).CopyTo(Data, 0x44); BitConverter.GetBytes((ushort)0).CopyTo(Data, 0x7E); } - else if (value < 2000 && value > 111 || value < 3000 && value > 2010) + else if ((value < 2000 && value > 111) || (value < 3000 && value > 2010)) { // Met location not in DP, set to Faraway Place BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x44); @@ -244,6 +246,7 @@ public override int Egg_Location } } } + public override int Met_Location { get @@ -260,7 +263,7 @@ public override int Met_Location BitConverter.GetBytes((ushort)0).CopyTo(Data, 0x46); BitConverter.GetBytes((ushort)0).CopyTo(Data, 0x80); } - else if (value < 2000 && value > 111 || value < 3000 && value > 2010) + else if ((value < 2000 && value > 111) || (value < 3000 && value > 2010)) { // Met location not in DP, set to Faraway Place BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x46); @@ -274,9 +277,11 @@ public override int Met_Location } } } + private byte PKRS { get => Data[0x82]; set => Data[0x82] = value; } - public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)(PKRS & ~0xF | value); } - public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)(PKRS & 0xF | (value << 4)); } + public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)((PKRS & ~0xF) | value); } + public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)((PKRS & 0xF) | (value << 4)); } + public override int Ball { get => @@ -299,6 +304,7 @@ public override int Ball Data[0x86] = 0; // Unused } } + public override int Met_Level { get => Data[0x84] & ~0x80; set => Data[0x84] = (byte)((Data[0x84] & 0x80) | value); } public override int OT_Gender { get => Data[0x84] >> 7; set => Data[0x84] = (byte)((Data[0x84] & ~0x80) | value << 7); } public override int EncounterType { get => Data[0x85]; set => Data[0x85] = (byte)value; } @@ -412,8 +418,11 @@ public PK5 ConvertToPK5() int[] newMoves = pk5.Moves; for (int i = 0; i < 4; i++) + { if (banned.Contains(newMoves[i])) newMoves[i] = 0; + } + pk5.Moves = newMoves; pk5.FixMoves(); diff --git a/PKHeX.Core/PKM/PK5.cs b/PKHeX.Core/PKM/PK5.cs index 14979832e..37a4d7bfe 100644 --- a/PKHeX.Core/PKM/PK5.cs +++ b/PKHeX.Core/PKM/PK5.cs @@ -10,6 +10,7 @@ public sealed class PK5 : PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetUni { 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x5E, 0x63, 0x64, 0x65, 0x66, 0x67, 0x87 }; + public override int SIZE_PARTY => PKX.SIZE_5PARTY; public override int SIZE_STORED => PKX.SIZE_5STORED; public override int Format => 5; @@ -23,6 +24,7 @@ public PK5(byte[] decryptedData = null, string ident = null) if (Data.Length != SIZE_PARTY) Array.Resize(ref Data, SIZE_PARTY); } + public override PKM Clone() => new PK5((byte[])Data.Clone(), Identifier); private string GetString(int Offset, int Count) => StringConverter.GetString5(Data, Offset, Count); @@ -70,38 +72,38 @@ public PK5(byte[] decryptedData = null, string ident = null) private byte RIB1 { get => Data[0x25]; set => Data[0x25] = value; } // Sinnoh 2 private byte RIB2 { get => Data[0x26]; set => Data[0x26] = value; } // Unova 1 private byte RIB3 { get => Data[0x27]; set => Data[0x27] = value; } // Unova 2 - public bool RibbonChampionSinnoh { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)(RIB0 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonAbility { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)(RIB0 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonAbilityGreat { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)(RIB0 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonAbilityDouble { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)(RIB0 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonAbilityMulti { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)(RIB0 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonAbilityPair { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)(RIB0 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonAbilityWorld { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)(RIB0 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonAlert { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)(RIB0 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonShock { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)(RIB1 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonDowncast { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)(RIB1 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonCareless { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)(RIB1 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonRelax { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)(RIB1 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonSnooze { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)(RIB1 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonSmile { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)(RIB1 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonGorgeous { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)(RIB1 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonRoyal { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)(RIB1 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)(RIB2 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonFootprint { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)(RIB2 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonRecord { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)(RIB2 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonEvent { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)(RIB2 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonLegend { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)(RIB2 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonChampionWorld { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)(RIB2 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonBirthday { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)(RIB2 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonSpecial { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)(RIB2 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonSouvenir { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)(RIB3 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonWishing { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)(RIB3 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)(RIB3 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)(RIB3 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RIB3_4 { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)(RIB3 & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public bool RIB3_5 { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)(RIB3 & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public bool RIB3_6 { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)(RIB3 & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public bool RIB3_7 { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)(RIB3 & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused + public bool RibbonChampionSinnoh { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)((RIB0 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonAbility { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)((RIB0 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonAbilityGreat { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)((RIB0 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonAbilityDouble { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)((RIB0 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonAbilityMulti { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)((RIB0 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonAbilityPair { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)((RIB0 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonAbilityWorld { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)((RIB0 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonAlert { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)((RIB0 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonShock { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)((RIB1 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonDowncast { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)((RIB1 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonCareless { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)((RIB1 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonRelax { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)((RIB1 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonSnooze { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)((RIB1 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonSmile { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)((RIB1 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonGorgeous { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)((RIB1 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonRoyal { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)((RIB1 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)((RIB2 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonFootprint { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)((RIB2 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonRecord { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)((RIB2 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonEvent { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)((RIB2 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonLegend { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)((RIB2 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonChampionWorld { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)((RIB2 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonBirthday { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)((RIB2 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonSpecial { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)((RIB2 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonSouvenir { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)((RIB3 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonWishing { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)((RIB3 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)((RIB3 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)((RIB3 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RIB3_4 { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)((RIB3 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public bool RIB3_5 { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)((RIB3 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public bool RIB3_6 { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)((RIB3 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public bool RIB3_7 { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)((RIB3 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused #endregion #region Block B @@ -131,45 +133,45 @@ public PK5(byte[] decryptedData = null, string ident = null) private byte RIB5 { get => Data[0x3D]; set => Data[0x3D] = value; } // Hoenn 1b private byte RIB6 { get => Data[0x3E]; set => Data[0x3E] = value; } // Hoenn 2a private byte RIB7 { get => Data[0x3F]; set => Data[0x3F] = value; } // Hoenn 2b - public bool RibbonG3Cool { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)(RIB4 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonG3CoolSuper { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)(RIB4 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonG3CoolHyper { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)(RIB4 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonG3CoolMaster { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)(RIB4 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonG3Beauty { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)(RIB4 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonG3BeautySuper { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)(RIB4 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonG3BeautyHyper { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)(RIB4 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonG3BeautyMaster { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)(RIB4 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonG3Cute { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)(RIB5 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonG3CuteSuper { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)(RIB5 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonG3CuteHyper { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)(RIB5 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonG3CuteMaster { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)(RIB5 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonG3Smart { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)(RIB5 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonG3SmartSuper { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)(RIB5 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonG3SmartHyper { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)(RIB5 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonG3SmartMaster { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)(RIB5 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonG3Tough { get => (RIB6 & (1 << 0)) == 1 << 0; set => RIB6 = (byte)(RIB6 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonG3ToughSuper { get => (RIB6 & (1 << 1)) == 1 << 1; set => RIB6 = (byte)(RIB6 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonG3ToughHyper { get => (RIB6 & (1 << 2)) == 1 << 2; set => RIB6 = (byte)(RIB6 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonG3ToughMaster { get => (RIB6 & (1 << 3)) == 1 << 3; set => RIB6 = (byte)(RIB6 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonChampionG3Hoenn { get => (RIB6 & (1 << 4)) == 1 << 4; set => RIB6 = (byte)(RIB6 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonWinning { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)(RIB6 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonVictory { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)(RIB6 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonArtist { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)(RIB6 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonEffort { get => (RIB7 & (1 << 0)) == 1 << 0; set => RIB7 = (byte)(RIB7 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonChampionBattle { get => (RIB7 & (1 << 1)) == 1 << 1; set => RIB7 = (byte)(RIB7 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonChampionRegional { get => (RIB7 & (1 << 2)) == 1 << 2; set => RIB7 = (byte)(RIB7 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonChampionNational { get => (RIB7 & (1 << 3)) == 1 << 3; set => RIB7 = (byte)(RIB7 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonCountry { get => (RIB7 & (1 << 4)) == 1 << 4; set => RIB7 = (byte)(RIB7 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonNational { get => (RIB7 & (1 << 5)) == 1 << 5; set => RIB7 = (byte)(RIB7 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonEarth { get => (RIB7 & (1 << 6)) == 1 << 6; set => RIB7 = (byte)(RIB7 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonWorld { get => (RIB7 & (1 << 7)) == 1 << 7; set => RIB7 = (byte)(RIB7 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool RibbonG3Cool { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)((RIB4 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonG3CoolSuper { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)((RIB4 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonG3CoolHyper { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)((RIB4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonG3CoolMaster { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)((RIB4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonG3Beauty { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)((RIB4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonG3BeautySuper { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonG3BeautyHyper { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonG3BeautyMaster { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)((RIB4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonG3Cute { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)((RIB5 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonG3CuteSuper { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)((RIB5 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonG3CuteHyper { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)((RIB5 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonG3CuteMaster { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)((RIB5 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonG3Smart { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)((RIB5 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonG3SmartSuper { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)((RIB5 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonG3SmartHyper { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)((RIB5 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonG3SmartMaster { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)((RIB5 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonG3Tough { get => (RIB6 & (1 << 0)) == 1 << 0; set => RIB6 = (byte)((RIB6 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonG3ToughSuper { get => (RIB6 & (1 << 1)) == 1 << 1; set => RIB6 = (byte)((RIB6 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonG3ToughHyper { get => (RIB6 & (1 << 2)) == 1 << 2; set => RIB6 = (byte)((RIB6 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonG3ToughMaster { get => (RIB6 & (1 << 3)) == 1 << 3; set => RIB6 = (byte)((RIB6 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonChampionG3Hoenn { get => (RIB6 & (1 << 4)) == 1 << 4; set => RIB6 = (byte)((RIB6 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonWinning { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)((RIB6 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonVictory { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)((RIB6 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonArtist { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)((RIB6 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonEffort { get => (RIB7 & (1 << 0)) == 1 << 0; set => RIB7 = (byte)((RIB7 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonChampionBattle { get => (RIB7 & (1 << 1)) == 1 << 1; set => RIB7 = (byte)((RIB7 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonChampionRegional { get => (RIB7 & (1 << 2)) == 1 << 2; set => RIB7 = (byte)((RIB7 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonChampionNational { get => (RIB7 & (1 << 3)) == 1 << 3; set => RIB7 = (byte)((RIB7 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonCountry { get => (RIB7 & (1 << 4)) == 1 << 4; set => RIB7 = (byte)((RIB7 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonNational { get => (RIB7 & (1 << 5)) == 1 << 5; set => RIB7 = (byte)((RIB7 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonEarth { get => (RIB7 & (1 << 6)) == 1 << 6; set => RIB7 = (byte)((RIB7 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonWorld { get => (RIB7 & (1 << 7)) == 1 << 7; set => RIB7 = (byte)((RIB7 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } - public override bool FatefulEncounter { get => (Data[0x40] & 1) == 1; set => Data[0x40] = (byte)(Data[0x40] & ~0x01 | (value ? 1 : 0)); } - public override int Gender { get => (Data[0x40] >> 1) & 0x3; set => Data[0x40] = (byte)(Data[0x40] & ~0x06 | (value << 1)); } - public override int AltForm { get => Data[0x40] >> 3; set => Data[0x40] = (byte)(Data[0x40] & 0x07 | (value << 3)); } + public override bool FatefulEncounter { get => (Data[0x40] & 1) == 1; set => Data[0x40] = (byte)((Data[0x40] & ~0x01) | (value ? 1 : 0)); } + public override int Gender { get => (Data[0x40] >> 1) & 0x3; set => Data[0x40] = (byte)((Data[0x40] & ~0x06) | (value << 1)); } + public override int AltForm { get => Data[0x40] >> 3; set => Data[0x40] = (byte)((Data[0x40] & 0x07) | (value << 3)); } public override int Nature { get => Data[0x41]; set => Data[0x41] = (byte)value; } - public bool HiddenAbility { get => (Data[0x42] & 1) == 1; set => Data[0x42] = (byte)(Data[0x42] & ~0x01 | (value ? 1 : 0)); } - public bool NPokémon { get => (Data[0x42] & 2) == 2; set => Data[0x42] = (byte)(Data[0x42] & ~0x02 | (value ? 2 : 0)); } + public bool HiddenAbility { get => (Data[0x42] & 1) == 1; set => Data[0x42] = (byte)((Data[0x42] & ~0x01) | (value ? 1 : 0)); } + public bool NPokémon { get => (Data[0x42] & 2) == 2; set => Data[0x42] = (byte)((Data[0x42] & ~0x02) | (value ? 2 : 0)); } // 0x43-0x47 Unused #endregion @@ -181,38 +183,38 @@ public PK5(byte[] decryptedData = null, string ident = null) private byte RIB9 { get => Data[0x61]; set => Data[0x61] = value; } // Sinnoh 4 private byte RIBA { get => Data[0x62]; set => Data[0x62] = value; } // Sinnoh 5 private byte RIBB { get => Data[0x63]; set => Data[0x63] = value; } // Sinnoh 6 - public bool RibbonG4Cool { get => (RIB8 & (1 << 0)) == 1 << 0; set => RIB8 = (byte)(RIB8 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonG4CoolGreat { get => (RIB8 & (1 << 1)) == 1 << 1; set => RIB8 = (byte)(RIB8 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonG4CoolUltra { get => (RIB8 & (1 << 2)) == 1 << 2; set => RIB8 = (byte)(RIB8 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonG4CoolMaster { get => (RIB8 & (1 << 3)) == 1 << 3; set => RIB8 = (byte)(RIB8 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonG4Beauty { get => (RIB8 & (1 << 4)) == 1 << 4; set => RIB8 = (byte)(RIB8 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonG4BeautyGreat { get => (RIB8 & (1 << 5)) == 1 << 5; set => RIB8 = (byte)(RIB8 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonG4BeautyUltra { get => (RIB8 & (1 << 6)) == 1 << 6; set => RIB8 = (byte)(RIB8 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonG4BeautyMaster { get => (RIB8 & (1 << 7)) == 1 << 7; set => RIB8 = (byte)(RIB8 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonG4Cute { get => (RIB9 & (1 << 0)) == 1 << 0; set => RIB9 = (byte)(RIB9 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonG4CuteGreat { get => (RIB9 & (1 << 1)) == 1 << 1; set => RIB9 = (byte)(RIB9 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonG4CuteUltra { get => (RIB9 & (1 << 2)) == 1 << 2; set => RIB9 = (byte)(RIB9 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonG4CuteMaster { get => (RIB9 & (1 << 3)) == 1 << 3; set => RIB9 = (byte)(RIB9 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonG4Smart { get => (RIB9 & (1 << 4)) == 1 << 4; set => RIB9 = (byte)(RIB9 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonG4SmartGreat { get => (RIB9 & (1 << 5)) == 1 << 5; set => RIB9 = (byte)(RIB9 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonG4SmartUltra { get => (RIB9 & (1 << 6)) == 1 << 6; set => RIB9 = (byte)(RIB9 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonG4SmartMaster { get => (RIB9 & (1 << 7)) == 1 << 7; set => RIB9 = (byte)(RIB9 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonG4Tough { get => (RIBA & (1 << 0)) == 1 << 0; set => RIBA = (byte)(RIBA & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonG4ToughGreat { get => (RIBA & (1 << 1)) == 1 << 1; set => RIBA = (byte)(RIBA & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonG4ToughUltra { get => (RIBA & (1 << 2)) == 1 << 2; set => RIBA = (byte)(RIBA & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonG4ToughMaster { get => (RIBA & (1 << 3)) == 1 << 3; set => RIBA = (byte)(RIBA & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RIBA_4 { get => (RIBA & (1 << 4)) == 1 << 4; set => RIBA = (byte)(RIBA & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public bool RIBA_5 { get => (RIBA & (1 << 5)) == 1 << 5; set => RIBA = (byte)(RIBA & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public bool RIBA_6 { get => (RIBA & (1 << 6)) == 1 << 6; set => RIBA = (byte)(RIBA & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public bool RIBA_7 { get => (RIBA & (1 << 7)) == 1 << 7; set => RIBA = (byte)(RIBA & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused - public bool RIBB_0 { get => (RIBB & (1 << 0)) == 1 << 0; set => RIBB = (byte)(RIBB & ~(1 << 0) | (value ? 1 << 0 : 0)); } // Unused - public bool RIBB_1 { get => (RIBB & (1 << 1)) == 1 << 1; set => RIBB = (byte)(RIBB & ~(1 << 1) | (value ? 1 << 1 : 0)); } // Unused - public bool RIBB_2 { get => (RIBB & (1 << 2)) == 1 << 2; set => RIBB = (byte)(RIBB & ~(1 << 2) | (value ? 1 << 2 : 0)); } // Unused - public bool RIBB_3 { get => (RIBB & (1 << 3)) == 1 << 3; set => RIBB = (byte)(RIBB & ~(1 << 3) | (value ? 1 << 3 : 0)); } // Unused - public bool RIBB_4 { get => (RIBB & (1 << 4)) == 1 << 4; set => RIBB = (byte)(RIBB & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public bool RIBB_5 { get => (RIBB & (1 << 5)) == 1 << 5; set => RIBB = (byte)(RIBB & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public bool RIBB_6 { get => (RIBB & (1 << 6)) == 1 << 6; set => RIBB = (byte)(RIBB & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public bool RIBB_7 { get => (RIBB & (1 << 7)) == 1 << 7; set => RIBB = (byte)(RIBB & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused + public bool RibbonG4Cool { get => (RIB8 & (1 << 0)) == 1 << 0; set => RIB8 = (byte)((RIB8 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonG4CoolGreat { get => (RIB8 & (1 << 1)) == 1 << 1; set => RIB8 = (byte)((RIB8 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonG4CoolUltra { get => (RIB8 & (1 << 2)) == 1 << 2; set => RIB8 = (byte)((RIB8 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonG4CoolMaster { get => (RIB8 & (1 << 3)) == 1 << 3; set => RIB8 = (byte)((RIB8 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonG4Beauty { get => (RIB8 & (1 << 4)) == 1 << 4; set => RIB8 = (byte)((RIB8 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonG4BeautyGreat { get => (RIB8 & (1 << 5)) == 1 << 5; set => RIB8 = (byte)((RIB8 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonG4BeautyUltra { get => (RIB8 & (1 << 6)) == 1 << 6; set => RIB8 = (byte)((RIB8 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonG4BeautyMaster { get => (RIB8 & (1 << 7)) == 1 << 7; set => RIB8 = (byte)((RIB8 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonG4Cute { get => (RIB9 & (1 << 0)) == 1 << 0; set => RIB9 = (byte)((RIB9 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonG4CuteGreat { get => (RIB9 & (1 << 1)) == 1 << 1; set => RIB9 = (byte)((RIB9 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonG4CuteUltra { get => (RIB9 & (1 << 2)) == 1 << 2; set => RIB9 = (byte)((RIB9 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonG4CuteMaster { get => (RIB9 & (1 << 3)) == 1 << 3; set => RIB9 = (byte)((RIB9 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonG4Smart { get => (RIB9 & (1 << 4)) == 1 << 4; set => RIB9 = (byte)((RIB9 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonG4SmartGreat { get => (RIB9 & (1 << 5)) == 1 << 5; set => RIB9 = (byte)((RIB9 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonG4SmartUltra { get => (RIB9 & (1 << 6)) == 1 << 6; set => RIB9 = (byte)((RIB9 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonG4SmartMaster { get => (RIB9 & (1 << 7)) == 1 << 7; set => RIB9 = (byte)((RIB9 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonG4Tough { get => (RIBA & (1 << 0)) == 1 << 0; set => RIBA = (byte)((RIBA & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonG4ToughGreat { get => (RIBA & (1 << 1)) == 1 << 1; set => RIBA = (byte)((RIBA & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonG4ToughUltra { get => (RIBA & (1 << 2)) == 1 << 2; set => RIBA = (byte)((RIBA & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonG4ToughMaster { get => (RIBA & (1 << 3)) == 1 << 3; set => RIBA = (byte)((RIBA & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RIBA_4 { get => (RIBA & (1 << 4)) == 1 << 4; set => RIBA = (byte)((RIBA & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public bool RIBA_5 { get => (RIBA & (1 << 5)) == 1 << 5; set => RIBA = (byte)((RIBA & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public bool RIBA_6 { get => (RIBA & (1 << 6)) == 1 << 6; set => RIBA = (byte)((RIBA & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public bool RIBA_7 { get => (RIBA & (1 << 7)) == 1 << 7; set => RIBA = (byte)((RIBA & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused + public bool RIBB_0 { get => (RIBB & (1 << 0)) == 1 << 0; set => RIBB = (byte)((RIBB & ~(1 << 0)) | (value ? 1 << 0 : 0)); } // Unused + public bool RIBB_1 { get => (RIBB & (1 << 1)) == 1 << 1; set => RIBB = (byte)((RIBB & ~(1 << 1)) | (value ? 1 << 1 : 0)); } // Unused + public bool RIBB_2 { get => (RIBB & (1 << 2)) == 1 << 2; set => RIBB = (byte)((RIBB & ~(1 << 2)) | (value ? 1 << 2 : 0)); } // Unused + public bool RIBB_3 { get => (RIBB & (1 << 3)) == 1 << 3; set => RIBB = (byte)((RIBB & ~(1 << 3)) | (value ? 1 << 3 : 0)); } // Unused + public bool RIBB_4 { get => (RIBB & (1 << 4)) == 1 << 4; set => RIBB = (byte)((RIBB & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public bool RIBB_5 { get => (RIBB & (1 << 5)) == 1 << 5; set => RIBB = (byte)((RIBB & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public bool RIBB_6 { get => (RIBB & (1 << 6)) == 1 << 6; set => RIBB = (byte)((RIBB & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public bool RIBB_7 { get => (RIBB & (1 << 7)) == 1 << 7; set => RIBB = (byte)((RIBB & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused // 0x64-0x67 Unused #endregion @@ -227,8 +229,8 @@ public PK5(byte[] decryptedData = null, string ident = null) public override int Egg_Location { get => BitConverter.ToUInt16(Data, 0x7E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x7E); } public override int Met_Location { get => BitConverter.ToUInt16(Data, 0x80); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x80); } private byte PKRS { get => Data[0x82]; set => Data[0x82] = value; } - public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)(PKRS & ~0xF | value); } - public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)(PKRS & 0xF | (value << 4)); } + public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)((PKRS & ~0xF) | value); } + public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)((PKRS & 0xF) | (value << 4)); } public override int Ball { get => Data[0x83]; set => Data[0x83] = (byte)value; } public override int Met_Level { get => Data[0x84] & ~0x80; set => Data[0x84] = (byte)((Data[0x84] & 0x80) | value); } public override int OT_Gender { get => Data[0x84] >> 7; set => Data[0x84] = (byte)((Data[0x84] & ~0x80) | value << 7); } @@ -247,8 +249,9 @@ public PK5(byte[] decryptedData = null, string ident = null) public byte[] HeldMailData { get => Data.Skip(0x9C).Take(0x38).ToArray(); set => value.CopyTo(Data, 0x9C); } // Generated Attributes - public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 3); + public override int PSV => (int)((PID >> 16 ^ (PID & 0xFFFF)) >> 3); public override int TSV => (TID ^ SID) >> 3; + public override int Characteristic { get @@ -264,7 +267,7 @@ public override int Characteristic if (IVs[pm6stat] == maxIV) break; // P%6 is this stat } - return pm6stat * 5 + maxIV % 5; + return (pm6stat * 5) + (maxIV % 5); } } diff --git a/PKHeX.Core/PKM/PK6.cs b/PKHeX.Core/PKM/PK6.cs index 9112979e1..fe486eb73 100644 --- a/PKHeX.Core/PKM/PK6.cs +++ b/PKHeX.Core/PKM/PK6.cs @@ -11,6 +11,7 @@ public sealed class PK6 : PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCom 0x36, 0x37, // Unused Ribbons 0x58, 0x59, 0x73, 0x90, 0x91, 0x9E, 0x9F, 0xA0, 0xA1, 0xA7, 0xAA, 0xAB, 0xAC, 0xAD, 0xC8, 0xC9, 0xD7, 0xE4, 0xE5, 0xE6, 0xE7 }; + public override int SIZE_PARTY => PKX.SIZE_6PARTY; public override int SIZE_STORED => PKX.SIZE_6STORED; public override int Format => 6; @@ -24,6 +25,7 @@ public PK6(byte[] decryptedData = null, string ident = null) if (Data.Length != SIZE_PARTY) Array.Resize(ref Data, SIZE_PARTY); } + public override PKM Clone() => new PK6((byte[])Data.Clone(), Identifier); private string GetString(int Offset, int Count) => StringConverter.GetString6(Data, Offset, Count); @@ -41,54 +43,64 @@ public override uint EncryptionConstant get => BitConverter.ToUInt32(Data, 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, 0x00); } + public override ushort Sanity { get => BitConverter.ToUInt16(Data, 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, 0x04); } + public override ushort Checksum { get => BitConverter.ToUInt16(Data, 0x06); set => BitConverter.GetBytes(value).CopyTo(Data, 0x06); } + public override int Species { get => BitConverter.ToUInt16(Data, 0x08); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x08); } + public override int HeldItem { get => BitConverter.ToUInt16(Data, 0x0A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0A); } + public override int TID { get => BitConverter.ToUInt16(Data, 0x0C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0C); } + public override int SID { get => BitConverter.ToUInt16(Data, 0x0E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0E); } + public override uint EXP { get => BitConverter.ToUInt32(Data, 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, 0x10); } + public override int Ability { get => Data[0x14]; set => Data[0x14] = (byte)value; } public override int AbilityNumber { get => Data[0x15]; set => Data[0x15] = (byte)value; } public int TrainingBagHits { get => Data[0x16]; set => Data[0x16] = (byte)value; } public int TrainingBag { get => Data[0x17]; set => Data[0x17] = (byte)value; } + public override uint PID { get => BitConverter.ToUInt32(Data, 0x18); set => BitConverter.GetBytes(value).CopyTo(Data, 0x18); } + public override int Nature { get => Data[0x1C]; set => Data[0x1C] = (byte)value; } - public override bool FatefulEncounter { get => (Data[0x1D] & 1) == 1; set => Data[0x1D] = (byte)(Data[0x1D] & ~0x01 | (value ? 1 : 0)); } - public override int Gender { get => (Data[0x1D] >> 1) & 0x3; set => Data[0x1D] = (byte)(Data[0x1D] & ~0x06 | (value << 1)); } - public override int AltForm { get => Data[0x1D] >> 3; set => Data[0x1D] = (byte)(Data[0x1D] & 0x07 | (value << 3)); } + public override bool FatefulEncounter { get => (Data[0x1D] & 1) == 1; set => Data[0x1D] = (byte)((Data[0x1D] & ~0x01) | (value ? 1 : 0)); } + public override int Gender { get => (Data[0x1D] >> 1) & 0x3; set => Data[0x1D] = (byte)((Data[0x1D] & ~0x06) | (value << 1)); } + public override int AltForm { get => Data[0x1D] >> 3; set => Data[0x1D] = (byte)((Data[0x1D] & 0x07) | (value << 3)); } public override int EV_HP { get => Data[0x1E]; set => Data[0x1E] = (byte)value; } public override int EV_ATK { get => Data[0x1F]; set => Data[0x1F] = (byte)value; } public override int EV_DEF { get => Data[0x20]; set => Data[0x20] = (byte)value; } @@ -103,44 +115,44 @@ public override uint PID public int CNT_Sheen { get => Data[0x29]; set => Data[0x29] = (byte)value; } public override int MarkValue { get => Data[0x2A]; protected set => Data[0x2A] = (byte)value; } private byte PKRS { get => Data[0x2B]; set => Data[0x2B] = value; } - public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)(PKRS & ~0xF | value); } - public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)(PKRS & 0xF | value << 4); } + public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)((PKRS & ~0xF) | value); } + public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)((PKRS & 0xF) | value << 4); } private byte ST1 { get => Data[0x2C]; set => Data[0x2C] = value; } - public bool Unused0 { get => (ST1 & (1 << 0)) == 1 << 0; set => ST1 = (byte)(ST1 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool Unused1 { get => (ST1 & (1 << 1)) == 1 << 1; set => ST1 = (byte)(ST1 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool SuperTrain1_SPA { get => (ST1 & (1 << 2)) == 1 << 2; set => ST1 = (byte)(ST1 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool SuperTrain1_HP { get => (ST1 & (1 << 3)) == 1 << 3; set => ST1 = (byte)(ST1 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool SuperTrain1_ATK { get => (ST1 & (1 << 4)) == 1 << 4; set => ST1 = (byte)(ST1 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool SuperTrain1_SPD { get => (ST1 & (1 << 5)) == 1 << 5; set => ST1 = (byte)(ST1 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool SuperTrain1_SPE { get => (ST1 & (1 << 6)) == 1 << 6; set => ST1 = (byte)(ST1 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool SuperTrain1_DEF { get => (ST1 & (1 << 7)) == 1 << 7; set => ST1 = (byte)(ST1 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool Unused0 { get => (ST1 & (1 << 0)) == 1 << 0; set => ST1 = (byte)((ST1 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool Unused1 { get => (ST1 & (1 << 1)) == 1 << 1; set => ST1 = (byte)((ST1 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool SuperTrain1_SPA { get => (ST1 & (1 << 2)) == 1 << 2; set => ST1 = (byte)((ST1 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool SuperTrain1_HP { get => (ST1 & (1 << 3)) == 1 << 3; set => ST1 = (byte)((ST1 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool SuperTrain1_ATK { get => (ST1 & (1 << 4)) == 1 << 4; set => ST1 = (byte)((ST1 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool SuperTrain1_SPD { get => (ST1 & (1 << 5)) == 1 << 5; set => ST1 = (byte)((ST1 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool SuperTrain1_SPE { get => (ST1 & (1 << 6)) == 1 << 6; set => ST1 = (byte)((ST1 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool SuperTrain1_DEF { get => (ST1 & (1 << 7)) == 1 << 7; set => ST1 = (byte)((ST1 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } private byte ST2 { get => Data[0x2D]; set => Data[0x2D] = value; } - public bool SuperTrain2_SPA { get => (ST2 & (1 << 0)) == 1 << 0; set => ST2 = (byte)(ST2 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool SuperTrain2_HP { get => (ST2 & (1 << 1)) == 1 << 1; set => ST2 = (byte)(ST2 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool SuperTrain2_ATK { get => (ST2 & (1 << 2)) == 1 << 2; set => ST2 = (byte)(ST2 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool SuperTrain2_SPD { get => (ST2 & (1 << 3)) == 1 << 3; set => ST2 = (byte)(ST2 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool SuperTrain2_SPE { get => (ST2 & (1 << 4)) == 1 << 4; set => ST2 = (byte)(ST2 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool SuperTrain2_DEF { get => (ST2 & (1 << 5)) == 1 << 5; set => ST2 = (byte)(ST2 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool SuperTrain3_SPA { get => (ST2 & (1 << 6)) == 1 << 6; set => ST2 = (byte)(ST2 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool SuperTrain3_HP { get => (ST2 & (1 << 7)) == 1 << 7; set => ST2 = (byte)(ST2 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool SuperTrain2_SPA { get => (ST2 & (1 << 0)) == 1 << 0; set => ST2 = (byte)((ST2 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool SuperTrain2_HP { get => (ST2 & (1 << 1)) == 1 << 1; set => ST2 = (byte)((ST2 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool SuperTrain2_ATK { get => (ST2 & (1 << 2)) == 1 << 2; set => ST2 = (byte)((ST2 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool SuperTrain2_SPD { get => (ST2 & (1 << 3)) == 1 << 3; set => ST2 = (byte)((ST2 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool SuperTrain2_SPE { get => (ST2 & (1 << 4)) == 1 << 4; set => ST2 = (byte)((ST2 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool SuperTrain2_DEF { get => (ST2 & (1 << 5)) == 1 << 5; set => ST2 = (byte)((ST2 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool SuperTrain3_SPA { get => (ST2 & (1 << 6)) == 1 << 6; set => ST2 = (byte)((ST2 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool SuperTrain3_HP { get => (ST2 & (1 << 7)) == 1 << 7; set => ST2 = (byte)((ST2 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } private byte ST3 { get => Data[0x2E]; set => Data[0x2E] = value; } - public bool SuperTrain3_ATK { get => (ST3 & (1 << 0)) == 1 << 0; set => ST3 = (byte)(ST3 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool SuperTrain3_SPD { get => (ST3 & (1 << 1)) == 1 << 1; set => ST3 = (byte)(ST3 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool SuperTrain3_SPE { get => (ST3 & (1 << 2)) == 1 << 2; set => ST3 = (byte)(ST3 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool SuperTrain3_DEF { get => (ST3 & (1 << 3)) == 1 << 3; set => ST3 = (byte)(ST3 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool SuperTrain4_1 { get => (ST3 & (1 << 4)) == 1 << 4; set => ST3 = (byte)(ST3 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool SuperTrain5_1 { get => (ST3 & (1 << 5)) == 1 << 5; set => ST3 = (byte)(ST3 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool SuperTrain5_2 { get => (ST3 & (1 << 6)) == 1 << 6; set => ST3 = (byte)(ST3 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool SuperTrain5_3 { get => (ST3 & (1 << 7)) == 1 << 7; set => ST3 = (byte)(ST3 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool SuperTrain3_ATK { get => (ST3 & (1 << 0)) == 1 << 0; set => ST3 = (byte)((ST3 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool SuperTrain3_SPD { get => (ST3 & (1 << 1)) == 1 << 1; set => ST3 = (byte)((ST3 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool SuperTrain3_SPE { get => (ST3 & (1 << 2)) == 1 << 2; set => ST3 = (byte)((ST3 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool SuperTrain3_DEF { get => (ST3 & (1 << 3)) == 1 << 3; set => ST3 = (byte)((ST3 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool SuperTrain4_1 { get => (ST3 & (1 << 4)) == 1 << 4; set => ST3 = (byte)((ST3 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool SuperTrain5_1 { get => (ST3 & (1 << 5)) == 1 << 5; set => ST3 = (byte)((ST3 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool SuperTrain5_2 { get => (ST3 & (1 << 6)) == 1 << 6; set => ST3 = (byte)((ST3 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool SuperTrain5_3 { get => (ST3 & (1 << 7)) == 1 << 7; set => ST3 = (byte)((ST3 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } private byte ST4 { get => Data[0x2F]; set => Data[0x2F] = value; } - public bool SuperTrain5_4 { get => (ST4 & (1 << 0)) == 1 << 0; set => ST4 = (byte)(ST4 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool SuperTrain6_1 { get => (ST4 & (1 << 1)) == 1 << 1; set => ST4 = (byte)(ST4 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool SuperTrain6_2 { get => (ST4 & (1 << 2)) == 1 << 2; set => ST4 = (byte)(ST4 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool SuperTrain6_3 { get => (ST4 & (1 << 3)) == 1 << 3; set => ST4 = (byte)(ST4 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool SuperTrain7_1 { get => (ST4 & (1 << 4)) == 1 << 4; set => ST4 = (byte)(ST4 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool SuperTrain7_2 { get => (ST4 & (1 << 5)) == 1 << 5; set => ST4 = (byte)(ST4 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool SuperTrain7_3 { get => (ST4 & (1 << 6)) == 1 << 6; set => ST4 = (byte)(ST4 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool SuperTrain8_1 { get => (ST4 & (1 << 7)) == 1 << 7; set => ST4 = (byte)(ST4 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool SuperTrain5_4 { get => (ST4 & (1 << 0)) == 1 << 0; set => ST4 = (byte)((ST4 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool SuperTrain6_1 { get => (ST4 & (1 << 1)) == 1 << 1; set => ST4 = (byte)((ST4 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool SuperTrain6_2 { get => (ST4 & (1 << 2)) == 1 << 2; set => ST4 = (byte)((ST4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool SuperTrain6_3 { get => (ST4 & (1 << 3)) == 1 << 3; set => ST4 = (byte)((ST4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool SuperTrain7_1 { get => (ST4 & (1 << 4)) == 1 << 4; set => ST4 = (byte)((ST4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool SuperTrain7_2 { get => (ST4 & (1 << 5)) == 1 << 5; set => ST4 = (byte)((ST4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool SuperTrain7_3 { get => (ST4 & (1 << 6)) == 1 << 6; set => ST4 = (byte)((ST4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool SuperTrain8_1 { get => (ST4 & (1 << 7)) == 1 << 7; set => ST4 = (byte)((ST4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } private byte RIB0 { get => Data[0x30]; set => Data[0x30] = value; } // Ribbons are read as uints, but let's keep them per byte. private byte RIB1 { get => Data[0x31]; set => Data[0x31] = value; } private byte RIB2 { get => Data[0x32]; set => Data[0x32] = value; } @@ -149,89 +161,94 @@ public override uint PID private byte RIB5 { get => Data[0x35]; set => Data[0x35] = value; } private byte RIB6 { get => Data[0x36]; set => Data[0x36] = value; } // Unused private byte RIB7 { get => Data[0x37]; set => Data[0x37] = value; } // Unused - public bool RibbonChampionKalos { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)(RIB0 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)(RIB0 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonChampionSinnoh { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)(RIB0 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonBestFriends { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)(RIB0 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonTraining { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)(RIB0 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonBattlerSkillful { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)(RIB0 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonBattlerExpert { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)(RIB0 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonEffort { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)(RIB0 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonAlert { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)(RIB1 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonShock { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)(RIB1 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonDowncast { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)(RIB1 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonCareless { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)(RIB1 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonRelax { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)(RIB1 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonSnooze { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)(RIB1 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonSmile { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)(RIB1 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonGorgeous { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)(RIB1 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)(RIB2 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)(RIB2 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonArtist { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)(RIB2 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonFootprint { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)(RIB2 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonRecord { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)(RIB2 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonLegend { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)(RIB2 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonCountry { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)(RIB2 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonNational { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)(RIB2 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonEarth { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)(RIB3 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonWorld { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)(RIB3 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)(RIB3 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)(RIB3 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonEvent { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)(RIB3 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonBirthday { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)(RIB3 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonSpecial { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)(RIB3 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonSouvenir { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)(RIB3 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonWishing { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)(RIB4 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonChampionBattle { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)(RIB4 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonChampionRegional { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)(RIB4 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonChampionNational { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)(RIB4 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonChampionWorld { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)(RIB4 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RIB4_5 { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)(RIB4 & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public bool RIB4_6 { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)(RIB4 & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public bool RibbonChampionG6Hoenn { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)(RIB4 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonContestStar { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)(RIB5 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonMasterCoolness { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)(RIB5 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonMasterBeauty { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)(RIB5 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonMasterCuteness { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)(RIB5 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonMasterCleverness { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)(RIB5 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonMasterToughness { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)(RIB5 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RIB5_6 { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)(RIB5 & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public bool RIB5_7 { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)(RIB5 & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused + public bool RibbonChampionKalos { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)((RIB0 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)((RIB0 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonChampionSinnoh { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)((RIB0 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonBestFriends { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)((RIB0 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonTraining { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)((RIB0 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonBattlerSkillful { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)((RIB0 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonBattlerExpert { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)((RIB0 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonEffort { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)((RIB0 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonAlert { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)((RIB1 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonShock { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)((RIB1 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonDowncast { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)((RIB1 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonCareless { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)((RIB1 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonRelax { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)((RIB1 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonSnooze { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)((RIB1 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonSmile { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)((RIB1 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonGorgeous { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)((RIB1 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)((RIB2 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)((RIB2 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonArtist { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)((RIB2 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonFootprint { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)((RIB2 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonRecord { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)((RIB2 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonLegend { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)((RIB2 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonCountry { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)((RIB2 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonNational { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)((RIB2 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonEarth { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)((RIB3 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonWorld { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)((RIB3 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)((RIB3 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)((RIB3 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonEvent { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)((RIB3 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonBirthday { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)((RIB3 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonSpecial { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)((RIB3 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonSouvenir { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)((RIB3 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonWishing { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)((RIB4 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonChampionBattle { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)((RIB4 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonChampionRegional { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)((RIB4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonChampionNational { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)((RIB4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonChampionWorld { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)((RIB4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RIB4_5 { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public bool RIB4_6 { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public bool RibbonChampionG6Hoenn { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)((RIB4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonContestStar { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)((RIB5 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonMasterCoolness { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)((RIB5 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonMasterBeauty { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)((RIB5 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonMasterCuteness { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)((RIB5 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonMasterCleverness { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)((RIB5 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonMasterToughness { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)((RIB5 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RIB5_6 { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)((RIB5 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public bool RIB5_7 { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)((RIB5 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused public int RibbonCountMemoryContest { get => Data[0x38]; set => Data[0x38] = (byte)value; } public int RibbonCountMemoryBattle { get => Data[0x39]; set => Data[0x39] = (byte)value; } private ushort DistByte { get => BitConverter.ToUInt16(Data, 0x3A); set => BitConverter.GetBytes(value).CopyTo(Data, 0x3A); } - public bool DistSuperTrain1 { get => (DistByte & (1 << 0)) == 1 << 0; set => DistByte = (byte)(DistByte & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool DistSuperTrain2 { get => (DistByte & (1 << 1)) == 1 << 1; set => DistByte = (byte)(DistByte & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool DistSuperTrain3 { get => (DistByte & (1 << 2)) == 1 << 2; set => DistByte = (byte)(DistByte & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool DistSuperTrain4 { get => (DistByte & (1 << 3)) == 1 << 3; set => DistByte = (byte)(DistByte & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool DistSuperTrain5 { get => (DistByte & (1 << 4)) == 1 << 4; set => DistByte = (byte)(DistByte & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool DistSuperTrain6 { get => (DistByte & (1 << 5)) == 1 << 5; set => DistByte = (byte)(DistByte & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool Dist7 { get => (DistByte & (1 << 6)) == 1 << 6; set => DistByte = (byte)(DistByte & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool Dist8 { get => (DistByte & (1 << 7)) == 1 << 7; set => DistByte = (byte)(DistByte & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool DistSuperTrain1 { get => (DistByte & (1 << 0)) == 1 << 0; set => DistByte = (byte)((DistByte & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool DistSuperTrain2 { get => (DistByte & (1 << 1)) == 1 << 1; set => DistByte = (byte)((DistByte & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool DistSuperTrain3 { get => (DistByte & (1 << 2)) == 1 << 2; set => DistByte = (byte)((DistByte & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool DistSuperTrain4 { get => (DistByte & (1 << 3)) == 1 << 3; set => DistByte = (byte)((DistByte & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool DistSuperTrain5 { get => (DistByte & (1 << 4)) == 1 << 4; set => DistByte = (byte)((DistByte & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool DistSuperTrain6 { get => (DistByte & (1 << 5)) == 1 << 5; set => DistByte = (byte)((DistByte & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool Dist7 { get => (DistByte & (1 << 6)) == 1 << 6; set => DistByte = (byte)((DistByte & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool Dist8 { get => (DistByte & (1 << 7)) == 1 << 7; set => DistByte = (byte)((DistByte & ~(1 << 7)) | (value ? 1 << 7 : 0)); } public uint FormDuration { get => BitConverter.ToUInt32(Data, 0x3C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x3C); } #endregion #region Block B public override string Nickname { get => GetString(0x40, 24); set => SetString(value, 12).CopyTo(Data, 0x40); } + public override int Move1 { get => BitConverter.ToUInt16(Data, 0x5A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5A); } + public override int Move2 { get => BitConverter.ToUInt16(Data, 0x5C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5C); } + public override int Move3 { get => BitConverter.ToUInt16(Data, 0x5E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5E); } + public override int Move4 { get => BitConverter.ToUInt16(Data, 0x60); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x60); } + public override int Move1_PP { get => Data[0x62]; set => Data[0x62] = (byte)value; } public override int Move2_PP { get => Data[0x63]; set => Data[0x63] = (byte)value; } public override int Move3_PP { get => Data[0x64]; set => Data[0x64] = (byte)value; } @@ -240,26 +257,31 @@ public override int Move4 public override int Move2_PPUps { get => Data[0x67]; set => Data[0x67] = (byte)value; } public override int Move3_PPUps { get => Data[0x68]; set => Data[0x68] = (byte)value; } public override int Move4_PPUps { get => Data[0x69]; set => Data[0x69] = (byte)value; } + public override int RelearnMove1 { get => BitConverter.ToUInt16(Data, 0x6A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x6A); } + public override int RelearnMove2 { get => BitConverter.ToUInt16(Data, 0x6C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x6C); } + public override int RelearnMove3 { get => BitConverter.ToUInt16(Data, 0x6E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x6E); } + public override int RelearnMove4 { get => BitConverter.ToUInt16(Data, 0x70); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x70); } + public override bool SecretSuperTrainingUnlocked { get => (Data[0x72] & 1) == 1; set => Data[0x72] = (byte)((Data[0x72] & ~1) | (value ? 1 : 0)); } public override bool SecretSuperTrainingComplete { get => (Data[0x72] & 2) == 2; set => Data[0x72] = (byte)((Data[0x72] & ~2) | (value ? 2 : 0)); } public byte _0x73 { get => Data[0x73]; set => Data[0x73] = value; } @@ -349,11 +371,13 @@ public override int CurrentFriendship get => CurrentHandler == 0 ? OT_Friendship : HT_Friendship; set { if (CurrentHandler == 0) OT_Friendship = value; else HT_Friendship = value; } } + public int OppositeFriendship { get => CurrentHandler == 1 ? OT_Friendship : HT_Friendship; set { if (CurrentHandler == 1) OT_Friendship = value; else HT_Friendship = value; } } + public override int SuperTrainingMedalCount(int maxCount = 30) { uint value = BitConverter.ToUInt32(Data, 0x2C); @@ -369,7 +393,7 @@ public override int SuperTrainingMedalCount(int maxCount = 30) return TrainCount; } - public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 4); + public override int PSV => (int)((PID >> 16 ^ (PID & 0xFFFF)) >> 4); public override int TSV => (TID ^ SID) >> 4; public bool IsUntradedEvent6 => Geo1_Country == 0 && Geo1_Region == 0 && Met_Location / 10000 == 4 && Gen6; public override bool IsUntraded => Data[0x78] == 0 && Data[0x78 + 1] == 0 && Format == GenNumber; // immediately terminated HT_Name data (\0) @@ -388,7 +412,7 @@ public override int Characteristic for (int i = 0; i < 6; i++) if (IVs[pm6stat = pm6++ % 6] == maxIV) break; - return pm6stat*5 + maxIV%5; + return (pm6stat * 5) + (maxIV % 5); } } @@ -424,6 +448,7 @@ public void FixRelearn() break; } } + public void FixMemories() { if (IsEgg) // No memories if is egg. @@ -456,6 +481,7 @@ public void Trade(string SAV_Trainer, int SAV_TID, int SAV_SID, int SAV_COUNTRY, else if (!TradeOT(SAV_Trainer, SAV_TID, SAV_SID, SAV_COUNTRY, SAV_REGION, SAV_GENDER)) TradeHT(SAV_Trainer, SAV_COUNTRY, SAV_REGION, SAV_GENDER, Bank); } + private bool TradeOT(string SAV_Trainer, int SAV_TID, int SAV_SID, int SAV_COUNTRY, int SAV_REGION, int SAV_GENDER) { // Check to see if the OT matches the SAV's OT info. @@ -468,6 +494,7 @@ private bool TradeOT(string SAV_Trainer, int SAV_TID, int SAV_SID, int SAV_COUNT return true; } + private void TradeHT(string SAV_Trainer, int SAV_COUNTRY, int SAV_REGION, int SAV_GENDER, bool Bank) { if (SAV_Trainer != HT_Name || SAV_GENDER != HT_Gender || (Geo1_Country == 0 && Geo1_Region == 0 && !IsUntradedEvent6)) @@ -497,7 +524,7 @@ public void TradeMemory(bool Bank) // Legality Properties public override bool WasLink => Met_Location == 30011; - public override bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter; + public override bool WasEvent => (Met_Location > 40000 && Met_Location < 50000) || FatefulEncounter; public override bool WasEventEgg => GenNumber < 5 ? base.WasEventEgg : ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1; // Maximums diff --git a/PKHeX.Core/PKM/PK7.cs b/PKHeX.Core/PKM/PK7.cs index 4988278b4..e05d3a144 100644 --- a/PKHeX.Core/PKM/PK7.cs +++ b/PKHeX.Core/PKM/PK7.cs @@ -12,6 +12,7 @@ public sealed class PK7 : PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCom // 0x36, 0x37, // Unused Ribbons 0x58, 0x59, 0x73, 0x90, 0x91, 0x9E, 0x9F, 0xA0, 0xA1, 0xA7, 0xAA, 0xAB, 0xAC, 0xAD, 0xC8, 0xC9, 0xD7, 0xE4, 0xE5, 0xE6, 0xE7 }; + public override int SIZE_PARTY => PKX.SIZE_6PARTY; public override int SIZE_STORED => PKX.SIZE_6STORED; public override int Format => 7; @@ -25,6 +26,7 @@ public PK7(byte[] decryptedData = null, string ident = null) if (Data.Length != SIZE_PARTY) Array.Resize(ref Data, SIZE_PARTY); } + public override PKM Clone() => new PK7((byte[])Data.Clone(), Identifier); private string GetString(int Offset, int Count) => StringConverter.GetString7(Data, Offset, Count); @@ -42,53 +44,63 @@ public override uint EncryptionConstant get => BitConverter.ToUInt32(Data, 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, 0x00); } + public override ushort Sanity { get => BitConverter.ToUInt16(Data, 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, 0x04); } + public override ushort Checksum { get => BitConverter.ToUInt16(Data, 0x06); set => BitConverter.GetBytes(value).CopyTo(Data, 0x06); } + public override int Species { get => BitConverter.ToUInt16(Data, 0x08); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x08); } + public override int HeldItem { get => BitConverter.ToUInt16(Data, 0x0A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0A); } + public override int TID { get => BitConverter.ToUInt16(Data, 0x0C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0C); } + public override int SID { get => BitConverter.ToUInt16(Data, 0x0E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0E); } + public override uint EXP { get => BitConverter.ToUInt32(Data, 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, 0x10); } + public override int Ability { get => Data[0x14]; set => Data[0x14] = (byte)value; } - public override int AbilityNumber { get => Data[0x15] & 7; set => Data[0x15] = (byte)(Data[0x15] & ~7 | value & 7); } + public override int AbilityNumber { get => Data[0x15] & 7; set => Data[0x15] = (byte)((Data[0x15] & ~7) | (value & 7)); } public override int MarkValue { get => BitConverter.ToUInt16(Data, 0x16); protected set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x16); } + public override uint PID { get => BitConverter.ToUInt32(Data, 0x18); set => BitConverter.GetBytes(value).CopyTo(Data, 0x18); } + public override int Nature { get => Data[0x1C]; set => Data[0x1C] = (byte)value; } - public override bool FatefulEncounter { get => (Data[0x1D] & 1) == 1; set => Data[0x1D] = (byte)(Data[0x1D] & ~0x01 | (value ? 1 : 0)); } - public override int Gender { get => (Data[0x1D] >> 1) & 0x3; set => Data[0x1D] = (byte)(Data[0x1D] & ~0x06 | (value << 1)); } - public override int AltForm { get => Data[0x1D] >> 3; set => Data[0x1D] = (byte)(Data[0x1D] & 0x07 | (value << 3)); } + public override bool FatefulEncounter { get => (Data[0x1D] & 1) == 1; set => Data[0x1D] = (byte)((Data[0x1D] & ~0x01) | (value ? 1 : 0)); } + public override int Gender { get => (Data[0x1D] >> 1) & 0x3; set => Data[0x1D] = (byte)((Data[0x1D] & ~0x06) | (value << 1)); } + public override int AltForm { get => Data[0x1D] >> 3; set => Data[0x1D] = (byte)((Data[0x1D] & 0x07) | (value << 3)); } public override int EV_HP { get => Data[0x1E]; set => Data[0x1E] = (byte)value; } public override int EV_ATK { get => Data[0x1F]; set => Data[0x1F] = (byte)value; } public override int EV_DEF { get => Data[0x20]; set => Data[0x20] = (byte)value; } @@ -103,119 +115,119 @@ public override uint PID public int CNT_Sheen { get => Data[0x29]; set => Data[0x29] = (byte)value; } public byte ResortEventStatus { get => Data[0x2A]; set => Data[0x2A] = value; } private byte PKRS { get => Data[0x2B]; set => Data[0x2B] = value; } - public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)(PKRS & ~0xF | value); } - public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)(PKRS & 0xF | value << 4); } + public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)((PKRS & ~0xF) | value); } + public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)((PKRS & 0xF) | value << 4); } private byte ST1 { get => Data[0x2C]; set => Data[0x2C] = value; } - public bool Unused0 { get => (ST1 & (1 << 0)) == 1 << 0; set => ST1 = (byte)(ST1 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool Unused1 { get => (ST1 & (1 << 1)) == 1 << 1; set => ST1 = (byte)(ST1 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool SuperTrain1_SPA { get => (ST1 & (1 << 2)) == 1 << 2; set => ST1 = (byte)(ST1 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool SuperTrain1_HP { get => (ST1 & (1 << 3)) == 1 << 3; set => ST1 = (byte)(ST1 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool SuperTrain1_ATK { get => (ST1 & (1 << 4)) == 1 << 4; set => ST1 = (byte)(ST1 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool SuperTrain1_SPD { get => (ST1 & (1 << 5)) == 1 << 5; set => ST1 = (byte)(ST1 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool SuperTrain1_SPE { get => (ST1 & (1 << 6)) == 1 << 6; set => ST1 = (byte)(ST1 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool SuperTrain1_DEF { get => (ST1 & (1 << 7)) == 1 << 7; set => ST1 = (byte)(ST1 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool Unused0 { get => (ST1 & (1 << 0)) == 1 << 0; set => ST1 = (byte)((ST1 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool Unused1 { get => (ST1 & (1 << 1)) == 1 << 1; set => ST1 = (byte)((ST1 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool SuperTrain1_SPA { get => (ST1 & (1 << 2)) == 1 << 2; set => ST1 = (byte)((ST1 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool SuperTrain1_HP { get => (ST1 & (1 << 3)) == 1 << 3; set => ST1 = (byte)((ST1 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool SuperTrain1_ATK { get => (ST1 & (1 << 4)) == 1 << 4; set => ST1 = (byte)((ST1 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool SuperTrain1_SPD { get => (ST1 & (1 << 5)) == 1 << 5; set => ST1 = (byte)((ST1 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool SuperTrain1_SPE { get => (ST1 & (1 << 6)) == 1 << 6; set => ST1 = (byte)((ST1 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool SuperTrain1_DEF { get => (ST1 & (1 << 7)) == 1 << 7; set => ST1 = (byte)((ST1 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } private byte ST2 { get => Data[0x2D]; set => Data[0x2D] = value; } - public bool SuperTrain2_SPA { get => (ST2 & (1 << 0)) == 1 << 0; set => ST2 = (byte)(ST2 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool SuperTrain2_HP { get => (ST2 & (1 << 1)) == 1 << 1; set => ST2 = (byte)(ST2 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool SuperTrain2_ATK { get => (ST2 & (1 << 2)) == 1 << 2; set => ST2 = (byte)(ST2 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool SuperTrain2_SPD { get => (ST2 & (1 << 3)) == 1 << 3; set => ST2 = (byte)(ST2 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool SuperTrain2_SPE { get => (ST2 & (1 << 4)) == 1 << 4; set => ST2 = (byte)(ST2 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool SuperTrain2_DEF { get => (ST2 & (1 << 5)) == 1 << 5; set => ST2 = (byte)(ST2 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool SuperTrain3_SPA { get => (ST2 & (1 << 6)) == 1 << 6; set => ST2 = (byte)(ST2 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool SuperTrain3_HP { get => (ST2 & (1 << 7)) == 1 << 7; set => ST2 = (byte)(ST2 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool SuperTrain2_SPA { get => (ST2 & (1 << 0)) == 1 << 0; set => ST2 = (byte)((ST2 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool SuperTrain2_HP { get => (ST2 & (1 << 1)) == 1 << 1; set => ST2 = (byte)((ST2 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool SuperTrain2_ATK { get => (ST2 & (1 << 2)) == 1 << 2; set => ST2 = (byte)((ST2 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool SuperTrain2_SPD { get => (ST2 & (1 << 3)) == 1 << 3; set => ST2 = (byte)((ST2 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool SuperTrain2_SPE { get => (ST2 & (1 << 4)) == 1 << 4; set => ST2 = (byte)((ST2 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool SuperTrain2_DEF { get => (ST2 & (1 << 5)) == 1 << 5; set => ST2 = (byte)((ST2 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool SuperTrain3_SPA { get => (ST2 & (1 << 6)) == 1 << 6; set => ST2 = (byte)((ST2 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool SuperTrain3_HP { get => (ST2 & (1 << 7)) == 1 << 7; set => ST2 = (byte)((ST2 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } private byte ST3 { get => Data[0x2E]; set => Data[0x2E] = value; } - public bool SuperTrain3_ATK { get => (ST3 & (1 << 0)) == 1 << 0; set => ST3 = (byte)(ST3 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool SuperTrain3_SPD { get => (ST3 & (1 << 1)) == 1 << 1; set => ST3 = (byte)(ST3 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool SuperTrain3_SPE { get => (ST3 & (1 << 2)) == 1 << 2; set => ST3 = (byte)(ST3 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool SuperTrain3_DEF { get => (ST3 & (1 << 3)) == 1 << 3; set => ST3 = (byte)(ST3 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool SuperTrain4_1 { get => (ST3 & (1 << 4)) == 1 << 4; set => ST3 = (byte)(ST3 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool SuperTrain5_1 { get => (ST3 & (1 << 5)) == 1 << 5; set => ST3 = (byte)(ST3 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool SuperTrain5_2 { get => (ST3 & (1 << 6)) == 1 << 6; set => ST3 = (byte)(ST3 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool SuperTrain5_3 { get => (ST3 & (1 << 7)) == 1 << 7; set => ST3 = (byte)(ST3 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool SuperTrain3_ATK { get => (ST3 & (1 << 0)) == 1 << 0; set => ST3 = (byte)((ST3 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool SuperTrain3_SPD { get => (ST3 & (1 << 1)) == 1 << 1; set => ST3 = (byte)((ST3 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool SuperTrain3_SPE { get => (ST3 & (1 << 2)) == 1 << 2; set => ST3 = (byte)((ST3 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool SuperTrain3_DEF { get => (ST3 & (1 << 3)) == 1 << 3; set => ST3 = (byte)((ST3 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool SuperTrain4_1 { get => (ST3 & (1 << 4)) == 1 << 4; set => ST3 = (byte)((ST3 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool SuperTrain5_1 { get => (ST3 & (1 << 5)) == 1 << 5; set => ST3 = (byte)((ST3 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool SuperTrain5_2 { get => (ST3 & (1 << 6)) == 1 << 6; set => ST3 = (byte)((ST3 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool SuperTrain5_3 { get => (ST3 & (1 << 7)) == 1 << 7; set => ST3 = (byte)((ST3 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } private byte ST4 { get => Data[0x2F]; set => Data[0x2F] = value; } - public bool SuperTrain5_4 { get => (ST4 & (1 << 0)) == 1 << 0; set => ST4 = (byte)(ST4 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool SuperTrain6_1 { get => (ST4 & (1 << 1)) == 1 << 1; set => ST4 = (byte)(ST4 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool SuperTrain6_2 { get => (ST4 & (1 << 2)) == 1 << 2; set => ST4 = (byte)(ST4 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool SuperTrain6_3 { get => (ST4 & (1 << 3)) == 1 << 3; set => ST4 = (byte)(ST4 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool SuperTrain7_1 { get => (ST4 & (1 << 4)) == 1 << 4; set => ST4 = (byte)(ST4 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool SuperTrain7_2 { get => (ST4 & (1 << 5)) == 1 << 5; set => ST4 = (byte)(ST4 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool SuperTrain7_3 { get => (ST4 & (1 << 6)) == 1 << 6; set => ST4 = (byte)(ST4 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool SuperTrain8_1 { get => (ST4 & (1 << 7)) == 1 << 7; set => ST4 = (byte)(ST4 & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool SuperTrain5_4 { get => (ST4 & (1 << 0)) == 1 << 0; set => ST4 = (byte)((ST4 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool SuperTrain6_1 { get => (ST4 & (1 << 1)) == 1 << 1; set => ST4 = (byte)((ST4 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool SuperTrain6_2 { get => (ST4 & (1 << 2)) == 1 << 2; set => ST4 = (byte)((ST4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool SuperTrain6_3 { get => (ST4 & (1 << 3)) == 1 << 3; set => ST4 = (byte)((ST4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool SuperTrain7_1 { get => (ST4 & (1 << 4)) == 1 << 4; set => ST4 = (byte)((ST4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool SuperTrain7_2 { get => (ST4 & (1 << 5)) == 1 << 5; set => ST4 = (byte)((ST4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool SuperTrain7_3 { get => (ST4 & (1 << 6)) == 1 << 6; set => ST4 = (byte)((ST4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool SuperTrain8_1 { get => (ST4 & (1 << 7)) == 1 << 7; set => ST4 = (byte)((ST4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } private byte RIB0 { get => Data[0x30]; set => Data[0x30] = value; } // Ribbons are read as uints, but let's keep them per byte. private byte RIB1 { get => Data[0x31]; set => Data[0x31] = value; } private byte RIB2 { get => Data[0x32]; set => Data[0x32] = value; } private byte RIB3 { get => Data[0x33]; set => Data[0x33] = value; } private byte RIB4 { get => Data[0x34]; set => Data[0x34] = value; } private byte RIB5 { get => Data[0x35]; set => Data[0x35] = value; } - private byte RIB6 { get => Data[0x36]; set => Data[0x36] = value; } // Unused - private byte RIB7 { get => Data[0x37]; set => Data[0x37] = value; } // Unused - public bool RibbonChampionKalos { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)(RIB0 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)(RIB0 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonChampionSinnoh { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)(RIB0 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonBestFriends { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)(RIB0 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonTraining { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)(RIB0 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonBattlerSkillful { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)(RIB0 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonBattlerExpert { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)(RIB0 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonEffort { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)(RIB0 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonAlert { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)(RIB1 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonShock { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)(RIB1 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonDowncast { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)(RIB1 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonCareless { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)(RIB1 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonRelax { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)(RIB1 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonSnooze { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)(RIB1 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonSmile { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)(RIB1 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonGorgeous { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)(RIB1 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)(RIB2 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)(RIB2 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonArtist { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)(RIB2 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonFootprint { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)(RIB2 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonRecord { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)(RIB2 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonLegend { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)(RIB2 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonCountry { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)(RIB2 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonNational { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)(RIB2 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonEarth { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)(RIB3 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonWorld { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)(RIB3 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)(RIB3 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)(RIB3 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonEvent { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)(RIB3 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonBirthday { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)(RIB3 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonSpecial { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)(RIB3 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonSouvenir { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)(RIB3 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonWishing { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)(RIB4 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonChampionBattle { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)(RIB4 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonChampionRegional { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)(RIB4 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonChampionNational { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)(RIB4 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonChampionWorld { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)(RIB4 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RIB4_5 { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)(RIB4 & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public bool RIB4_6 { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)(RIB4 & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public bool RibbonChampionG6Hoenn { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)(RIB4 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonContestStar { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)(RIB5 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonMasterCoolness { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)(RIB5 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RibbonMasterBeauty { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)(RIB5 & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool RibbonMasterCuteness { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)(RIB5 & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool RibbonMasterCleverness { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)(RIB5 & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool RibbonMasterToughness { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)(RIB5 & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool RibbonChampionAlola { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)(RIB5 & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool RibbonBattleRoyale { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)(RIB5 & ~(1 << 7) | (value ? 1 << 7 : 0)); } - public bool RibbonBattleTreeGreat { get => (RIB6 & (1 << 0)) == 1 << 0; set => RIB6 = (byte)(RIB6 & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool RibbonBattleTreeMaster { get => (RIB6 & (1 << 1)) == 1 << 1; set => RIB6 = (byte)(RIB6 & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool RIB6_2 { get => (RIB6 & (1 << 2)) == 1 << 2; set => RIB6 = (byte)(RIB6 & ~(1 << 2) | (value ? 1 << 2 : 0)); } // Unused - public bool RIB6_3 { get => (RIB6 & (1 << 3)) == 1 << 3; set => RIB6 = (byte)(RIB6 & ~(1 << 3) | (value ? 1 << 3 : 0)); } // Unused - public bool RIB6_4 { get => (RIB6 & (1 << 4)) == 1 << 4; set => RIB6 = (byte)(RIB6 & ~(1 << 4) | (value ? 1 << 4 : 0)); } // Unused - public bool RIB6_5 { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)(RIB6 & ~(1 << 5) | (value ? 1 << 5 : 0)); } // Unused - public bool RIB6_6 { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)(RIB6 & ~(1 << 6) | (value ? 1 << 6 : 0)); } // Unused - public bool RIB6_7 { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)(RIB6 & ~(1 << 7) | (value ? 1 << 7 : 0)); } // Unused + private byte RIB6 { get => Data[0x36]; set => Data[0x36] = value; } + //private byte RIB7 { get => Data[0x37]; set => Data[0x37] = value; } // Unused + public bool RibbonChampionKalos { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)((RIB0 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)((RIB0 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonChampionSinnoh { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)((RIB0 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonBestFriends { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)((RIB0 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonTraining { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)((RIB0 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonBattlerSkillful { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)((RIB0 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonBattlerExpert { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)((RIB0 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonEffort { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)((RIB0 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonAlert { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)((RIB1 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonShock { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)((RIB1 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonDowncast { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)((RIB1 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonCareless { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)((RIB1 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonRelax { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)((RIB1 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonSnooze { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)((RIB1 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonSmile { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)((RIB1 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonGorgeous { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)((RIB1 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)((RIB2 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)((RIB2 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonArtist { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)((RIB2 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonFootprint { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)((RIB2 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonRecord { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)((RIB2 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonLegend { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)((RIB2 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonCountry { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)((RIB2 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonNational { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)((RIB2 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonEarth { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)((RIB3 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonWorld { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)((RIB3 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)((RIB3 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)((RIB3 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonEvent { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)((RIB3 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonBirthday { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)((RIB3 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonSpecial { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)((RIB3 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonSouvenir { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)((RIB3 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonWishing { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)((RIB4 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonChampionBattle { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)((RIB4 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonChampionRegional { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)((RIB4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonChampionNational { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)((RIB4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonChampionWorld { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)((RIB4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RIB4_5 { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public bool RIB4_6 { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public bool RibbonChampionG6Hoenn { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)((RIB4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonContestStar { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)((RIB5 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonMasterCoolness { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)((RIB5 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RibbonMasterBeauty { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)((RIB5 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool RibbonMasterCuteness { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)((RIB5 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool RibbonMasterCleverness { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)((RIB5 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool RibbonMasterToughness { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)((RIB5 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool RibbonChampionAlola { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)((RIB5 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool RibbonBattleRoyale { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)((RIB5 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } + public bool RibbonBattleTreeGreat { get => (RIB6 & (1 << 0)) == 1 << 0; set => RIB6 = (byte)((RIB6 & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool RibbonBattleTreeMaster { get => (RIB6 & (1 << 1)) == 1 << 1; set => RIB6 = (byte)((RIB6 & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool RIB6_2 { get => (RIB6 & (1 << 2)) == 1 << 2; set => RIB6 = (byte)((RIB6 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } // Unused + public bool RIB6_3 { get => (RIB6 & (1 << 3)) == 1 << 3; set => RIB6 = (byte)((RIB6 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } // Unused + public bool RIB6_4 { get => (RIB6 & (1 << 4)) == 1 << 4; set => RIB6 = (byte)((RIB6 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused + public bool RIB6_5 { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)((RIB6 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused + public bool RIB6_6 { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)((RIB6 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused + public bool RIB6_7 { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)((RIB6 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused public int RibbonCountMemoryContest { get => Data[0x38]; set => Data[0x38] = (byte)value; } public int RibbonCountMemoryBattle { get => Data[0x39]; set => Data[0x39] = (byte)value; } private ushort DistByte { get => BitConverter.ToUInt16(Data, 0x3A); set => BitConverter.GetBytes(value).CopyTo(Data, 0x3A); } - public bool DistSuperTrain1 { get => (DistByte & (1 << 0)) == 1 << 0; set => DistByte = (byte)(DistByte & ~(1 << 0) | (value ? 1 << 0 : 0)); } - public bool DistSuperTrain2 { get => (DistByte & (1 << 1)) == 1 << 1; set => DistByte = (byte)(DistByte & ~(1 << 1) | (value ? 1 << 1 : 0)); } - public bool DistSuperTrain3 { get => (DistByte & (1 << 2)) == 1 << 2; set => DistByte = (byte)(DistByte & ~(1 << 2) | (value ? 1 << 2 : 0)); } - public bool DistSuperTrain4 { get => (DistByte & (1 << 3)) == 1 << 3; set => DistByte = (byte)(DistByte & ~(1 << 3) | (value ? 1 << 3 : 0)); } - public bool DistSuperTrain5 { get => (DistByte & (1 << 4)) == 1 << 4; set => DistByte = (byte)(DistByte & ~(1 << 4) | (value ? 1 << 4 : 0)); } - public bool DistSuperTrain6 { get => (DistByte & (1 << 5)) == 1 << 5; set => DistByte = (byte)(DistByte & ~(1 << 5) | (value ? 1 << 5 : 0)); } - public bool Dist7 { get => (DistByte & (1 << 6)) == 1 << 6; set => DistByte = (byte)(DistByte & ~(1 << 6) | (value ? 1 << 6 : 0)); } - public bool Dist8 { get => (DistByte & (1 << 7)) == 1 << 7; set => DistByte = (byte)(DistByte & ~(1 << 7) | (value ? 1 << 7 : 0)); } + public bool DistSuperTrain1 { get => (DistByte & (1 << 0)) == 1 << 0; set => DistByte = (byte)((DistByte & ~(1 << 0)) | (value ? 1 << 0 : 0)); } + public bool DistSuperTrain2 { get => (DistByte & (1 << 1)) == 1 << 1; set => DistByte = (byte)((DistByte & ~(1 << 1)) | (value ? 1 << 1 : 0)); } + public bool DistSuperTrain3 { get => (DistByte & (1 << 2)) == 1 << 2; set => DistByte = (byte)((DistByte & ~(1 << 2)) | (value ? 1 << 2 : 0)); } + public bool DistSuperTrain4 { get => (DistByte & (1 << 3)) == 1 << 3; set => DistByte = (byte)((DistByte & ~(1 << 3)) | (value ? 1 << 3 : 0)); } + public bool DistSuperTrain5 { get => (DistByte & (1 << 4)) == 1 << 4; set => DistByte = (byte)((DistByte & ~(1 << 4)) | (value ? 1 << 4 : 0)); } + public bool DistSuperTrain6 { get => (DistByte & (1 << 5)) == 1 << 5; set => DistByte = (byte)((DistByte & ~(1 << 5)) | (value ? 1 << 5 : 0)); } + public bool Dist7 { get => (DistByte & (1 << 6)) == 1 << 6; set => DistByte = (byte)((DistByte & ~(1 << 6)) | (value ? 1 << 6 : 0)); } + public bool Dist8 { get => (DistByte & (1 << 7)) == 1 << 7; set => DistByte = (byte)((DistByte & ~(1 << 7)) | (value ? 1 << 7 : 0)); } public uint FormDuration { get => BitConverter.ToUInt32(Data, 0x3C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x3C); } #endregion #region Block B @@ -242,21 +254,25 @@ public override int Move1 get => BitConverter.ToUInt16(Data, 0x5A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5A); } + public override int Move2 { get => BitConverter.ToUInt16(Data, 0x5C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5C); } + public override int Move3 { get => BitConverter.ToUInt16(Data, 0x5E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5E); } + public override int Move4 { get => BitConverter.ToUInt16(Data, 0x60); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x60); } + public override int Move1_PP { get => Data[0x62]; set => Data[0x62] = (byte)value; } public override int Move2_PP { get => Data[0x63]; set => Data[0x63] = (byte)value; } public override int Move3_PP { get => Data[0x64]; set => Data[0x64] = (byte)value; } @@ -265,26 +281,31 @@ public override int Move4 public override int Move2_PPUps { get => Data[0x67]; set => Data[0x67] = (byte)value; } public override int Move3_PPUps { get => Data[0x68]; set => Data[0x68] = (byte)value; } public override int Move4_PPUps { get => Data[0x69]; set => Data[0x69] = (byte)value; } + public override int RelearnMove1 { get => BitConverter.ToUInt16(Data, 0x6A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x6A); } + public override int RelearnMove2 { get => BitConverter.ToUInt16(Data, 0x6C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x6C); } + public override int RelearnMove3 { get => BitConverter.ToUInt16(Data, 0x6E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x6E); } + public override int RelearnMove4 { get => BitConverter.ToUInt16(Data, 0x70); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x70); } + public override bool SecretSuperTrainingUnlocked { get => (Data[0x72] & 1) == 1; set => Data[0x72] = (byte)((Data[0x72] & ~1) | (value ? 1 : 0)); } public override bool SecretSuperTrainingComplete { get => (Data[0x72] & 2) == 2; set => Data[0x72] = (byte)((Data[0x72] & ~2) | (value ? 2 : 0)); } public byte _0x73 { get => Data[0x73]; set => Data[0x73] = value; } @@ -384,11 +405,13 @@ public override int CurrentFriendship get => CurrentHandler == 0 ? OT_Friendship : HT_Friendship; set { if (CurrentHandler == 0) OT_Friendship = value; else HT_Friendship = value; } } + public int OppositeFriendship { get => CurrentHandler == 1 ? OT_Friendship : HT_Friendship; set { if (CurrentHandler == 1) OT_Friendship = value; else HT_Friendship = value; } } + public override int SuperTrainingMedalCount(int maxCount = 30) { uint value = BitConverter.ToUInt32(Data, 0x2C); @@ -404,7 +427,7 @@ public override int SuperTrainingMedalCount(int maxCount = 30) return TrainCount; } - public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 4); + public override int PSV => (int)((PID >> 16 ^ (PID & 0xFFFF)) >> 4); public override int TSV => (TID ^ SID) >> 4; public bool IsUntradedEvent6 => Geo1_Country == 0 && Geo1_Region == 0 && Met_Location / 10000 == 4 && Gen6; public override bool IsUntraded => Data[0x78] == 0 && Data[0x78 + 1] == 0 && Format == GenNumber; // immediately terminated HT_Name data (\0) @@ -420,9 +443,11 @@ public override int Characteristic int pm6stat = 0; for (int i = 0; i < 6; i++) + { if (IVs[pm6stat = pm6++ % 6] == maxIV) break; - return pm6stat*5 + maxIV%5; + } + return (pm6stat * 5) + (maxIV % 5); } } @@ -479,6 +504,7 @@ public void FixRelearn() break; } } + public void FixMemories() { if (IsEgg) // No memories if is egg. @@ -516,6 +542,7 @@ public void Trade(string SAV_Trainer, int SAV_TID, int SAV_SID, int SAV_COUNTRY, else if (!TradeOT(SAV_Trainer, SAV_TID, SAV_SID, SAV_COUNTRY, SAV_REGION, SAV_GENDER, Bank)) TradeHT(SAV_Trainer, SAV_COUNTRY, SAV_REGION, SAV_GENDER, Bank); } + private bool TradeOT(string SAV_Trainer, int SAV_TID, int SAV_SID, int SAV_COUNTRY, int SAV_REGION, int SAV_GENDER, bool Bank) { // Check to see if the OT matches the SAV's OT info. @@ -528,6 +555,7 @@ private bool TradeOT(string SAV_Trainer, int SAV_TID, int SAV_SID, int SAV_COUNT return true; } + private void TradeHT(string SAV_Trainer, int SAV_COUNTRY, int SAV_REGION, int SAV_GENDER, bool Bank) { if (SAV_Trainer != HT_Name || SAV_GENDER != HT_Gender || (Geo1_Country == 0 && Geo1_Region == 0 && !IsUntradedEvent6)) @@ -564,7 +592,7 @@ public void TradeMemory(bool Bank) // Legality Properties public override bool WasLink => Met_Location == 30011; - public override bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter; + public override bool WasEvent => (Met_Location > 40000 && Met_Location < 50000) || FatefulEncounter; public override bool WasEventEgg => GenNumber < 5 ? base.WasEventEgg : ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1; // Maximums diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs index 1376604aa..17a153119 100644 --- a/PKHeX.Core/PKM/PKM.cs +++ b/PKHeX.Core/PKM/PKM.cs @@ -30,6 +30,7 @@ public abstract class PKM : ITrainerID, ILangNick, IGameValueLimit public abstract byte[] Nickname_Trash { get; set; } public abstract byte[] OT_Trash { get; set; } public virtual byte[] HT_Trash { get; set; } + protected byte[] GetData(int Offset, int Length) { if (Offset + Length > Data.Length) @@ -55,8 +56,10 @@ protected virtual ushort CalculateChecksum() return chk; } } + protected abstract byte[] Encrypt(); public abstract int Format { get; } + private byte[] Write() { RefreshChecksum(); @@ -275,6 +278,7 @@ private byte[] Write() public virtual bool Locked { get => false; set { } } public int TrainerID7 { get => (int)((uint)(TID | (SID << 16)) % 1000000); set => SetID7(TrainerSID7, value); } public int TrainerSID7 { get => (int)((uint)(TID | (SID << 16)) / 1000000); set => SetID7(value, TrainerID7); } + private void SetID7(int sid7, int tid7) { var oid = (sid7 * 1_000_000) + (tid7 % 1_000_000); @@ -302,10 +306,11 @@ private void SetID7(int sid7, int tid7) public bool Gen6 => Version >= 24 && Version <= 29; public bool Gen5 => Version >= 20 && Version <= 23; public bool Gen4 => Version >= 7 && Version <= 12 && Version != 9; - public bool Gen3 => Version >= 1 && Version <= 5 || Version == 15; + public bool Gen3 => (Version >= 1 && Version <= 5) || Version == 15; public bool Gen2 => Version == (int)GameVersion.GSC; public bool Gen1 => Version == (int)GameVersion.RBY; public bool GenU => !(Gen7 || Gen6 || Gen5 || Gen4 || Gen3 || Gen2 || Gen1 || VC); + public int GenNumber { get @@ -322,6 +327,7 @@ public int GenNumber return -1; } } + public int DebutGeneration => Legal.GetDebutGeneration(Species); public bool PKRS_Infected => PKRS_Strain > 0; public bool PKRS_Cured => PKRS_Days == 0 && PKRS_Strain > 0; @@ -346,6 +352,7 @@ public virtual string FileName return $"{Species:000}{form}{star} - {Nickname} - {Checksum:X4}{EncryptionConstant:X8}.{Extension}"; } } + public int[] IVs { get => new[] { IV_HP, IV_ATK, IV_DEF, IV_SPE, IV_SPA, IV_SPD }; @@ -356,6 +363,7 @@ public int[] IVs IV_SPE = value[3]; IV_SPA = value[4]; IV_SPD = value[5]; } } + public int[] EVs { get => new[] { EV_HP, EV_ATK, EV_DEF, EV_SPE, EV_SPA, EV_SPD }; @@ -366,6 +374,7 @@ public int[] EVs EV_SPE = value[3]; EV_SPA = value[4]; EV_SPD = value[5]; } } + public int[] Moves { get => new[] { Move1, Move2, Move3, Move4 }; @@ -377,6 +386,7 @@ public int[] Moves Move4 = value.Length > 3 ? value[3] : 0; } } + public int[] RelearnMoves { get => new[] { RelearnMove1, RelearnMove2, RelearnMove3, RelearnMove4 }; @@ -388,6 +398,7 @@ public int[] RelearnMoves RelearnMove4 = value.Length > 3 ? value[3] : 0; } } + public int PIDAbility { get @@ -428,8 +439,10 @@ protected static int GetHiddenPowerBitVal(int[] ivs) sum |= (ivs[i] & 1) << i; return sum; } + private int HPVal => GetHiddenPowerBitVal(IVs); - public virtual int HPPower => Format < 6 ? 40*HPVal/63 + 30 : 60; + public virtual int HPPower => Format < 6 ? (40 *HPVal/63) + 30 : 60; + public virtual int HPType { get => 15 * HPVal / 63; @@ -450,6 +463,7 @@ public virtual int HPType public bool Gen2_NotTradeback => TradebackStatus == TradebackType.Gen2_NotTradeback; public virtual bool WasLink => false; private bool _WasEgg; + public bool WasEgg { get @@ -466,6 +480,7 @@ public bool WasEgg } set => _WasEgg = value; } + public bool WasBredEgg { get @@ -473,7 +488,7 @@ public bool WasBredEgg int loc = Egg_Location; switch (GenNumber) { - case 4: return loc == 02000 || loc == 02002 || loc == 03002 && PtHGSS; // faraway + case 4: return loc == 02000 || loc == 02002 || (loc == 03002 && PtHGSS); // faraway case 5: return loc == 60002 || loc == 30003; case 6: case 7: return loc == 60002 || loc == 30002; @@ -482,6 +497,7 @@ public bool WasBredEgg } set => _WasEgg = value; } + public virtual bool WasGiftEgg { get @@ -497,8 +513,10 @@ public virtual bool WasGiftEgg return false; } } - public virtual bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter; + + public virtual bool WasEvent => (Met_Location > 40000 && Met_Location < 50000) || FatefulEncounter; public virtual bool WasEventEgg => Gen4 ? WasEgg && Species == 490 : ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location > 0)) && Met_Level == 1; + public bool WasTradedEgg { get @@ -514,7 +532,8 @@ public bool WasTradedEgg } } } - public virtual bool WasIngameTrade => Met_Location == 30001 || Gen4 && Egg_Location == 2001; + + public virtual bool WasIngameTrade => Met_Location == 30001 || (Gen4 && Egg_Location == 2001); public virtual bool IsUntraded => false; public virtual bool IsNative => GenNumber == Format; public virtual bool IsOriginValid => Species <= Legal.GetMaxSpeciesOrigin(Format); @@ -564,7 +583,7 @@ public bool InhabitedGeneration(int Generation, int species = -1) case 4: return 3 <= gen && gen <= 4; case 5: return 3 <= gen && gen <= 5; case 6: return 3 <= gen && gen <= 6; - case 7: return 3 <= gen && gen <= 7 || VC; + case 7: return (3 <= gen && gen <= 7) || VC; default: return false; } @@ -574,7 +593,7 @@ public bool InhabitedGeneration(int Generation, int species = -1) /// Checks if the PKM has its original met location. /// /// Returns false if the Met Location has been overwritten via generational transfer. - public virtual bool HasOriginalMetLocation => !(Format < 3 || VC || GenNumber <= 4 && Format != GenNumber); + public virtual bool HasOriginalMetLocation => !(Format < 3 || VC || (GenNumber <= 4 && Format != GenNumber)); /// /// Checks if the current is valid. @@ -695,17 +714,19 @@ public virtual ushort[] GetStats(PersonalInfo p) PKX.ModifyStatsForNature(Stats, Nature); return Stats; } + private ushort[] GetStats(PersonalInfo p, IHyperTrain t, int level) { ushort[] Stats = new ushort[6]; - Stats[0] = (ushort)(p.HP == 1 ? 1 : ((t.HT_HP ? 31 : IV_HP) + 2 * p.HP + EV_HP / 4 + 100) * level / 100 + 10); - Stats[1] = (ushort)(((t.HT_ATK ? 31 : IV_ATK) + 2 * p.ATK + EV_ATK / 4) * level / 100 + 5); - Stats[2] = (ushort)(((t.HT_DEF ? 31 : IV_DEF) + 2 * p.DEF + EV_DEF / 4) * level / 100 + 5); - Stats[4] = (ushort)(((t.HT_SPA ? 31 : IV_SPA) + 2 * p.SPA + EV_SPA / 4) * level / 100 + 5); - Stats[5] = (ushort)(((t.HT_SPD ? 31 : IV_SPD) + 2 * p.SPD + EV_SPD / 4) * level / 100 + 5); - Stats[3] = (ushort)(((t.HT_SPE ? 31 : IV_SPE) + 2 * p.SPE + EV_SPE / 4) * level / 100 + 5); + Stats[0] = (ushort)(p.HP == 1 ? 1 : (((t.HT_HP ? 31 : IV_HP) + (2 * p.HP) + (EV_HP / 4) + 100) * level / 100) + 10); + Stats[1] = (ushort)((((t.HT_ATK ? 31 : IV_ATK) + (2 * p.ATK) + (EV_ATK / 4)) * level / 100) + 5); + Stats[2] = (ushort)((((t.HT_DEF ? 31 : IV_DEF) + (2 * p.DEF) + (EV_DEF / 4)) * level / 100) + 5); + Stats[4] = (ushort)((((t.HT_SPA ? 31 : IV_SPA) + (2 * p.SPA) + (EV_SPA / 4)) * level / 100) + 5); + Stats[5] = (ushort)((((t.HT_SPD ? 31 : IV_SPD) + (2 * p.SPD) + (EV_SPD / 4)) * level / 100) + 5); + Stats[3] = (ushort)((((t.HT_SPE ? 31 : IV_SPE) + (2 * p.SPE) + (EV_SPE / 4)) * level / 100) + 5); return Stats; } + private ushort[] GetStats(PersonalInfo p, int level) { ushort[] Stats = new ushort[6]; @@ -827,6 +848,7 @@ public void SetShinyPID() if (Format >= 6 && 3 <= GenNumber && GenNumber <= 5) EncryptionConstant = PID; } + /// /// Applies a shiny to the . /// @@ -836,6 +858,7 @@ public void SetShinySID() var xor = TID ^ (PID >> 16) ^ (PID & 0xFFFF); SID = (int)(xor & 0xFFF8) | Util.Rand.Next(8); } + /// /// Applies a to the according to the specified . /// @@ -849,6 +872,7 @@ public void SetPIDGender(int gender) if (Format >= 6 && 3 <= GenNumber && GenNumber <= 5) EncryptionConstant = PID; } + /// /// Applies a to the according to the specified . /// @@ -862,6 +886,7 @@ public void SetPIDNature(int nature) if (Format >= 6 && 3 <= GenNumber && GenNumber <= 5) EncryptionConstant = PID; } + /// /// Applies a to the according to the specified . /// diff --git a/PKHeX.Core/PKM/Shared/_K3.cs b/PKHeX.Core/PKM/Shared/_K3.cs index ca5386f65..4c076abe5 100644 --- a/PKHeX.Core/PKM/Shared/_K3.cs +++ b/PKHeX.Core/PKM/Shared/_K3.cs @@ -18,7 +18,7 @@ public abstract class _K3 : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSet public override int NickLength => 10; // Generated Attributes - public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 3); + public override int PSV => (int)((PID >> 16 ^ (PID & 0xFFFF)) >> 3); public override int TSV => (TID ^ SID) >> 3; public override bool Japanese => Language == (int)LanguageID.Japanese; public override bool WasEvent => Met_Location == 255; // Fateful diff --git a/PKHeX.Core/PKM/Shared/_K4.cs b/PKHeX.Core/PKM/Shared/_K4.cs index 5b6382f38..d68c5b16a 100644 --- a/PKHeX.Core/PKM/Shared/_K4.cs +++ b/PKHeX.Core/PKM/Shared/_K4.cs @@ -16,8 +16,9 @@ public abstract class _K4 : PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetU public override int OTLength => 7; public override int NickLength => 10; - public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 3); + public override int PSV => (int)((PID >> 16 ^ (PID & 0xFFFF)) >> 3); public override int TSV => (TID ^ SID) >> 3; + public override int Characteristic { get @@ -33,7 +34,7 @@ public override int Characteristic if (IVs[pm6stat] == maxIV) break; // P%6 is this stat } - return pm6stat * 5 + maxIV % 5; + return (pm6stat * 5) + (maxIV % 5); } } @@ -49,7 +50,7 @@ public override int Characteristic public override int AbilityNumber { get => 1 << PIDAbility; set { } } // Legality Extensions - public override bool WasEvent => Met_Location >= 3000 && Met_Location <= 3076 || FatefulEncounter; + public override bool WasEvent => (Met_Location >= 3000 && Met_Location <= 3076) || FatefulEncounter; public override bool WasIngameTrade => Met_Location == 2001; // Trade public override bool WasEventEgg => WasEgg && Species == 490; // Manaphy was the only generation 4 released event egg @@ -337,13 +338,13 @@ protected T ConvertTo() where T : _K4, new() // Transfer Trash Bytes for (int i = 0; i < 11; i++) // Nickname { - pk.Data[0x48 + 2*i] = Data[0x48 + 2*i + 1]; - pk.Data[0x48 + 2*i + 1] = Data[0x48 + 2*i]; + pk.Data[0x48 + (2 * i)] = Data[0x48 + (2 * i) + 1]; + pk.Data[0x48 + (2 * i) + 1] = Data[0x48 + (2 * i)]; } for (int i = 0; i < 8; i++) // OT_Name { - pk.Data[0x68 + 2*i] = Data[0x68 + 2*i + 1]; - pk.Data[0x68 + 2*i + 1] = Data[0x68 + 2*i]; + pk.Data[0x68 + (2 * i)] = Data[0x68 + (2 * i) + 1]; + pk.Data[0x68 + (2 * i) + 1] = Data[0x68 + (2 * i)]; } return pk; } diff --git a/PKHeX.Core/PKM/XK3.cs b/PKHeX.Core/PKM/XK3.cs index 51c7277f7..f839709e1 100644 --- a/PKHeX.Core/PKM/XK3.cs +++ b/PKHeX.Core/PKM/XK3.cs @@ -12,15 +12,18 @@ public sealed class XK3 : _K3, IShadowPKM 0x7A, 0x7B, 0x7E, 0x7F }; + public override int SIZE_PARTY => PKX.SIZE_3XSTORED; public override int SIZE_STORED => PKX.SIZE_3XSTORED; public override int Format => 3; public override PersonalInfo PersonalInfo => PersonalTable.RS[Species]; + public XK3(byte[] decryptedData = null, string ident = null) { Data = decryptedData ?? new byte[SIZE_PARTY]; Identifier = ident; } + public XK3() => Data = new byte[SIZE_PARTY]; public override PKM Clone() => new XK3((byte[])Data.Clone(), Identifier) {Purification = Purification}; @@ -54,14 +57,14 @@ public XK3(byte[] decryptedData = null, string ident = null) public override int PKRS_Days { get => Math.Max((sbyte)Data[0x15], (sbyte)0); set => Data[0x15] = (byte)(value == 0 ? 0xFF : value & 0xF); } // 0x16-0x1C Battle Related private int XDPKMFLAGS { get => Data[0x1D]; set => Data[0x1D] = (byte)value; } - public bool UnusedFlag0 { get => (XDPKMFLAGS & (1 << 0)) == 1 << 0; set => XDPKMFLAGS = XDPKMFLAGS & ~(1 << 0) | (value ? 1 << 0 : 0); } - public bool UnusedFlag1 { get => (XDPKMFLAGS & (1 << 1)) == 1 << 1; set => XDPKMFLAGS = XDPKMFLAGS & ~(1 << 1) | (value ? 1 << 1 : 0); } - public bool CapturedFlag { get => (XDPKMFLAGS & (1 << 2)) == 1 << 2; set => XDPKMFLAGS = XDPKMFLAGS & ~(1 << 2) | (value ? 1 << 2 : 0); } - public bool UnusedFlag3 { get => (XDPKMFLAGS & (1 << 3)) == 1 << 3; set => XDPKMFLAGS = XDPKMFLAGS & ~(1 << 3) | (value ? 1 << 3 : 0); } - public bool BlockTrades { get => (XDPKMFLAGS & (1 << 4)) == 1 << 4; set => XDPKMFLAGS = XDPKMFLAGS & ~(1 << 4) | (value ? 1 << 4 : 0); } - public override bool Valid { get => (XDPKMFLAGS & (1 << 5)) == 0; set => XDPKMFLAGS = XDPKMFLAGS & ~(1 << 5) | (value ? 0 : 1 << 5); } // invalid flag - public override bool AbilityBit { get => 1 << ((XDPKMFLAGS >> 6) & 1) == 1; set => XDPKMFLAGS = XDPKMFLAGS & ~(1 << 6) | ((value ? 1 : 0) << 6); } - public override bool IsEgg { get => (XDPKMFLAGS & (1 << 7)) == 1 << 7; set => XDPKMFLAGS = XDPKMFLAGS & ~(1 << 7) | (value ? 1 << 7 : 0); } + public bool UnusedFlag0 { get => (XDPKMFLAGS & (1 << 0)) == 1 << 0; set => XDPKMFLAGS = (XDPKMFLAGS & ~(1 << 0)) | (value ? 1 << 0 : 0); } + public bool UnusedFlag1 { get => (XDPKMFLAGS & (1 << 1)) == 1 << 1; set => XDPKMFLAGS = (XDPKMFLAGS & ~(1 << 1)) | (value ? 1 << 1 : 0); } + public bool CapturedFlag { get => (XDPKMFLAGS & (1 << 2)) == 1 << 2; set => XDPKMFLAGS = (XDPKMFLAGS & ~(1 << 2)) | (value ? 1 << 2 : 0); } + public bool UnusedFlag3 { get => (XDPKMFLAGS & (1 << 3)) == 1 << 3; set => XDPKMFLAGS = (XDPKMFLAGS & ~(1 << 3)) | (value ? 1 << 3 : 0); } + public bool BlockTrades { get => (XDPKMFLAGS & (1 << 4)) == 1 << 4; set => XDPKMFLAGS = (XDPKMFLAGS & ~(1 << 4)) | (value ? 1 << 4 : 0); } + public override bool Valid { get => (XDPKMFLAGS & (1 << 5)) == 0; set => XDPKMFLAGS = (XDPKMFLAGS & ~(1 << 5)) | (value ? 0 : 1 << 5); } // invalid flag + public override bool AbilityBit { get => 1 << ((XDPKMFLAGS >> 6) & 1) == 1; set => XDPKMFLAGS = (XDPKMFLAGS & ~(1 << 6)) | ((value ? 1 : 0) << 6); } + public override bool IsEgg { get => (XDPKMFLAGS & (1 << 7)) == 1 << 7; set => XDPKMFLAGS = (XDPKMFLAGS & ~(1 << 7)) | (value ? 1 << 7 : 0); } // 0x1E-0x1F Unknown public override uint EXP { get => BigEndian.ToUInt32(Data, 0x20); set => BigEndian.GetBytes(value).CopyTo(Data, 0x20); } public override int SID { get => BigEndian.ToUInt16(Data, 0x24); set => BigEndian.GetBytes((ushort)value).CopyTo(Data, 0x24); } @@ -81,22 +84,22 @@ public XK3(byte[] decryptedData = null, string ident = null) private string Nickname2 { get => GetString(0x64, 20); set => SetString(value, 10).CopyTo(Data, 0x64); } // +2 terminator // 0x7A-0x7B Unknown private ushort RIB0 { get => BigEndian.ToUInt16(Data, 0x7C); set => BigEndian.GetBytes(value).CopyTo(Data, 0x7C); } - public override bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 15)) == 1 << 15; set => RIB0 = (ushort)(RIB0 & ~(1 << 15) | (ushort)(value ? 1 << 15 : 0)); } - public override bool RibbonWinning { get => (RIB0 & (1 << 14)) == 1 << 14; set => RIB0 = (ushort)(RIB0 & ~(1 << 14) | (ushort)(value ? 1 << 14 : 0)); } - public override bool RibbonVictory { get => (RIB0 & (1 << 13)) == 1 << 13; set => RIB0 = (ushort)(RIB0 & ~(1 << 13) | (ushort)(value ? 1 << 13 : 0)); } - public override bool RibbonArtist { get => (RIB0 & (1 << 12)) == 1 << 12; set => RIB0 = (ushort)(RIB0 & ~(1 << 12) | (ushort)(value ? 1 << 12 : 0)); } - public override bool RibbonEffort { get => (RIB0 & (1 << 11)) == 1 << 11; set => RIB0 = (ushort)(RIB0 & ~(1 << 11) | (ushort)(value ? 1 << 11 : 0)); } - public override bool RibbonChampionBattle { get => (RIB0 & (1 << 10)) == 1 << 10; set => RIB0 = (ushort)(RIB0 & ~(1 << 10) | (ushort)(value ? 1 << 10 : 0)); } - public override bool RibbonChampionRegional { get => (RIB0 & (1 << 09)) == 1 << 09; set => RIB0 = (ushort)(RIB0 & ~(1 << 09) | (ushort)(value ? 1 << 09 : 0)); } - public override bool RibbonChampionNational { get => (RIB0 & (1 << 08)) == 1 << 08; set => RIB0 = (ushort)(RIB0 & ~(1 << 08) | (ushort)(value ? 1 << 08 : 0)); } - public override bool RibbonCountry { get => (RIB0 & (1 << 07)) == 1 << 07; set => RIB0 = (ushort)(RIB0 & ~(1 << 07) | (ushort)(value ? 1 << 07 : 0)); } - public override bool RibbonNational { get => (RIB0 & (1 << 06)) == 1 << 06; set => RIB0 = (ushort)(RIB0 & ~(1 << 06) | (ushort)(value ? 1 << 06 : 0)); } - public override bool RibbonEarth { get => (RIB0 & (1 << 05)) == 1 << 05; set => RIB0 = (ushort)(RIB0 & ~(1 << 05) | (ushort)(value ? 1 << 05 : 0)); } - public override bool RibbonWorld { get => (RIB0 & (1 << 04)) == 1 << 04; set => RIB0 = (ushort)(RIB0 & ~(1 << 04) | (ushort)(value ? 1 << 04 : 0)); } - public override bool Unused1 { get => (RIB0 & (1 << 03)) == 1 << 03; set => RIB0 = (ushort)(RIB0 & ~(1 << 03) | (ushort)(value ? 1 << 03 : 0)); } - public override bool Unused2 { get => (RIB0 & (1 << 02)) == 1 << 02; set => RIB0 = (ushort)(RIB0 & ~(1 << 02) | (ushort)(value ? 1 << 02 : 0)); } - public override bool Unused3 { get => (RIB0 & (1 << 01)) == 1 << 01; set => RIB0 = (ushort)(RIB0 & ~(1 << 01) | (ushort)(value ? 1 << 01 : 0)); } - public override bool Unused4 { get => (RIB0 & (1 << 00)) == 1 << 00; set => RIB0 = (ushort)(RIB0 & ~(1 << 00) | (ushort)(value ? 1 << 00 : 0)); } + public override bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 15)) == 1 << 15; set => RIB0 = (ushort)((RIB0 & ~(1 << 15)) | (ushort)(value ? 1 << 15 : 0)); } + public override bool RibbonWinning { get => (RIB0 & (1 << 14)) == 1 << 14; set => RIB0 = (ushort)((RIB0 & ~(1 << 14)) | (ushort)(value ? 1 << 14 : 0)); } + public override bool RibbonVictory { get => (RIB0 & (1 << 13)) == 1 << 13; set => RIB0 = (ushort)((RIB0 & ~(1 << 13)) | (ushort)(value ? 1 << 13 : 0)); } + public override bool RibbonArtist { get => (RIB0 & (1 << 12)) == 1 << 12; set => RIB0 = (ushort)((RIB0 & ~(1 << 12)) | (ushort)(value ? 1 << 12 : 0)); } + public override bool RibbonEffort { get => (RIB0 & (1 << 11)) == 1 << 11; set => RIB0 = (ushort)((RIB0 & ~(1 << 11)) | (ushort)(value ? 1 << 11 : 0)); } + public override bool RibbonChampionBattle { get => (RIB0 & (1 << 10)) == 1 << 10; set => RIB0 = (ushort)((RIB0 & ~(1 << 10)) | (ushort)(value ? 1 << 10 : 0)); } + public override bool RibbonChampionRegional { get => (RIB0 & (1 << 09)) == 1 << 09; set => RIB0 = (ushort)((RIB0 & ~(1 << 09)) | (ushort)(value ? 1 << 09 : 0)); } + public override bool RibbonChampionNational { get => (RIB0 & (1 << 08)) == 1 << 08; set => RIB0 = (ushort)((RIB0 & ~(1 << 08)) | (ushort)(value ? 1 << 08 : 0)); } + public override bool RibbonCountry { get => (RIB0 & (1 << 07)) == 1 << 07; set => RIB0 = (ushort)((RIB0 & ~(1 << 07)) | (ushort)(value ? 1 << 07 : 0)); } + public override bool RibbonNational { get => (RIB0 & (1 << 06)) == 1 << 06; set => RIB0 = (ushort)((RIB0 & ~(1 << 06)) | (ushort)(value ? 1 << 06 : 0)); } + public override bool RibbonEarth { get => (RIB0 & (1 << 05)) == 1 << 05; set => RIB0 = (ushort)((RIB0 & ~(1 << 05)) | (ushort)(value ? 1 << 05 : 0)); } + public override bool RibbonWorld { get => (RIB0 & (1 << 04)) == 1 << 04; set => RIB0 = (ushort)((RIB0 & ~(1 << 04)) | (ushort)(value ? 1 << 04 : 0)); } + public override bool Unused1 { get => (RIB0 & (1 << 03)) == 1 << 03; set => RIB0 = (ushort)((RIB0 & ~(1 << 03)) | (ushort)(value ? 1 << 03 : 0)); } + public override bool Unused2 { get => (RIB0 & (1 << 02)) == 1 << 02; set => RIB0 = (ushort)((RIB0 & ~(1 << 02)) | (ushort)(value ? 1 << 02 : 0)); } + public override bool Unused3 { get => (RIB0 & (1 << 01)) == 1 << 01; set => RIB0 = (ushort)((RIB0 & ~(1 << 01)) | (ushort)(value ? 1 << 01 : 0)); } + public override bool Unused4 { get => (RIB0 & (1 << 00)) == 1 << 00; set => RIB0 = (ushort)((RIB0 & ~(1 << 00)) | (ushort)(value ? 1 << 00 : 0)); } // 0x7E-0x7F Unknown // Moves @@ -127,26 +130,31 @@ public override int EV_HP get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0x9C)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0x9C); } + public override int EV_ATK { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0x9E)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0x9E); } + public override int EV_DEF { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0xA0)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0xA0); } + public override int EV_SPA { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0xA2)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0xA2); } + public override int EV_SPD { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0xA4)); set => BigEndian.GetBytes((ushort)(value & 0xFF)).CopyTo(Data, 0xA4); } + public override int EV_SPE { get => Math.Min(byte.MaxValue, BigEndian.ToUInt16(Data, 0xA6)); @@ -204,6 +212,7 @@ private bool IsOriginXD() return true; return IsOriginXD(Species, Met_Level); } + private static bool IsOriginXD(int species, int metLevel) { switch (species) diff --git a/PKHeX.Core/Saves/SAV2.cs b/PKHeX.Core/Saves/SAV2.cs index 706ea6f4a..e1414d820 100644 --- a/PKHeX.Core/Saves/SAV2.cs +++ b/PKHeX.Core/Saves/SAV2.cs @@ -11,6 +11,7 @@ public sealed class SAV2 : SaveFile protected override string BAKText => $"{OT} ({Version}) - {PlayTimeString}"; public override string Filter => "SAV File|*.sav|All Files|*.*"; public override string Extension => ".sav"; + public override string[] PKMExtensions => PKM.Extensions.Where(f => { int gen = f.Last() - 0x30; @@ -105,13 +106,13 @@ public SAV2(byte[] data = null, GameVersion versionOverride = GameVersion.Any) DaycareFlags[0] = Data[offset]; offset++; var pk1 = ReadPKMFromOffset(offset); // parent 1 var daycare1 = new PokeList2(pk1); - offset += StringLength * 2 + 0x20; // nick/ot/pkm + offset += (StringLength * 2) + 0x20; // nick/ot/pkm DaycareFlags[1] = Data[offset]; offset++; byte steps = Data[offset]; offset++; byte BreedMotherOrNonDitto = Data[offset]; offset++; var pk2 = ReadPKMFromOffset(offset); // parent 2 var daycare2 = new PokeList2(pk2); - offset += StringLength * 2 + PKX.SIZE_2STORED; // nick/ot/pkm + offset += (StringLength * 2) + PKX.SIZE_2STORED; // nick/ot/pkm var pk3 = ReadPKMFromOffset(offset); // egg! pk3.IsEgg = true; var daycare3 = new PokeList2(pk3); @@ -164,7 +165,7 @@ protected override byte[] Write(bool DSV) int slot = 0; for (int j = 0; j < boxPL.Pokemon.Length; j++) { - PK2 boxPK = (PK2) GetPKM(GetData(GetBoxOffset(i) + j*SIZE_STORED, SIZE_STORED)); + PK2 boxPK = (PK2) GetPKM(GetData(GetBoxOffset(i) + (j * SIZE_STORED), SIZE_STORED)); if (boxPK.Species > 0) boxPL[slot++] = boxPK; } @@ -207,8 +208,10 @@ protected override byte[] Write(bool DSV) new ushort[] {0x7E39, 0x7E6A}, }; foreach (ushort[] p in offsetpairs) + { for (int i = p[0]; i < p[1]; i++) sum += Data[i]; + } BitConverter.GetBytes(sum).CopyTo(Data, 0x7E6B); } else @@ -277,12 +280,14 @@ private ushort GetChecksum() { return (ushort)Data.Skip(Offsets.Trainer1).Take(Offsets.AccumulatedChecksumEnd - Offsets.Trainer1 + 1).Sum(a => a); } + protected override void SetChecksums() { ushort accum = GetChecksum(); BitConverter.GetBytes(accum).CopyTo(Data, Offsets.OverallChecksumPosition); BitConverter.GetBytes(accum).CopyTo(Data, Offsets.OverallChecksumPosition2); } + public override bool ChecksumsValid { get @@ -303,7 +308,9 @@ public override string OT get => GetString(Offsets.Trainer1 + 2, (Korean ? 2 : 1) * OTLength); set => SetString(value, (Korean ? 2 : 1) * OTLength).CopyTo(Data, Offsets.Trainer1 + 2); } + public byte[] OT_Trash { get => GetData(Offsets.Trainer1 + 2, StringLength); set { if (value?.Length == StringLength) SetData(value, Offsets.Trainer1 + 2); } } + public override int Gender { get => Version == GameVersion.C ? Data[Offsets.Gender] : 0; @@ -315,21 +322,26 @@ public override int Gender Data[Offsets.Palette] = (byte) value; } } + public override int TID { get => BigEndian.ToUInt16(Data, Offsets.Trainer1); set => BigEndian.GetBytes((ushort)value).CopyTo(Data, Offsets.Trainer1); } + public override int SID { get => 0; set { } } + public override int PlayedHours { get => BigEndian.ToUInt16(Data, Offsets.TimePlayed); set => BigEndian.GetBytes((ushort)value).CopyTo(Data, Offsets.TimePlayed); } + public override int PlayedMinutes { get => Data[Offsets.TimePlayed + 2]; set => Data[Offsets.TimePlayed + 2] = (byte)value; } + public override int PlayedSeconds { get => Data[Offsets.TimePlayed + 3]; @@ -341,21 +353,25 @@ public int Badges get => BitConverter.ToUInt16(Data, Offsets.JohtoBadges); set { if (value < 0) return; BitConverter.GetBytes((ushort)value).CopyTo(Data, Offsets.JohtoBadges); } } + private byte Options { get => Data[Offsets.Options]; set => Data[Offsets.Options] = value; } + public bool BattleEffects { get => (Options & 0x80) == 0; set => Options = (byte)((Options & 0x7F) | (value ? 0 : 0x80)); } + public bool BattleStyleSwitch { get => (Options & 0x40) == 0; set => Options = (byte)((Options & 0xBF) | (value ? 0 : 0x40)); } + public int Sound { get => (Options & 0x30) >> 4; @@ -369,6 +385,7 @@ public int Sound Options = (byte)((Options & 0xCF) | (new_sound << 4)); } } + public int TextSpeed { get => Options & 0x7; @@ -382,6 +399,7 @@ public int TextSpeed Options = (byte)((Options & 0xF8) | new_speed); } } + public override uint Money { get => BigEndian.ToUInt32(Data, Offsets.Money - 1) & 0xFFFFFF; @@ -391,6 +409,7 @@ public override uint Money Array.Copy(data, 1, Data, Offsets.Money, 3); } } + public uint Coin { get => BigEndian.ToUInt16(Data, Offsets.Money + 7); @@ -402,6 +421,7 @@ public uint Coin } private readonly ushort[] LegalItems, LegalKeyItems, LegalBalls, LegalTMHMs; + public override InventoryPouch[] Inventory { get @@ -439,7 +459,7 @@ public override InventoryPouch[] Inventory } private readonly byte[] DaycareFlags = new byte[2]; - public override int GetDaycareSlotOffset(int loc, int slot) => GetPartyOffset(7 + slot*2); + public override int GetDaycareSlotOffset(int loc, int slot) => GetPartyOffset(7 + (slot * 2)); public override uint? GetDaycareEXP(int loc, int slot) => null; public override bool? IsDaycareOccupied(int loc, int slot) => (DaycareFlags[slot] & 1) != 0; public override void SetDaycareEXP(int loc, int slot, uint EXP) { } @@ -450,14 +470,17 @@ public override int PartyCount { get => Data[Offsets.Party]; protected set => Data[Offsets.Party] = (byte)value; } + public override int GetBoxOffset(int box) { - return Data.Length - SIZE_RESERVED + box * SIZE_BOX; + return Data.Length - SIZE_RESERVED + (box * SIZE_BOX); } + public override int GetPartyOffset(int slot) { - return Data.Length - SIZE_RESERVED + BoxCount * SIZE_BOX + slot * SIZE_STORED; + return Data.Length - SIZE_RESERVED + (BoxCount * SIZE_BOX) + (slot * SIZE_STORED); } + public override int CurrentBox { get => Data[Offsets.CurrentBoxIndex] & 0x7F; set => Data[Offsets.CurrentBoxIndex] = (byte)((Data[Offsets.OtherCurrentBox] & 0x80) | (value & 0x7F)); @@ -466,13 +489,14 @@ public override int CurrentBox public override string GetBoxName(int box) { int len = Korean ? 17 : 9; - return GetString(Offsets.BoxNames + box * len, len); + return GetString(Offsets.BoxNames + (box * len), len); } + public override void SetBoxName(int box, string value) { int len = Korean ? 17 : 9; var data = SetString(value, len, len, 0x50); - SetData(data, Offsets.BoxNames + box * len); + SetData(data, Offsets.BoxNames + (box * len)); } public override PKM GetPKM(byte[] data) @@ -481,6 +505,7 @@ public override PKM GetPKM(byte[] data) return new PokeList2(data, PokeListType.Single, Japanese)[0]; return new PK2(data); } + public override byte[] DecryptPKM(byte[] data) { return data; @@ -496,6 +521,7 @@ protected override void SetDex(PKM pkm) SetCaught(pkm.Species, true); SetSeen(pkm.Species, true); } + private bool CanSetDex(int species) { if (species <= 0) @@ -506,12 +532,14 @@ private bool CanSetDex(int species) return false; return true; } + public override void SetSeen(int species, bool seen) { int bit = species - 1; int ofs = bit >> 3; SetFlag(Offsets.PokedexSeen + ofs, bit & 7, seen); } + public override void SetCaught(int species, bool caught) { int bit = species - 1; @@ -520,6 +548,7 @@ public override void SetCaught(int species, bool caught) if (caught && species == 201) SetUnownFormFlags(); } + private void SetUnownFormFlags() { // Give all Unown caught to prevent a crash on pokedex view @@ -528,6 +557,7 @@ private void SetUnownFormFlags() if (UnownFirstSeen == 0) // Invalid UnownFirstSeen = 1; // A } + /// /// Toggles the availability of Unown letter groups in the Wild /// @@ -543,10 +573,12 @@ public int UnownUnlocked get => Data[Offsets.PokedexSeen + 0x1F + 27]; set => Data[Offsets.PokedexSeen + 0x1F + 27] = (byte)value; } + /// /// Unlocks all Unown letters/forms in the wild. /// public void UnownUnlockAll() => UnownUnlocked = 0x0F; // all 4 bitflags + /// /// Flag that determines if Unown Letters are available in the wild: A, B, C, D, E, F, G, H, I, J, K /// @@ -555,6 +587,7 @@ public bool UnownUnlocked0 get => (UnownUnlocked & 1 << 0) == 1 << 0; set => UnownUnlocked |= 1 << 0; } + /// /// Flag that determines if Unown Letters are available in the wild: L, M, N, O, P, Q, R /// @@ -563,6 +596,7 @@ public bool UnownUnlocked1 get => (UnownUnlocked & 1 << 1) == 1 << 1; set => UnownUnlocked |= 1 << 1; } + /// /// Flag that determines if Unown Letters are available in the wild: S, T, U, V, W /// @@ -571,6 +605,7 @@ public bool UnownUnlocked2 get => (UnownUnlocked & 1 << 2) == 1 << 2; set => UnownUnlocked |= 1 << 2; } + /// /// Flag that determines if Unown Letters are available in the wild: X, Y, Z /// @@ -579,6 +614,7 @@ public bool UnownUnlocked3 get => (UnownUnlocked & 1 << 3) == 1 << 3; set => UnownUnlocked |= 1 << 3; } + /// /// Chooses which Unown sprite to show in the regular Pokédex View /// @@ -587,12 +623,14 @@ public int UnownFirstSeen get => Data[Offsets.PokedexSeen + 0x1F + 28]; set => Data[Offsets.PokedexSeen + 0x1F + 28] = (byte)value; } + public override bool GetSeen(int species) { int bit = species - 1; int ofs = bit >> 3; return GetFlag(Offsets.PokedexSeen + ofs, bit & 7); } + public override bool GetCaught(int species) { int bit = species - 1; @@ -602,6 +640,7 @@ public override bool GetCaught(int species) // Misc public ushort ResetKey => GetResetKey(); + private ushort GetResetKey() { var val = (TID >> 8) + (TID & 0xFF) + ((Money >> 16) & 0xFF) + ((Money >> 8) & 0xFF) + (Money & 0xFF); @@ -609,6 +648,7 @@ private ushort GetResetKey() var tr = ot.Sum(z => z); return (ushort)(val + tr); } + public void UnlockAllDecorations() { for (int i = 676; i <= 721; i++) @@ -621,6 +661,7 @@ public override string GetString(int Offset, int Length) return StringConverter.GetString2KOR(Data, Offset, Length); return StringConverter.GetString1(Data, Offset, Length, Japanese); } + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (Korean) diff --git a/PKHeX.Core/Saves/SAV3.cs b/PKHeX.Core/Saves/SAV3.cs index 33c045609..0a083879e 100644 --- a/PKHeX.Core/Saves/SAV3.cs +++ b/PKHeX.Core/Saves/SAV3.cs @@ -22,6 +22,7 @@ public sealed class SAV3 : SaveFile private const int SIZE_BLOCK = 0x1000; private const int BLOCK_COUNT = 14; private const int SIZE_RESERVED = 0x10000; // unpacked box data will start after the save data + private static readonly int[] chunkLength = { 0xf2c, // 0 | Small Block (Trainer Info) @@ -51,6 +52,7 @@ public static void GetLargeBlockOffset(int contiguousOffset, out int chunk, out } chunkOffset = contiguousOffset; } + public static int GetLargeBlockOffset(int chunk, int chunkOffset) { if (chunk == 1) @@ -78,27 +80,11 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any) if (Version == GameVersion.Invalid) return; - int[] BlockOrder1 = new int[BLOCK_COUNT]; - for (int i = 0; i < BLOCK_COUNT; i++) - BlockOrder1[i] = BitConverter.ToInt16(Data, i*SIZE_BLOCK + 0xFF4); - int zeroBlock1 = Array.IndexOf(BlockOrder1, 0); - + int[] BlockOrder1 = GetBlockOrder(0); if (Data.Length > SaveUtil.SIZE_G3RAWHALF) { - int[] BlockOrder2 = new int[BLOCK_COUNT]; - for (int i = 0; i < BLOCK_COUNT; i++) - BlockOrder2[i] = BitConverter.ToInt16(Data, 0xE000 + i*SIZE_BLOCK + 0xFF4); - int zeroBlock2 = Array.IndexOf(BlockOrder2, 0); - - if (zeroBlock2 < 0) - ActiveSAV = 0; - else if (zeroBlock1 < 0) - ActiveSAV = 1; - else - ActiveSAV = BitConverter.ToUInt32(Data, zeroBlock1*SIZE_BLOCK + 0xFFC) > - BitConverter.ToUInt32(Data, zeroBlock2*SIZE_BLOCK + 0xEFFC) - ? 0 - : 1; + int[] BlockOrder2 = GetBlockOrder(0xE000); + ActiveSAV = GetActiveSaveIndex(BlockOrder1, BlockOrder2); BlockOrder = ActiveSAV == 0 ? BlockOrder1 : BlockOrder2; } else @@ -111,7 +97,7 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any) for (int i = 0; i < BLOCK_COUNT; i++) { int index = Array.IndexOf(BlockOrder, i); - BlockOfs[i] = index < 0 ? int.MinValue : index*SIZE_BLOCK + ABO; + BlockOfs[i] = index < 0 ? int.MinValue : (index * SIZE_BLOCK) + ABO; } // Set up PC data buffer beyond end of save file. @@ -124,7 +110,7 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any) int blockIndex = Array.IndexOf(BlockOrder, i); if (blockIndex == -1) // block empty continue; - Array.Copy(Data, blockIndex * SIZE_BLOCK + ABO, Data, Box + (i - 5)*0xF80, chunkLength[i]); + Array.Copy(Data, (blockIndex * SIZE_BLOCK) + ABO, Data, Box + ((i - 5) * 0xF80), chunkLength[i]); } // Japanese games are limited to 5 character OT names; any unused characters are 0xFF. @@ -143,9 +129,9 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any) OFS_PouchBalls = BlockOfs[1] + 0x0600; OFS_PouchTMHM = BlockOfs[1] + 0x0640; OFS_PouchBerry = BlockOfs[1] + 0x0740; - SeenFlagOffsets = new[] {PokeDex + 0x44, BlockOfs[1] + 0x938, BlockOfs[4] + 0xC0C}; + SeenFlagOffsets = new[] { PokeDex + 0x44, BlockOfs[1] + 0x938, BlockOfs[4] + 0xC0C }; EventFlag = BlockOfs[2] + 0x2A0; - EventConst = EventFlag + EventFlagMax / 8; + EventConst = EventFlag + (EventFlagMax / 8); Daycare = BlockOfs[4] + 0x11C; break; case GameVersion.E: @@ -156,9 +142,9 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any) OFS_PouchBalls = BlockOfs[1] + 0x0650; OFS_PouchTMHM = BlockOfs[1] + 0x0690; OFS_PouchBerry = BlockOfs[1] + 0x0790; - SeenFlagOffsets = new[] {PokeDex + 0x44, BlockOfs[1] + 0x988, BlockOfs[4] + 0xCA4}; + SeenFlagOffsets = new[] { PokeDex + 0x44, BlockOfs[1] + 0x988, BlockOfs[4] + 0xCA4 }; EventFlag = BlockOfs[2] + 0x2F0; - EventConst = EventFlag + EventFlagMax / 8; + EventConst = EventFlag + (EventFlagMax / 8); Daycare = BlockOfs[4] + 0x1B0; break; case GameVersion.FRLG: @@ -169,9 +155,9 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any) OFS_PouchBalls = BlockOfs[1] + 0x0430; OFS_PouchTMHM = BlockOfs[1] + 0x0464; OFS_PouchBerry = BlockOfs[1] + 0x054C; - SeenFlagOffsets = new[] {PokeDex + 0x44, BlockOfs[1] + 0x5F8, BlockOfs[4] + 0xB98}; + SeenFlagOffsets = new[] { PokeDex + 0x44, BlockOfs[1] + 0x5F8, BlockOfs[4] + 0xB98 }; EventFlag = BlockOfs[2] + 0x000; - EventConst = EventFlag + EventFlagMax / 8; + EventConst = EventFlag + (EventFlagMax / 8); Daycare = BlockOfs[4] + 0x100; break; } @@ -190,6 +176,27 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any) ClearBoxes(); } + private int[] GetBlockOrder(int ofs) + { + int[] order = new int[BLOCK_COUNT]; + for (int i = 0; i < BLOCK_COUNT; i++) + order[i] = BitConverter.ToInt16(Data, ofs + (i * SIZE_BLOCK) + 0xFF4); + return order; + } + + private int GetActiveSaveIndex(int[] BlockOrder1, int[] BlockOrder2) + { + int zeroBlock1 = Array.IndexOf(BlockOrder1, 0); + int zeroBlock2 = Array.IndexOf(BlockOrder2, 0); + if (zeroBlock2 < 0) + return 0; + if (zeroBlock1 < 0) + return 1; + var count1 = BitConverter.ToUInt32(Data, (zeroBlock1 * SIZE_BLOCK) + 0xFFC); + var count2 = BitConverter.ToUInt32(Data, (zeroBlock2 * SIZE_BLOCK) + 0xEFFC); + return count1 < count2 ? 0 : 1; + } + protected override byte[] Write(bool DSV) { // Copy Box data back @@ -198,7 +205,7 @@ protected override byte[] Write(bool DSV) int blockIndex = Array.IndexOf(BlockOrder, i); if (blockIndex == -1) // block empty continue; - Array.Copy(Data, Box + (i - 5) * 0xF80, Data, blockIndex * SIZE_BLOCK + ABO, chunkLength[i]); + Array.Copy(Data, Box + ((i - 5) * 0xF80), Data, (blockIndex * SIZE_BLOCK) + ABO, chunkLength[i]); } SetChecksums(); @@ -246,19 +253,20 @@ protected override void SetChecksums() { for (int i = 0; i < BLOCK_COUNT; i++) { - int ofs = ABO + i * SIZE_BLOCK; + int ofs = ABO + (i * SIZE_BLOCK); int len = chunkLength[BlockOrder[i]]; ushort chk = SaveUtil.CRC32(Data, ofs, len); BitConverter.GetBytes(chk).CopyTo(Data, ofs + 0xFF6); } } + public override bool ChecksumsValid { get { for (int i = 0; i < BLOCK_COUNT; i++) { - int ofs = ABO + i * SIZE_BLOCK; + int ofs = ABO + (i * SIZE_BLOCK); int len = chunkLength[BlockOrder[i]]; ushort chk = SaveUtil.CRC32(Data, ofs, len); if (chk != BitConverter.ToUInt16(Data, ofs + 0xFF6)) @@ -267,6 +275,7 @@ public override bool ChecksumsValid return true; } } + public override string ChecksumInfo { get @@ -274,7 +283,7 @@ public override string ChecksumInfo var list = new List(); for (int i = 0; i < BLOCK_COUNT; i++) { - int ofs = ABO + i * SIZE_BLOCK; + int ofs = ABO + (i * SIZE_BLOCK); int len = chunkLength[BlockOrder[i]]; ushort chk = SaveUtil.CRC32(Data, ofs, len); if (chk != BitConverter.ToUInt16(Data, ofs + 0xFF6)) @@ -299,6 +308,7 @@ private uint SecurityKey } } } + public override string OT { get => GetString(BlockOfs[0], 0x10); @@ -308,41 +318,49 @@ public override string OT SetString(value, len, PadToSize: len, PadWith: 0xFF).CopyTo(Data, BlockOfs[0]); } } + public override int Gender { get => Data[BlockOfs[0] + 8]; set => Data[BlockOfs[0] + 8] = (byte)value; } + public override int TID { get => BitConverter.ToUInt16(Data, BlockOfs[0] + 0xA + 0); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, BlockOfs[0] + 0xA + 0); } + public override int SID { get => BitConverter.ToUInt16(Data, BlockOfs[0] + 0xC); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, BlockOfs[0] + 0xC); } + public override int PlayedHours { get => BitConverter.ToUInt16(Data, BlockOfs[0] + 0xE); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, BlockOfs[0] + 0xE); } + public override int PlayedMinutes { get => Data[BlockOfs[0] + 0x10]; set => Data[BlockOfs[0] + 0x10] = (byte)value; } + public override int PlayedSeconds { get => Data[BlockOfs[0] + 0x11]; set => Data[BlockOfs[0] + 0x11] = (byte)value; } + public int PlayedFrames { get => Data[BlockOfs[0] + 0x12]; set => Data[BlockOfs[0] + 0x12] = (byte)value; } + public int Badges { get @@ -350,8 +368,11 @@ public int Badges int startFlag = BadgeFlagStart; int val = 0; for (int i = 0; i < 8; i++) + { if (GetEventFlag(startFlag + i)) val |= 1 << i; + } + return val; } set @@ -373,6 +394,7 @@ private int BadgeFlagStart return 0x867; // emerald } } + public override uint Money { get @@ -395,6 +417,7 @@ public override uint Money } } } + public uint Coin { get @@ -419,6 +442,7 @@ public uint Coin } } } + public uint BP { get => BitConverter.ToUInt16(Data, BlockOfs[0] + 0xEB8); @@ -429,6 +453,7 @@ public uint BP BitConverter.GetBytes((ushort)value).CopyTo(Data, BlockOfs[0] + 0xEB8); } } + public uint BerryPowder { get @@ -446,6 +471,7 @@ public uint BerryPowder } private readonly ushort[] LegalItems, LegalKeyItems, LegalBalls, LegalTMHMs, LegalBerries; + public override InventoryPouch[] Inventory { get @@ -484,6 +510,7 @@ public override InventoryPouch[] Inventory public override void SetDaycareOccupied(int loc, int slot, bool occupied) { } public override int GetDaycareSlotOffset(int loc, int slot) => Daycare + (slot * DaycareSlotSize); public override bool? IsDaycareHasEgg(int loc) => GetDaycareRNGSeed(loc).Any(z => z != '0'); + public override void SetDaycareHasEgg(int loc, bool hasEgg) { SetDaycareRNGSeed(loc, E ? Util.Rand32().ToString("X8") : Util.Rand.Next(0x10000).ToString("X4")); @@ -502,6 +529,7 @@ public override string GetDaycareRNGSeed(int loc) return BitConverter.ToUInt32(Data, GetDaycareSlotOffset(0, 2)).ToString("X8"); // after the 2 slots, before the step counter return BitConverter.ToUInt16(Data, GetDaycareEXPOffset(2)).ToString("X4"); // after the 2nd slot EXP, before the step counter } + public override void SetDaycareRNGSeed(int loc, string seed) { if (Version == GameVersion.E) // egg pid @@ -534,42 +562,50 @@ protected set Data[BlockOfs[1] + ofs] = (byte)value; } } + public override int GetBoxOffset(int box) { - return Box + 4 + SIZE_STORED * box * 30; + return Box + 4 + (SIZE_STORED * box * 30); } + public override int GetPartyOffset(int slot) { int ofs = 0x38; if (GameVersion.FRLG != Version) ofs += 0x200; - return BlockOfs[1] + ofs + SIZE_PARTY * slot; + return BlockOfs[1] + ofs + (SIZE_PARTY * slot); } + public override int CurrentBox { get => Data[Box]; set => Data[Box] = (byte)value; } + protected override int GetBoxWallpaperOffset(int box) { int offset = GetBoxOffset(BoxCount); - offset += BoxCount * 0x9 + box; + offset += (BoxCount * 0x9) + box; return offset; } + public override string GetBoxName(int box) { int offset = GetBoxOffset(BoxCount); - return StringConverter.GetString3(Data, offset + box * 9, 9, Japanese); + return StringConverter.GetString3(Data, offset + (box * 9), 9, Japanese); } + public override void SetBoxName(int box, string value) { int offset = GetBoxOffset(BoxCount); - SetString(value, 8).CopyTo(Data, offset + box * 9); + SetString(value, 8).CopyTo(Data, offset + (box * 9)); } + public override PKM GetPKM(byte[] data) { return new PK3(data); } + public override byte[] DecryptPKM(byte[] data) { return PKX.DecryptArray3(data); @@ -577,6 +613,7 @@ public override byte[] DecryptPKM(byte[] data) // Pokédex private readonly int[] SeenFlagOffsets; + protected override void SetDex(PKM pkm) { int species = pkm.Species; @@ -595,6 +632,7 @@ protected override void SetDex(PKM pkm) SetCaught(species, true); SetSeen(species, true); } + private bool CanSetDex(int species) { if (species <= 0) @@ -607,6 +645,7 @@ private bool CanSetDex(int species) return false; return true; } + public uint DexPIDUnown { get => BitConverter.ToUInt32(Data, PokeDex + 0x4); set => BitConverter.GetBytes(value).CopyTo(Data, PokeDex + 0x4); } public uint DexPIDSpinda { get => BitConverter.ToUInt32(Data, PokeDex + 0x8); set => BitConverter.GetBytes(value).CopyTo(Data, PokeDex + 0x8); } public int DexUnownForm => PKX.GetUnownForm(DexPIDUnown); @@ -618,6 +657,7 @@ public override bool GetCaught(int species) int caughtOffset = PokeDex + 0x10; return GetFlag(caughtOffset + ofs, bit & 7); } + public override void SetCaught(int species, bool caught) { int bit = species - 1; @@ -633,6 +673,7 @@ public override bool GetSeen(int species) int seenOffset = PokeDex + 0x44; return GetFlag(seenOffset + ofs, bit & 7); } + public override void SetSeen(int species, bool seen) { int bit = species - 1; @@ -688,7 +729,9 @@ public bool NationalDex } } } + public override string GetString(int Offset, int Length) => StringConverter.GetString3(Data, Offset, Length, Japanese); + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (PadToSize == 0) @@ -714,6 +757,7 @@ public override string EBerryName return StringConverter.GetString3(Data, BlockOfs[4] + OFFSET_EBERRY, 7, Japanese).Trim(); } } + public override bool IsEBerryIsEnigma => string.IsNullOrEmpty(EBerryName.Trim()); private void LoadEReaderBerryData() @@ -736,6 +780,7 @@ public class RTC3 { public readonly byte[] Data; private const int Size = 8; + public RTC3(byte[] data = null) { if (data == null || data.Length != Size) @@ -748,6 +793,7 @@ public RTC3(byte[] data = null) public int Minute { get => Data[3]; set => Data[3] = (byte)value; } public int Second { get => Data[4]; set => Data[4] = (byte)value; } } + public RTC3 ClockInitial { get @@ -765,6 +811,7 @@ public RTC3 ClockInitial SetData(value.Data, block0 + 0x98); } } + public RTC3 ClockElapsed { get diff --git a/PKHeX.Core/Saves/SAV3Colosseum.cs b/PKHeX.Core/Saves/SAV3Colosseum.cs index 00b3aff6f..97918db95 100644 --- a/PKHeX.Core/Saves/SAV3Colosseum.cs +++ b/PKHeX.Core/Saves/SAV3Colosseum.cs @@ -10,6 +10,7 @@ namespace PKHeX.Core public sealed class SAV3Colosseum : SaveFile, IDisposable { protected override string BAKText => $"{OT} ({Version}) - {PlayTimeString}"; + public override string Filter { get @@ -44,6 +45,7 @@ public override string Filter private readonly SAV3GCMemoryCard MC; private bool IsMemoryCardSave => MC != null; public SAV3Colosseum(byte[] data, SAV3GCMemoryCard MC) : this(data) { this.MC = MC; BAK = MC.Data; } + public SAV3Colosseum(byte[] data = null) { Data = data ?? new byte[SaveUtil.SIZE_G3COLO]; @@ -56,7 +58,7 @@ public SAV3Colosseum(byte[] data = null) // Scan all 3 save slots for the highest counter for (int i = 0; i < SLOT_COUNT; i++) { - int slotOffset = SLOT_START + i * SLOT_SIZE; + int slotOffset = SLOT_START + (i * SLOT_SIZE); int SaveCounter = BigEndian.ToInt32(Data, slotOffset + 4); if (SaveCounter <= SaveCount) continue; @@ -68,7 +70,7 @@ public SAV3Colosseum(byte[] data = null) // Decrypt most recent save slot { byte[] slot = new byte[SLOT_SIZE]; - int slotOffset = SLOT_START + SaveIndex * SLOT_SIZE; + int slotOffset = SLOT_START + (SaveIndex * SLOT_SIZE); Array.Copy(Data, slotOffset, slot, 0, slot.Length); byte[] digest = new byte[20]; Array.Copy(slot, SLOT_SIZE - 20, digest, 0, digest.Length); @@ -107,8 +109,10 @@ public SAV3Colosseum(byte[] data = null) // Since PartyCount is not stored in the save file, // Count up how many party slots are active. for (int i = 0; i < 6; i++) + { if (GetPartySlot(GetPartyOffset(i)).Species != 0) PartyCount++; + } } public override byte[] Write(bool DSV, bool GCI) @@ -122,7 +126,7 @@ public override byte[] Write(bool DSV, bool GCI) // Put save slot back in original save data byte[] newFile = MC != null ? MC.SelectedSaveData : (byte[])BAK.Clone(); - Array.Copy(newSAV, 0, newFile, SLOT_START + SaveIndex*SLOT_SIZE, newSAV.Length); + Array.Copy(newSAV, 0, newFile, SLOT_START + (SaveIndex * SLOT_SIZE), newSAV.Length); // Return the gci if Memory Card is not being exported if (!IsMemoryCardSave || GCI) @@ -164,6 +168,7 @@ public override SaveFile Clone() // Checksums private readonly SHA1 sha1 = SHA1.Create(); public void Dispose() => sha1?.Dispose(); + private byte[] EncryptColosseum(byte[] input, byte[] digest) { if (input.Length != SLOT_SIZE) @@ -184,6 +189,7 @@ private byte[] EncryptColosseum(byte[] input, byte[] digest) } return d; } + private byte[] DecryptColosseum(byte[] input, byte[] digest) { if (input.Length != SLOT_SIZE) @@ -205,6 +211,7 @@ private byte[] DecryptColosseum(byte[] input, byte[] digest) } return d; } + protected override void SetChecksums() { // Clear Header Checksum @@ -232,7 +239,9 @@ protected override void SetChecksums() // Set Header Checksum BigEndian.GetBytes(newHC).CopyTo(Data, 12); } + public override bool ChecksumsValid => !ChecksumInfo.Contains("Invalid"); + public override string ChecksumInfo { get @@ -274,24 +283,29 @@ public override string ChecksumInfo // Storage public override int GetPartyOffset(int slot) { - return Party + SIZE_STORED * slot; + return Party + (SIZE_STORED * slot); } + public override int GetBoxOffset(int box) { - return Box + (30 * SIZE_STORED + 0x14)*box + 0x14; + return Box + (((30 * SIZE_STORED) + 0x14)*box) + 0x14; } + public override string GetBoxName(int box) { - return GetString(Box + 0x24A4*box, 16); + return GetString(Box + (0x24A4 * box), 16); } + public override void SetBoxName(int box, string value) { - SetString(value, 8).CopyTo(Data, Box + 0x24A4*box); + SetString(value, 8).CopyTo(Data, Box + (0x24A4 * box)); } + public override PKM GetPKM(byte[] data) { return new CK3(data.Take(SIZE_STORED).ToArray()); } + public override byte[] DecryptPKM(byte[] data) { return data; @@ -307,6 +321,7 @@ protected override void SetPKM(PKM pkm) if (pk.OriginalRegion == 0) pk.OriginalRegion = 2; // NTSC-U } + protected override void SetDex(PKM pkm) { // Dex Related @@ -331,16 +346,19 @@ private TimeSpan PlayedSpan get => TimeSpan.FromSeconds((double)(BigEndian.ToUInt32(Data, 40) - 0x47000000) / 128); set => BigEndian.GetBytes((uint)(value.TotalSeconds * 128) + 0x47000000).CopyTo(Data, 40); } + public override int PlayedHours { get => (ushort)PlayedSpan.Hours; set { var time = PlayedSpan; PlayedSpan = time - TimeSpan.FromHours(time.Hours) + TimeSpan.FromHours(value); } } + public override int PlayedMinutes { get => (byte)PlayedSpan.Minutes; set { var time = PlayedSpan; PlayedSpan = time - TimeSpan.FromMinutes(time.Minutes) + TimeSpan.FromMinutes(value); } } + public override int PlayedSeconds { get => (byte)PlayedSpan.Seconds; @@ -394,6 +412,7 @@ public override InventoryPouch[] Inventory public override void SetDaycareOccupied(int loc, int slot, bool occupied) { } public override string GetString(int Offset, int Length) => StringConverter.GetBEString3(Data, Offset, Length); + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (PadToSize == 0) diff --git a/PKHeX.Core/Saves/SAV3RSBox.cs b/PKHeX.Core/Saves/SAV3RSBox.cs index c26a12da6..8908e71dd 100644 --- a/PKHeX.Core/Saves/SAV3RSBox.cs +++ b/PKHeX.Core/Saves/SAV3RSBox.cs @@ -9,6 +9,7 @@ namespace PKHeX.Core public sealed class SAV3RSBox : SaveFile { protected override string BAKText => $"{Version} #{SaveCount:0000}"; + public override string Filter { get @@ -18,10 +19,12 @@ public override string Filter return "GameCube Save File|*.gci|All Files|*.*"; } } + public override string Extension => IsMemoryCardSave ? ".raw" : ".gci"; private readonly SAV3GCMemoryCard MC; private bool IsMemoryCardSave => MC != null; public SAV3RSBox(byte[] data, SAV3GCMemoryCard MC) : this(data) { this.MC = MC; BAK = MC.Data; } + public SAV3RSBox(byte[] data = null) { Data = data ?? new byte[SaveUtil.SIZE_G3BOX]; @@ -34,7 +37,7 @@ public SAV3RSBox(byte[] data = null) Blocks = new BlockInfo[2*BLOCK_COUNT]; for (int i = 0; i < Blocks.Length; i++) { - int offset = BLOCK_SIZE + i* BLOCK_SIZE; + int offset = BLOCK_SIZE + (i * BLOCK_SIZE); Blocks[i] = new BlockInfoRSBOX(Data, offset); } @@ -51,7 +54,7 @@ public SAV3RSBox(byte[] data = null) // Copy block to the allocated location const int copySize = BLOCK_SIZE - 0x10; foreach (var b in Blocks) - Array.Copy(Data, b.Offset + 0xC, Data, (int)(Box + b.ID*copySize), copySize); + Array.Copy(Data, b.Offset + 0xC, Data, (int)(Box + (b.ID*copySize)), copySize); Personal = PersonalTable.RS; HeldItems = Legal.HeldItems_RS; @@ -65,12 +68,13 @@ public SAV3RSBox(byte[] data = null) private const int BLOCK_COUNT = 23; private const int BLOCK_SIZE = 0x2000; private const int SIZE_RESERVED = BLOCK_COUNT * BLOCK_SIZE; // unpacked box data + public override byte[] Write(bool DSV, bool GCI) { // Copy Box data back const int copySize = BLOCK_SIZE - 0x10; foreach (var b in Blocks) - Array.Copy(Data, (int)(Box + b.ID * copySize), Data, b.Offset + 0xC, copySize); + Array.Copy(Data, (int)(Box + (b.ID * copySize)), Data, b.Offset + 0xC, copySize); SetChecksums(); @@ -126,45 +130,51 @@ public override SaveFile Clone() // Storage public override int GetPartyOffset(int slot) => -1; - public override int GetBoxOffset(int box) => Box + 8 + SIZE_STORED * box * 30; + public override int GetBoxOffset(int box) => Box + 8 + (SIZE_STORED * box * 30); + public override int CurrentBox { get => Data[Box + 4] * 2; set => Data[Box + 4] = (byte)(value / 2); } + protected override int GetBoxWallpaperOffset(int box) { // Box Wallpaper is directly after the Box Names - int offset = Box + 0x1ED19 + box/2; + int offset = Box + 0x1ED19 + (box / 2); return offset; } + public override string GetBoxName(int box) { // Tweaked for the 1-30/31-60 box showing - int lo = 30*(box%2) + 1; - int hi = 30*(box%2 + 1); + int lo = (30 *(box%2)) + 1; + int hi = 30*((box % 2) + 1); string boxName = $"[{lo:00}-{hi:00}] "; box /= 2; - int offset = Box + 0x1EC38 + 9 * box; + int offset = Box + 0x1EC38 + (9 * box); if (Data[offset] == 0 || Data[offset] == 0xFF) boxName += $"BOX {box + 1}"; boxName += GetString(offset, 9); return boxName; } + public override void SetBoxName(int box, string value) { - int offset = Box + 0x1EC38 + 9 * box; + int offset = Box + 0x1EC38 + (9 * box); byte[] data = value == $"BOX {box + 1}" ? new byte[9] : SetString(value, 8); SetData(data, offset); } + public override PKM GetPKM(byte[] data) { if (data.Length != PKX.SIZE_3STORED) Array.Resize(ref data, PKX.SIZE_3STORED); return new PK3(data); } + public override byte[] DecryptPKM(byte[] data) { if (data.Length != PKX.SIZE_3STORED) @@ -192,6 +202,7 @@ public override void SetStoredSlot(PKM pkm, int offset, bool? trade = null, bool } public override string GetString(int Offset, int Length) => StringConverter.GetString3(Data, Offset, Length, Japanese); + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (PadToSize == 0) diff --git a/PKHeX.Core/Saves/SAV3XD.cs b/PKHeX.Core/Saves/SAV3XD.cs index 8e6c528f1..f10f3fe55 100644 --- a/PKHeX.Core/Saves/SAV3XD.cs +++ b/PKHeX.Core/Saves/SAV3XD.cs @@ -9,6 +9,7 @@ namespace PKHeX.Core public sealed class SAV3XD : SaveFile { protected override string BAKText => $"{OT} ({Version}) #{SaveCount:0000}"; + public override string Filter { get @@ -18,6 +19,7 @@ public override string Filter return "GameCube Save File|*.gci|All Files|*.*"; } } + public override string Extension => IsMemoryCardSave ? ".raw" : ".gci"; private const int SLOT_SIZE = 0x28000; @@ -36,6 +38,7 @@ public override string Filter private readonly SAV3GCMemoryCard MC; private bool IsMemoryCardSave => MC != null; public SAV3XD(byte[] data, SAV3GCMemoryCard MC) : this(data) { this.MC = MC; BAK = MC.Data; } + public SAV3XD(byte[] data = null) { Data = data ?? new byte[SaveUtil.SIZE_G3XD]; @@ -48,7 +51,7 @@ public SAV3XD(byte[] data = null) // Scan all 3 save slots for the highest counter for (int i = 0; i < SLOT_COUNT; i++) { - int slotOffset = SLOT_START + i * SLOT_SIZE; + int slotOffset = SLOT_START + (i * SLOT_SIZE); int SaveCounter = BigEndian.ToInt32(Data, slotOffset + 4); if (SaveCounter <= SaveCount) continue; @@ -60,12 +63,12 @@ public SAV3XD(byte[] data = null) // Decrypt most recent save slot { byte[] slot = new byte[SLOT_SIZE]; - int slotOffset = SLOT_START + SaveIndex * SLOT_SIZE; + int slotOffset = SLOT_START + (SaveIndex * SLOT_SIZE); Array.Copy(Data, slotOffset, slot, 0, slot.Length); ushort[] keys = new ushort[4]; for (int i = 0; i < keys.Length; i++) - keys[i] = BigEndian.ToUInt16(slot, 8 + i * 2); + keys[i] = BigEndian.ToUInt16(slot, 8 + (i * 2)); // Decrypt Slot Data = SaveUtil.DecryptGC(slot, 0x00010, 0x27FD8, keys); @@ -75,8 +78,8 @@ public SAV3XD(byte[] data = null) ushort[] subLength = new ushort[16]; for (int i = 0; i < 16; i++) { - subLength[i] = BigEndian.ToUInt16(Data, 0x20 + 2*i); - subOffsets[i] = BigEndian.ToUInt16(Data, 0x40 + 4*i) | BigEndian.ToUInt16(Data, 0x40 + 4*i + 2) << 16; + subLength[i] = BigEndian.ToUInt16(Data, 0x20 + (2 * i)); + subOffsets[i] = BigEndian.ToUInt16(Data, 0x40 + (4 * i)) | BigEndian.ToUInt16(Data, 0x40 + (4 * i) + 2) << 16; } // Offsets are displaced by the 0xA8 savedata region Trainer1 = subOffsets[1] + 0xA8; @@ -115,8 +118,10 @@ public SAV3XD(byte[] data = null) // Since PartyCount is not stored in the save file, // Count up how many party slots are active. for (int i = 0; i < 6; i++) + { if (GetPartySlot(GetPartyOffset(i)).Species != 0) PartyCount++; + } } public override byte[] Write(bool DSV, bool GCI) @@ -129,12 +134,12 @@ public override byte[] Write(bool DSV, bool GCI) // Get updated save slot data ushort[] keys = new ushort[4]; for (int i = 0; i < keys.Length; i++) - keys[i] = BigEndian.ToUInt16(Data, 8 + i * 2); + keys[i] = BigEndian.ToUInt16(Data, 8 + (i * 2)); byte[] newSAV = SaveUtil.EncryptGC(Data, 0x10, 0x27FD8, keys); // Put save slot back in original save data byte[] newFile = MC != null ? MC.SelectedSaveData : (byte[])BAK.Clone(); - Array.Copy(newSAV, 0, newFile, SLOT_START + SaveIndex * SLOT_SIZE, newSAV.Length); + Array.Copy(newSAV, 0, newFile, SLOT_START + (SaveIndex * SLOT_SIZE), newSAV.Length); // Return the gci if Memory Card is not being exported if (!IsMemoryCardSave || GCI) @@ -180,7 +185,9 @@ protected override void SetChecksums() { Data = SetChecksums(Data, subOffsets[0]); } + public override bool ChecksumsValid => !ChecksumInfo.Contains("Invalid"); + public override string ChecksumInfo { get @@ -198,6 +205,7 @@ public override string ChecksumInfo return $"Header Checksum {(header ? "V" : "Inv")}alid, Body Checksum {(body ? "V" : "Inv")}alid."; } } + private static byte[] SetChecksums(byte[] input, int subOffset0) { if (input.Length != 0x28000) @@ -218,19 +226,21 @@ private static byte[] SetChecksums(byte[] input, int subOffset0) uint[] checksum = new uint[4]; int dt = 8; for (int i = 0; i < 4; i++) + { for (int j = 0; j < 0x9FF4; j += 2, dt += 2) checksum[i] += BigEndian.ToUInt16(data, dt); + } ushort[] newchks = new ushort[8]; for (int i = 0; i < 4; i++) { newchks[i*2] = (ushort)(checksum[i] >> 16); - newchks[i*2+1] = (ushort)checksum[i]; + newchks[(i * 2) + 1] = (ushort)checksum[i]; } Array.Reverse(newchks); for (int i = 0; i < newchks.Length; i++) - BigEndian.GetBytes(newchks[i]).CopyTo(data, 0x10 + 2*i); + BigEndian.GetBytes(newchks[i]).CopyTo(data, 0x10 + (2 * i)); return data; } @@ -247,26 +257,31 @@ private static byte[] SetChecksums(byte[] input, int subOffset0) // Storage public override int GetPartyOffset(int slot) { - return Party + SIZE_STORED * slot; + return Party + (SIZE_STORED * slot); } + public override int GetBoxOffset(int box) { - return Box + (30 * SIZE_STORED + 0x14)*box + 0x14; + return Box + (((30 * SIZE_STORED) + 0x14)*box) + 0x14; } + public override string GetBoxName(int box) { - return GetString(Box + (30 * SIZE_STORED + 0x14)*box, 16); + return GetString(Box + (((30 * SIZE_STORED) + 0x14)*box), 16); } + public override void SetBoxName(int box, string value) { if (value.Length > 8) value = value.Substring(0, 8); // Hard cap - SetString(value, 8).CopyTo(Data, Box + 0x24A4*box); + SetString(value, 8).CopyTo(Data, Box + (0x24A4 * box)); } + public override PKM GetPKM(byte[] data) { return new XK3(data.Take(SIZE_STORED).ToArray()); } + public override byte[] DecryptPKM(byte[] data) { return data; @@ -276,6 +291,7 @@ public override PKM GetPartySlot(int offset) { return GetStoredSlot(offset); } + public override PKM GetStoredSlot(int offset) { // Get Shadow Data @@ -284,6 +300,7 @@ public override PKM GetStoredSlot(int offset) pk.Purification = ShadowInfo[pk.ShadowID - 1].Purification; return pk; } + protected override void SetPKM(PKM pkm) { if (!(pkm is XK3 pk)) @@ -361,6 +378,7 @@ public override InventoryPouch[] Inventory public override void SetDaycareOccupied(int loc, int slot, bool occupied) { } public override string GetString(int Offset, int Length) => StringConverter.GetBEString3(Data, Offset, Length); + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (PadToSize == 0) diff --git a/PKHeX.Core/Saves/SAV4.cs b/PKHeX.Core/Saves/SAV4.cs index 3a328f3cf..7a738f502 100644 --- a/PKHeX.Core/Saves/SAV4.cs +++ b/PKHeX.Core/Saves/SAV4.cs @@ -12,6 +12,7 @@ public sealed class SAV4 : SaveFile protected override string BAKText => $"{OT} ({Version}) - {PlayTimeString}"; public override string Filter => (Footer.Length > 0 ? "DeSmuME DSV|*.dsv|" : "") + "SAV File|*.sav|All Files|*.*"; public override string Extension => ".sav"; + public SAV4(byte[] data = null, GameVersion versionOverride = GameVersion.Any) { Data = data ?? new byte[SaveUtil.SIZE_G4RAW]; @@ -85,6 +86,7 @@ private static int[][] GetChecksumOffsets(GameVersion g) return null; } } + protected override void SetChecksums() { int[][] c = GetChecksumOffsets(Version); @@ -94,6 +96,7 @@ protected override void SetChecksums() BitConverter.GetBytes(SaveUtil.CRC16_CCITT(Data, c[0][0] + GBO, c[0][1] - c[0][0])).CopyTo(Data, c[0][2] + GBO); BitConverter.GetBytes(SaveUtil.CRC16_CCITT(Data, c[1][0] + SBO, c[1][1] - c[1][0])).CopyTo(Data, c[1][2] + SBO); } + public override bool ChecksumsValid { get @@ -110,6 +113,7 @@ public override bool ChecksumsValid return true; } } + public override string ChecksumInfo { get @@ -131,10 +135,9 @@ public override string ChecksumInfo // Blocks & Offsets private readonly int generalBlock = -1; // Small Block private readonly int storageBlock = -1; // Big Block - private readonly int hofBlock = -1; // Hall of Fame Block private int SBO => 0x40000 * storageBlock; public int GBO => 0x40000 * generalBlock; - private int HBO => 0x40000 * hofBlock; + private int GetActiveGeneralBlock() { if (Version < 0) @@ -314,6 +317,7 @@ private void GetSAVOffsets() // Inventory private ushort[] LegalItems, LegalKeyItems, LegalTMHMs, LegalMedicine, LegalBerries, LegalBalls, LegalBattleItems, LegalMailItems; + public override InventoryPouch[] Inventory { get @@ -346,13 +350,15 @@ public override int PartyCount get => Data[Party - 4]; protected set => Data[Party - 4] = (byte)value; } + public override int GetBoxOffset(int box) { - return Box + SIZE_STORED*box*30 + (Version == GameVersion.HGSS ? box * 0x10 : 0); + return Box + (SIZE_STORED *box*30) + (Version == GameVersion.HGSS ? box * 0x10 : 0); } + public override int GetPartyOffset(int slot) { - return Party + SIZE_PARTY*slot; + return Party + (SIZE_PARTY * slot); } // Trainer Info @@ -361,46 +367,55 @@ public override string OT get => GetString(Trainer1, 16); set => SetString(value, OTLength).CopyTo(Data, Trainer1); } + public override int TID { get => BitConverter.ToUInt16(Data, Trainer1 + 0x10 + 0); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x10 + 0); } + public override int SID { get => BitConverter.ToUInt16(Data, Trainer1 + 0x12); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x12); } + public override uint Money { get => BitConverter.ToUInt32(Data, Trainer1 + 0x14); set => BitConverter.GetBytes(value).CopyTo(Data, Trainer1 + 0x14); } + public uint Coin { get => BitConverter.ToUInt16(Data, Trainer1 + 0x20); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x20); } + public override int Gender { get => Data[Trainer1 + 0x18]; set => Data[Trainer1 + 0x18] = (byte)value; } + public override int Language { get => Data[Trainer1 + 0x19]; set => Data[Trainer1 + 0x19] = (byte)value; } + public int Badges { get => Data[Trainer1 + 0x1A]; set { if (value < 0) return; Data[Trainer1 + 0x1A] = (byte)value; } } + public int Sprite { get => Data[Trainer1 + 0x1B]; set { if (value < 0) return; Data[Trainer1 + 0x1B] = (byte)value; } } + public int Badges16 { get @@ -418,21 +433,25 @@ public int Badges16 Data[Trainer1 + 0x1F] = (byte)value; } } + public override int PlayedHours { get => BitConverter.ToUInt16(Data, Trainer1 + 0x22); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x22); } + public override int PlayedMinutes { get => Data[Trainer1 + 0x24]; set => Data[Trainer1 + 0x24] = (byte)value; } + public override int PlayedSeconds { get => Data[Trainer1 + 0x25]; set => Data[Trainer1 + 0x25] = (byte)value; } + public int M { get @@ -460,6 +479,7 @@ public int M BitConverter.GetBytes((ushort)value).CopyTo(Data, ofs); } } + public int X { get @@ -488,6 +508,7 @@ public int X BitConverter.GetBytes((ushort)value).CopyTo(Data, ofs2); } } + public int Z { get @@ -515,6 +536,7 @@ public int Z BitConverter.GetBytes((ushort)value).CopyTo(Data, ofs); } } + public int Y { get @@ -543,6 +565,7 @@ public int Y BitConverter.GetBytes((ushort)value).CopyTo(Data, ofs2); } } + public override int SecondsToStart { get => BitConverter.ToInt32(Data, AdventureInfo + 0x34); set => BitConverter.GetBytes(value).CopyTo(Data, AdventureInfo + 0x34); } public override int SecondsToFame { get => BitConverter.ToInt32(Data, AdventureInfo + 0x3C); set => BitConverter.GetBytes(value).CopyTo(Data, AdventureInfo + 0x3C); } public int CurrentPoketchApp { get => (sbyte)Data[_currentPoketchApp]; set => Data[_currentPoketchApp] = (byte)Math.Min(24, value); /* Alarm Clock */ } @@ -554,6 +577,7 @@ public override int CurrentBox get => Data[Version == GameVersion.HGSS ? GetBoxOffset(BoxCount) : Box - 4]; set => Data[Version == GameVersion.HGSS ? GetBoxOffset(BoxCount) : Box - 4] = (byte)value; } + private static int AdjustWallpaper(int value, int shift) { // Pt's Special Wallpapers 1-8 are shifted by +0x8 @@ -562,6 +586,7 @@ private static int AdjustWallpaper(int value, int shift) return value + shift; return value; } + public override int GetBoxWallpaper(int box) { int value = base.GetBoxWallpaper(box); @@ -569,38 +594,44 @@ public override int GetBoxWallpaper(int box) value = AdjustWallpaper(value, -(Version == GameVersion.Pt ? 0x8 : 0x10)); return value; } + public override void SetBoxWallpaper(int box, int value) { if (Version != GameVersion.DP) value = AdjustWallpaper(value, Version == GameVersion.Pt ? 0x8 : 0x10); base.SetBoxWallpaper(box, value); } + protected override int GetBoxWallpaperOffset(int box) { // Box Wallpaper is directly after the Box Names int offset = GetBoxOffset(BoxCount); if (Version == GameVersion.HGSS) offset += 0x8; - offset += BoxCount*0x28 + box; + offset += (BoxCount * 0x28) + box; return offset; } + public override string GetBoxName(int box) { int offset = GetBoxOffset(BoxCount); if (Version == GameVersion.HGSS) offset += 0x8; - return GetString(offset + box*0x28, 0x28); + return GetString(offset + (box * 0x28), 0x28); } + public override void SetBoxName(int box, string value) { if (value.Length > 13) value = value.Substring(0, 13); // Hard cap int offset = GetBoxOffset(BoxCount); if (Version == GameVersion.HGSS) offset += 0x8; - SetData(SetString(value, 13), offset + box*0x28); + SetData(SetString(value, 13), offset + (box * 0x28)); } + public override PKM GetPKM(byte[] data) { return new PK4(data); } + public override byte[] DecryptPKM(byte[] data) { return PKX.DecryptArray45(data); @@ -618,22 +649,26 @@ protected override void SetPKM(PKM pkm) // Daycare public override int GetDaycareSlotOffset(int loc, int slot) { - return Daycare + slot * SIZE_PARTY; + return Daycare + (slot * SIZE_PARTY); } + public override uint? GetDaycareEXP(int loc, int slot) { - int ofs = Daycare + (slot+1)*SIZE_PARTY - 4; + int ofs = Daycare + ((slot+1)*SIZE_PARTY) - 4; return BitConverter.ToUInt32(Data, ofs); } + public override bool? IsDaycareOccupied(int loc, int slot) { return null; } + public override void SetDaycareEXP(int loc, int slot, uint EXP) { - int ofs = Daycare + (slot+1)*SIZE_PARTY - 4; + int ofs = Daycare + ((slot+1)*SIZE_PARTY) - 4; BitConverter.GetBytes(EXP).CopyTo(Data, ofs); } + public override void SetDaycareOccupied(int loc, int slot, bool occupied) { @@ -641,16 +676,21 @@ public override void SetDaycareOccupied(int loc, int slot, bool occupied) // Mystery Gift private bool MysteryGiftActive { get => (Data[GBO + 72] & 1) == 1; set => Data[GBO + 72] = (byte)((Data[GBO + 72] & 0xFE) | (value ? 1 : 0)); } + private static bool IsMysteryGiftAvailable(MysteryGift[] value) { if (value == null) return false; for (int i = 0; i < 8; i++) // 8 PGT + { if (value[i] is PGT g && g.CardType != 0) return true; + } for (int i = 8; i < 11; i++) // 3 PCD + { if (value[i] is PCD d && d.Gift.CardType != 0) return true; + } return false; } @@ -687,6 +727,7 @@ private static int[] MatchMysteryGifts(MysteryGift[] value) } return cardMatch; } + public override MysteryGiftAlbum GiftAlbum { get @@ -709,7 +750,9 @@ public override MysteryGiftAlbum GiftAlbum foreach (var g in value.Gifts) { if (g is PGT pgt) + { pgt.VerifyPKEncryption(); + } else if (g is PCD pcd) { var dg = pcd.Gift; @@ -728,6 +771,7 @@ public override MysteryGiftAlbum GiftAlbum MysteryGiftDPSlotActiveFlags = activeGifts; } } + protected override bool[] MysteryGiftReceivedFlags { get @@ -749,8 +793,10 @@ protected override bool[] MysteryGiftReceivedFlags byte[] data = new byte[value.Length / 8]; for (int i = 0; i < value.Length; i++) + { if (value[i]) data[i >> 3] |= (byte)(1 << (i & 7)); + } data.CopyTo(Data, WondercardFlags); Edited = true; @@ -758,6 +804,7 @@ protected override bool[] MysteryGiftReceivedFlags } private const uint MysteryGiftDPSlotActive = 0xEDB88320; + private bool[] MysteryGiftDPSlotActiveFlags { get @@ -768,7 +815,7 @@ private bool[] MysteryGiftDPSlotActiveFlags int ofs = WondercardFlags + 0x100; // skip over flags bool[] active = new bool[GiftCountMax]; // 8 PGT, 3 PCD for (int i = 0; i < active.Length; i++) - active[i] = BitConverter.ToUInt32(Data, ofs + 4*i) == MysteryGiftDPSlotActive; + active[i] = BitConverter.ToUInt32(Data, ofs + (4 * i)) == MysteryGiftDPSlotActive; return active; } @@ -783,7 +830,7 @@ private bool[] MysteryGiftDPSlotActiveFlags for (int i = 0; i < value.Length; i++) { byte[] magic = BitConverter.GetBytes(value[i] ? MysteryGiftDPSlotActive : 0); // 4 bytes - SetData(magic, ofs + 4*i); + SetData(magic, ofs + (4 * i)); } } } @@ -794,9 +841,9 @@ protected override MysteryGift[] MysteryGiftCards { MysteryGift[] cards = new MysteryGift[8 + 3]; for (int i = 0; i < 8; i++) // 8 PGT - cards[i] = new PGT(GetData(WondercardData + i * PGT.Size, PGT.Size)); + cards[i] = new PGT(GetData(WondercardData + (i * PGT.Size), PGT.Size)); for (int i = 8; i < 11; i++) // 3 PCD - cards[i] = new PCD(GetData(WondercardData + 8 * PGT.Size + (i-8) * PCD.Size, PCD.Size)); + cards[i] = new PCD(GetData(WondercardData + (8 * PGT.Size) + ((i-8) * PCD.Size), PCD.Size)); return cards; } set @@ -809,11 +856,15 @@ protected override MysteryGift[] MysteryGiftCards return; for (int i = 0; i < 8; i++) // 8 PGT + { if (value[i] is PGT) - SetData(value[i].Data, WondercardData + i*PGT.Size); + SetData(value[i].Data, WondercardData + (i *PGT.Size)); + } for (int i = 8; i < 11; i++) // 3 PCD + { if (value[i] is PCD) - SetData(value[i].Data, WondercardData + 8*PGT.Size + (i - 8)*PCD.Size); + SetData(value[i].Data, WondercardData + (8 *PGT.Size) + ((i - 8)*PCD.Size)); + } } } @@ -847,39 +898,39 @@ protected override void SetDex(PKM pkm) */ // Set the Species Owned Flag - Data[ofs + brSize * 0] |= mask; + Data[ofs + (brSize * 0)] |= mask; // Check if already Seen - if ((Data[ofs + brSize * 1] & mask) == 0) // Not seen + if ((Data[ofs + (brSize * 1)] & mask) == 0) // Not seen { - Data[ofs + brSize * 1] |= mask; // Set seen + Data[ofs + (brSize * 1)] |= mask; // Set seen int gr = pkm.PersonalInfo.Gender; switch (gr) { case 255: // Genderless case 0: // Male Only - Data[ofs + brSize * 2] &= mask; - Data[ofs + brSize * 3] &= mask; + Data[ofs + (brSize * 2)] &= mask; + Data[ofs + (brSize * 3)] &= mask; break; case 254: // Female Only - Data[ofs + brSize * 2] |= mask; - Data[ofs + brSize * 3] |= mask; + Data[ofs + (brSize * 2)] |= mask; + Data[ofs + (brSize * 3)] |= mask; break; default: // Male or Female - bool m = (Data[ofs + brSize * 2] & mask) != 0; - bool f = (Data[ofs + brSize * 3] & mask) != 0; + bool m = (Data[ofs + (brSize * 2)] & mask) != 0; + bool f = (Data[ofs + (brSize * 3)] & mask) != 0; if (m || f) // bit already set? break; int gender = pkm.Gender & 1; - Data[ofs + brSize * 2] &= (byte)~mask; // unset - Data[ofs + brSize * 3] &= (byte)~mask; // unset + Data[ofs + (brSize * 2)] &= (byte)~mask; // unset + Data[ofs + (brSize * 3)] &= (byte)~mask; // unset gender ^= 1; // Set OTHER gender seen bit so it appears second - Data[ofs + brSize * (2 + gender)] |= mask; + Data[ofs + (brSize * (2 + gender))] |= mask; break; } } - int FormOffset1 = PokeDex + 4 + brSize * 4 + 4; + int FormOffset1 = PokeDex + 4 + (brSize * 4) + 4; var forms = GetForms(pkm.Species); if (forms != null) { @@ -920,6 +971,7 @@ protected override void SetDex(PKM pkm) int lang = GetGen4LanguageBitIndex(pkm.Language); Data[PokeDexLanguageFlags + (DP ? dpl : pkm.Species)] |= (byte)(1 << lang); } + private static int GetGen4LanguageBitIndex(int lang) { lang--; @@ -942,6 +994,7 @@ public override bool GetCaught(int species) + 0x4; // Magic return (1 << bm & Data[ofs + bd]) != 0; } + public override bool GetSeen(int species) { const int brSize = 0x40; @@ -952,7 +1005,7 @@ public override bool GetSeen(int species) int ofs = PokeDex // Raw Offset + 0x4; // Magic - return (1 << bm & Data[ofs + bd + brSize*1]) != 0; + return (1 << bm & Data[ofs + bd + (brSize * 1)]) != 0; } public int[] GetForms(int species) @@ -960,11 +1013,11 @@ public int[] GetForms(int species) const int brSize = 0x40; if (species == 386) { - uint val = (uint) (Data[PokeDex + 0x4 + 1*brSize - 1] | Data[PokeDex + 0x4 + 2*brSize - 1] << 8); + uint val = (uint) (Data[PokeDex + 0x4 + (1 * brSize) - 1] | Data[PokeDex + 0x4 + (2 * brSize) - 1] << 8); return GetDexFormValues(val, 4, 4); } - int FormOffset1 = PokeDex + 4 + 4*brSize + 4; + int FormOffset1 = PokeDex + 4 + (4 * brSize) + 4; switch (species) { case 422: // Shellos @@ -999,6 +1052,7 @@ public int[] GetForms(int species) return null; } + public void SetForms(int spec, int[] forms) { const int brSize = 0x40; @@ -1006,12 +1060,12 @@ public void SetForms(int spec, int[] forms) { case 386: // Deoxys 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); + Data[PokeDex + 0x4 + (1 * brSize) - 1] = (byte) (newval & 0xFF); + Data[PokeDex + 0x4 + (2 * brSize) - 1] = (byte) ((newval >> 8) & 0xFF); break; } - int FormOffset1 = PokeDex + 4 + 4*brSize + 4; + int FormOffset1 = PokeDex + 4 + (4 * brSize) + 4; switch (spec) { case 422: // Shellos @@ -1079,6 +1133,7 @@ private static int[] GetDexFormValues(uint Value, int BitsPerForm, int readCt) return Forms; } + private static uint SetDexFormValues(int[] Forms, int BitsPerForm, int readCt) { int n1 = 0xFF >> (8 - BitsPerForm); @@ -1090,9 +1145,12 @@ private static uint SetDexFormValues(int[] Forms, int BitsPerForm, int readCt) val = n1; Value |= (uint)(val << (BitsPerForm*i)); + if (i >= readCt) + throw new ArgumentException("Array count should be less than bitfield count", nameof(Forms)); } return Value; } + private static bool CheckInsertForm(ref int[] Forms, int FormNum) { if (Forms.Any(num => num == FormNum)) @@ -1113,6 +1171,7 @@ private static bool CheckInsertForm(ref int[] Forms, int FormNum) Forms[n1] = FormNum; return true; } + public int DexUpgraded { get @@ -1153,7 +1212,7 @@ public int DexUpgraded Data[0x15ED + GBO] = (byte)(value == 3 ? 1 : 0); Data[0x15EF + GBO] = (byte)(value >= 2 ? 1 : 0); Data[0x15EE + GBO] = (byte)(value >= 1 ? 1 : 0); - Data[0x10D1 + GBO] = (byte)(Data[0x10D1 + GBO] & ~8 | (value >= 1 ? 8 : 0)); + Data[0x10D1 + GBO] = (byte)((Data[0x10D1 + GBO] & ~8) | (value >= 1 ? 8 : 0)); break; case GameVersion.Pt: Data[0x1641 + GBO] = (byte)(value == 4 ? 1 : 0); @@ -1169,17 +1228,20 @@ public int DexUpgraded // Honey Trees private int OFS_HONEY = int.MinValue; private const int HONEY_SIZE = 8; + public HoneyTree GetHoneyTree(int index) { if (OFS_HONEY <= 0 || index > 21) return null; - return new HoneyTree(GetData(OFS_HONEY + HONEY_SIZE * index, HONEY_SIZE)); + return new HoneyTree(GetData(OFS_HONEY + (HONEY_SIZE * index), HONEY_SIZE)); } + public void SetHoneyTree(HoneyTree tree, int index) { if (index <= 21 && OFS_HONEY > 0) - SetData(tree.Data, OFS_HONEY + HONEY_SIZE * index); + SetData(tree.Data, OFS_HONEY + (HONEY_SIZE * index)); } + public int[] MunchlaxTrees { get @@ -1203,6 +1265,7 @@ public int[] MunchlaxTrees // Pokewalker private int OFS_WALKER = int.MinValue; public void PokewalkerCoursesUnlockAll() => SetData(BitConverter.GetBytes((uint)0x07FF_FFFF), OFS_WALKER); + public bool[] PokewalkerCoursesUnlocked { get @@ -1237,6 +1300,7 @@ public bool[] PokewalkerCoursesUnlocked public void SetApricornCount(int i, int count) => Data[0xE558 + GBO + i] = (byte)count; public override string GetString(int Offset, int Length) => StringConverter.GetString4(Data, Offset, Length); + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (PadToSize == 0) diff --git a/PKHeX.Core/Saves/SAV4BR.cs b/PKHeX.Core/Saves/SAV4BR.cs index 13fa49c7e..7eb2cb1e2 100644 --- a/PKHeX.Core/Saves/SAV4BR.cs +++ b/PKHeX.Core/Saves/SAV4BR.cs @@ -15,6 +15,7 @@ public sealed class SAV4BR : SaveFile public override string Extension => ""; private const int SAVE_COUNT = 4; + public SAV4BR(byte[] data = null) { Data = data ?? new byte[SaveUtil.SIZE_G4BR]; @@ -55,7 +56,7 @@ public SAV4BR(byte[] data = null) private bool IsOTNamePresent(int i) { - return BitConverter.ToUInt16(Data, 0x390 + 0x6FF00 * i) != 0; + return BitConverter.ToUInt16(Data, 0x390 + (0x6FF00 * i)) != 0; } private readonly uint SaveCount; @@ -73,6 +74,7 @@ protected override byte[] Write(bool DSV) public readonly List SaveNames = new List(SAVE_COUNT); private int _currentSlot; + public int CurrentSlot { get => SaveSlots.IndexOf(_currentSlot); @@ -115,8 +117,10 @@ public override int PartyCount { int ctr = 0; for (int i = 0; i < 6; i++) + { if (Data[GetPartyOffset(i) + 4] != 0) // sanity ctr++; + } return ctr; } protected set { } @@ -130,6 +134,7 @@ protected override void SetChecksums() SetChecksum(Data, 0x1C0000, 0x100, 0x1C0008); SetChecksum(Data, 0x1C0000, 0x1C0000, 0x1BFF80 + 0x1C0000); } + public override bool ChecksumsValid => IsChecksumsValid(Data); public override string ChecksumInfo => $"Checksums valid: {ChecksumsValid}."; @@ -143,30 +148,33 @@ public static bool IsChecksumsValid(byte[] sav) // Trainer Info public override GameVersion Version { get => GameVersion.BATREV; protected set { } } + private string GetOTName(int i) { - return Encoding.BigEndianUnicode.GetString(Data, 0x390 + 0x6FF00 * i, 0x10); + return Encoding.BigEndianUnicode.GetString(Data, 0x390 + (0x6FF00 * i), 0x10); } // Storage public override int GetPartyOffset(int slot) { - return Party + SIZE_PARTY * slot; + return Party + (SIZE_PARTY * slot); } + public override int GetBoxOffset(int box) { - return Box + SIZE_STORED * box * 30; + return Box + (SIZE_STORED * box * 30); } // Save file does not have Box Name / Wallpaper info private int BoxName = -1; private const int BoxNameLength = 0x28; + public override string GetBoxName(int box) { if (BoxName < 0) return $"BOX {box + 1}"; - var str = Encoding.BigEndianUnicode.GetString(Data, BoxName + box * BoxNameLength, BoxNameLength); + var str = Encoding.BigEndianUnicode.GetString(Data, BoxName + (box * BoxNameLength), BoxNameLength); str = Util.TrimFromZero(str); if (string.IsNullOrWhiteSpace(str)) return $"BOX {box + 1}"; @@ -178,7 +186,7 @@ public override void SetBoxName(int box, string value) if (BoxName < 0) return; - int ofs = BoxName + box * BoxNameLength; + int ofs = BoxName + (box * BoxNameLength); var str = Encoding.BigEndianUnicode.GetString(Data, ofs, BoxNameLength); str = Util.TrimFromZero(str); if (string.IsNullOrWhiteSpace(str)) @@ -194,12 +202,14 @@ public override PKM GetPKM(byte[] data) PKM bk = new BK4(pkm); return bk; } + public override byte[] DecryptPKM(byte[] data) { return data; } protected override void SetDex(PKM pkm) { } + protected override void SetPKM(PKM pkm) { var pk4 = (BK4)pkm; @@ -222,16 +232,16 @@ public static byte[] DecryptPBRSaveData(byte[] input) { Array.Copy(input, base_ofs, output, base_ofs, 8); for (int i = 0; i < keys.Length; i++) - keys[i] = BigEndian.ToUInt16(input, base_ofs + i * 2); + keys[i] = BigEndian.ToUInt16(input, base_ofs + (i * 2)); for (int ofs = base_ofs + 8; ofs < base_ofs + 0x1C0000; ofs += 8) { for (int i = 0; i < keys.Length; i++) { - ushort val = BigEndian.ToUInt16(input, ofs + i*2); + ushort val = BigEndian.ToUInt16(input, ofs + (i * 2)); val -= keys[i]; - output[ofs + i * 2] = (byte)(val >> 8); - output[ofs + i * 2 + 1] = (byte)val; + output[ofs + (i * 2)] = (byte)(val >> 8); + output[ofs + (i * 2) + 1] = (byte)val; } keys = SaveUtil.AdvanceGCKeys(keys); } @@ -247,16 +257,16 @@ private static byte[] EncryptPBRSaveData(byte[] input) { Array.Copy(input, base_ofs, output, base_ofs, 8); for (int i = 0; i < keys.Length; i++) - keys[i] = BigEndian.ToUInt16(input, base_ofs + i * 2); + keys[i] = BigEndian.ToUInt16(input, base_ofs + (i * 2)); for (int ofs = base_ofs + 8; ofs < base_ofs + 0x1C0000; ofs += 8) { for (int i = 0; i < keys.Length; i++) { - ushort val = BigEndian.ToUInt16(input, ofs + i * 2); + ushort val = BigEndian.ToUInt16(input, ofs + (i * 2)); val += keys[i]; - output[ofs + i * 2] = (byte)(val >> 8); - output[ofs + i * 2 + 1] = (byte)val; + output[ofs + (i * 2)] = (byte)(val >> 8); + output[ofs + (i * 2) + 1] = (byte)val; } keys = SaveUtil.AdvanceGCKeys(keys); } @@ -269,8 +279,8 @@ public static bool VerifyChecksum(byte[] input, int offset, int len, int checksu uint[] storedChecksums = new uint[16]; for (int i = 0; i < storedChecksums.Length; i++) { - storedChecksums[i] = BigEndian.ToUInt32(input, checksum_offset + i*4); - BitConverter.GetBytes((uint)0).CopyTo(input, checksum_offset + i*4); + storedChecksums[i] = BigEndian.ToUInt32(input, checksum_offset + (i * 4)); + BitConverter.GetBytes((uint)0).CopyTo(input, checksum_offset + (i * 4)); } uint[] checksums = new uint[16]; @@ -286,7 +296,7 @@ public static bool VerifyChecksum(byte[] input, int offset, int len, int checksu for (int i = 0; i < storedChecksums.Length; i++) { - BigEndian.GetBytes(storedChecksums[i]).CopyTo(input, checksum_offset + i*4); + BigEndian.GetBytes(storedChecksums[i]).CopyTo(input, checksum_offset + (i * 4)); } return checksums.SequenceEqual(storedChecksums); @@ -297,8 +307,8 @@ private static void SetChecksum(byte[] input, int offset, int len, int checksum_ uint[] storedChecksums = new uint[16]; for (int i = 0; i < storedChecksums.Length; i++) { - storedChecksums[i] = BigEndian.ToUInt32(input, checksum_offset + i * 4); - BitConverter.GetBytes((uint)0).CopyTo(input, checksum_offset + i * 4); + storedChecksums[i] = BigEndian.ToUInt32(input, checksum_offset + (i * 4)); + BitConverter.GetBytes((uint)0).CopyTo(input, checksum_offset + (i * 4)); } uint[] checksums = new uint[16]; @@ -307,18 +317,17 @@ private static void SetChecksum(byte[] input, int offset, int len, int checksum_ { ushort val = BigEndian.ToUInt16(input, offset + i); for (int j = 0; j < 16; j++) - { checksums[j] += (uint)((val >> j) & 1); - } } for (int i = 0; i < checksums.Length; i++) { - BigEndian.GetBytes(checksums[i]).CopyTo(input, checksum_offset + i * 4); + BigEndian.GetBytes(checksums[i]).CopyTo(input, checksum_offset + (i * 4)); } } public override string GetString(int Offset, int Length) => StringConverter.GetBEString4(Data, Offset, Length); + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (PadToSize == 0) diff --git a/PKHeX.Core/Saves/SAV5.cs b/PKHeX.Core/Saves/SAV5.cs index 63a3a9944..1c9ffe12d 100644 --- a/PKHeX.Core/Saves/SAV5.cs +++ b/PKHeX.Core/Saves/SAV5.cs @@ -13,6 +13,7 @@ public sealed class SAV5 : SaveFile protected override string BAKText => $"{OT} ({(GameVersion)Game}) - {PlayTimeString}"; public override string Filter => (Footer.Length > 0 ? "DeSmuME DSV|*.dsv|" : "") + "SAV File|*.sav|All Files|*.*"; public override string Extension => ".sav"; + public SAV5(byte[] data = null, GameVersion versionOverride = GameVersion.Any) { Data = data ?? new byte[SaveUtil.SIZE_G5RAW]; @@ -140,10 +141,12 @@ public SAV5(byte[] data = null, GameVersion versionOverride = GameVersion.Any) // Daycare public override int DaycareSeedSize => 16; + public override int GetDaycareSlotOffset(int loc, int slot) { - return Daycare + 4 + 0xE4 * slot; + return Daycare + 4 + (0xE4 * slot); } + public override string GetDaycareRNGSeed(int loc) { if (Version != GameVersion.B2W2) @@ -151,22 +154,27 @@ public override string GetDaycareRNGSeed(int loc) var data = Data.Skip(Daycare + 0x1CC).Take(DaycareSeedSize/2).Reverse().ToArray(); return BitConverter.ToString(data).Replace("-", ""); } + public override uint? GetDaycareEXP(int loc, int slot) { - return BitConverter.ToUInt32(Data, Daycare + 4 + 0xDC + slot * 0xE4); + return BitConverter.ToUInt32(Data, Daycare + 4 + 0xDC + (slot * 0xE4)); } + public override bool? IsDaycareOccupied(int loc, int slot) { - return BitConverter.ToUInt32(Data, Daycare + 0xE4*slot) == 1; + return BitConverter.ToUInt32(Data, Daycare + (0xE4 * slot)) == 1; } + public override void SetDaycareEXP(int loc, int slot, uint EXP) { - BitConverter.GetBytes(EXP).CopyTo(Data, Daycare + 4 + 0xDC + slot * 0xE4); + BitConverter.GetBytes(EXP).CopyTo(Data, Daycare + 4 + 0xDC + (slot * 0xE4)); } + public override void SetDaycareOccupied(int loc, int slot, bool occupied) { BitConverter.GetBytes((uint)(occupied ? 1 : 0)).CopyTo(Data, Daycare + 0x1CC); } + public override void SetDaycareRNGSeed(int loc, string seed) { if (Version != GameVersion.B2W2) @@ -179,6 +187,7 @@ public override void SetDaycareRNGSeed(int loc, string seed) // Inventory private readonly ushort[] LegalItems, LegalKeyItems, LegalTMHMs, LegalMedicine, LegalBerries; + public override InventoryPouch[] Inventory { get @@ -208,50 +217,60 @@ public override int PartyCount get => Data[Party + 4]; protected set => Data[Party + 4] = (byte)value; } + public override int GetBoxOffset(int box) { - return Box + SIZE_STORED * box * 30 + box * 0x10; + return Box + (SIZE_STORED * box * 30) + (box * 0x10); } + public override int GetPartyOffset(int slot) { - return Party + 8 + SIZE_PARTY*slot; + return Party + 8 + (SIZE_PARTY * slot); } + public override string GetBoxName(int box) { if (box >= BoxCount) return ""; - return StringConverter.TrimFromFFFF(Encoding.Unicode.GetString(Data, PCLayout + 0x28 * box + 4, 0x28)); + return StringConverter.TrimFromFFFF(Encoding.Unicode.GetString(Data, PCLayout + (0x28 * box) + 4, 0x28)); } + public override void SetBoxName(int box, string value) { if (value.Length > 38) return; value += '\uFFFF'; - Encoding.Unicode.GetBytes(value.PadRight(0x14, '\0')).CopyTo(Data, PCLayout + 0x28 * box + 4); + Encoding.Unicode.GetBytes(value.PadRight(0x14, '\0')).CopyTo(Data, PCLayout + (0x28 * box) + 4); Edited = true; } + protected override int GetBoxWallpaperOffset(int box) { return PCLayout + 0x3C4 + box; } + public override int CurrentBox { get => Data[PCLayout]; set => Data[PCLayout] = (byte)value; } + public override bool BattleBoxLocked { get => BattleBox >= 0 && Data[BattleBox + 0x358] != 0; // wifi/live set { } } + public override PKM GetPKM(byte[] data) { return new PK5(data); } + public override byte[] DecryptPKM(byte[] data) { return PKX.DecryptArray45(data); } + protected override void SetPKM(PKM pkm) { var pk5 = (PK5)pkm; @@ -279,7 +298,7 @@ public override MysteryGiftAlbum GiftAlbum Info.Flags[i] = (wcData[i/8] >> i%8 & 0x1) == 1; // 12 PGFs for (int i = 0; i < Info.Gifts.Length; i++) - Info.Gifts[i] = new PGF(wcData.Skip(0x100 + i*PGF.Size).Take(PGF.Size).ToArray()); + Info.Gifts[i] = new PGF(wcData.Skip(0x100 + (i *PGF.Size)).Take(PGF.Size).ToArray()); return Info; } @@ -289,10 +308,13 @@ public override MysteryGiftAlbum GiftAlbum // Toss back into byte[] for (int i = 0; i < value.Flags.Length; i++) + { if (value.Flags[i]) wcData[i/8] |= (byte)(1 << (i & 7)); + } + for (int i = 0; i < value.Gifts.Length; i++) - value.Gifts[i].Data.CopyTo(wcData, 0x100 + i*PGF.Size); + value.Gifts[i].Data.CopyTo(wcData, 0x100 + (i *PGF.Size)); // Decrypted, Encrypt uint seed = value.Seed; @@ -304,6 +326,7 @@ public override MysteryGiftAlbum GiftAlbum BitConverter.GetBytes(value.Seed).CopyTo(Data, wcSeed); } } + protected override bool[] MysteryGiftReceivedFlags { get => null; set { } } protected override MysteryGift[] MysteryGiftCards { get => Array.Empty(); set { } } @@ -313,56 +336,67 @@ public override string OT get => GetString(Trainer1 + 0x4, 16); set => SetString(value, OTLength).CopyTo(Data, Trainer1 + 0x4); } + public override int TID { get => BitConverter.ToUInt16(Data, Trainer1 + 0x14 + 0); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x14 + 0); } + public override int SID { get => BitConverter.ToUInt16(Data, Trainer1 + 0x14 + 2); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x14 + 2); } + public override uint Money { get => BitConverter.ToUInt32(Data, Trainer2); set => BitConverter.GetBytes(value).CopyTo(Data, Trainer2); } + public override int Gender { get => Data[Trainer1 + 0x21]; set => Data[Trainer1 + 0x21] = (byte)value; } + public override int Language { get => Data[Trainer1 + 0x1E]; set => Data[Trainer1 + 0x1E] = (byte)value; } + public override int Game { get => Data[Trainer1 + 0x1F]; set => Data[Trainer1 + 0x1F] = (byte)value; } + public int Badges { get => Data[Trainer2 + 0x4]; set => Data[Trainer2 + 0x4] = (byte)value; } + public int M { get => BitConverter.ToInt32(Data, Trainer1 + 0x180); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x180); } + public int X { get => BitConverter.ToUInt16(Data, Trainer1 + 0x186); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x186); } + public int Z { get => BitConverter.ToUInt16(Data, Trainer1 + 0x18A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x18A); } + public int Y { get => BitConverter.ToUInt16(Data, Trainer1 + 0x18E); @@ -374,16 +408,19 @@ public override int PlayedHours get => BitConverter.ToUInt16(Data, Trainer1 + 0x24); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x24); } + public override int PlayedMinutes { get => Data[Trainer1 + 0x24 + 2]; set => Data[Trainer1 + 0x24 + 2] = (byte)value; } + public override int PlayedSeconds { get => Data[Trainer1 + 0x24 + 3]; set => Data[Trainer1 + 0x24 + 3] = (byte)value; } + public override int SecondsToStart { get => BitConverter.ToInt32(Data, AdventureInfo + 0x34); set => BitConverter.GetBytes(value).CopyTo(Data, AdventureInfo + 0x34); } public override int SecondsToFame { get => BitConverter.ToInt32(Data, AdventureInfo + 0x3C); set => BitConverter.GetBytes(value).CopyTo(Data, AdventureInfo + 0x3C); } @@ -394,19 +431,22 @@ public int BP } public ushort GetPWTRecord(int id) => GetPWTRecord((PWTRecordID) id); + public ushort GetPWTRecord(PWTRecordID id) { if (id < PWTRecordID.Normal || id > PWTRecordID.MixMaster) throw new ArgumentException(nameof(id)); - int ofs = 0x2375C + (int)id * 2; + int ofs = 0x2375C + ((int)id * 2); return BitConverter.ToUInt16(Data, ofs); } + public void SetPWTRecord(int id, ushort value) => SetPWTRecord((PWTRecordID) id, value); + public void SetPWTRecord(PWTRecordID id, ushort value) { if (id < PWTRecordID.Normal || id > PWTRecordID.MixMaster) throw new ArgumentException(nameof(id)); - int ofs = 0x2375C + (int)id * 2; + int ofs = 0x2375C + ((int)id * 2); SetData(BitConverter.GetBytes(value), ofs); } @@ -425,31 +465,31 @@ protected override void SetDex(PKM pkm) int bit = pkm.Species - 1; int gender = pkm.Gender % 2; // genderless -> male int shiny = pkm.IsShiny ? 1 : 0; - int shift = shiny*2 + gender + 1; - int shiftoff = shiny * brSize * 2 + gender * brSize + brSize; + int shift = (shiny * 2) + gender + 1; + int shiftoff = (shiny * brSize * 2) + (gender * brSize) + brSize; int ofs = PokeDex + 0x8 + (bit >> 3); // Set the Species Owned Flag - Data[ofs + brSize*0] |= (byte)(1 << (bit % 8)); + Data[ofs + (brSize * 0)] |= (byte)(1 << (bit % 8)); // Set the [Species/Gender/Shiny] Seen Flag - Data[PokeDex + 0x8 + shiftoff + bit / 8] |= (byte)(1 << (bit&7)); + Data[PokeDex + 0x8 + shiftoff + (bit / 8)] |= (byte)(1 << (bit&7)); // Set the Display flag if none are set bool Displayed = false; - Displayed |= (Data[ofs + brSize*5] & (byte)(1 << (bit&7))) != 0; - Displayed |= (Data[ofs + brSize*6] & (byte)(1 << (bit&7))) != 0; - Displayed |= (Data[ofs + brSize*7] & (byte)(1 << (bit&7))) != 0; - Displayed |= (Data[ofs + brSize*8] & (byte)(1 << (bit&7))) != 0; + Displayed |= (Data[ofs + (brSize * 5)] & (byte)(1 << (bit&7))) != 0; + Displayed |= (Data[ofs + (brSize * 6)] & (byte)(1 << (bit&7))) != 0; + Displayed |= (Data[ofs + (brSize * 7)] & (byte)(1 << (bit&7))) != 0; + Displayed |= (Data[ofs + (brSize * 8)] & (byte)(1 << (bit&7))) != 0; if (!Displayed) // offset is already biased by brSize, reuse shiftoff but for the display flags. - Data[ofs + brSize*(shift + 4)] |= (byte)(1 << (bit&7)); + Data[ofs + (brSize *(shift + 4))] |= (byte)(1 << (bit&7)); // Set the Language if (bit < 493) // shifted by 1, Gen5 species do not have international language bits { int lang = pkm.Language - 1; if (lang > 5) lang--; // 0-6 language vals if (lang < 0) lang = 1; - Data[PokeDexLanguageFlags + ((bit*7 + lang)>>3)] |= (byte)(1 << ((bit*7 + lang) & 7)); + Data[PokeDexLanguageFlags + (((bit * 7) + lang)>>3)] |= (byte)(1 << (((bit * 7) + lang) & 7)); } // Formes @@ -458,23 +498,23 @@ protected override void SetDex(PKM pkm) if (f < 0) return; int FormLen = B2W2 ? 0xB : 0x9; - int FormDex = PokeDex + 0x8 + brSize*9; + int FormDex = PokeDex + 0x8 + (brSize * 9); bit = f + pkm.AltForm; // Set Form Seen Flag - Data[FormDex + FormLen*shiny + (bit>>3)] |= (byte)(1 << (bit&7)); + Data[FormDex + (FormLen * shiny) + (bit>>3)] |= (byte)(1 << (bit&7)); // Set Displayed Flag if necessary, check all flags for (int i = 0; i < fc; i++) { bit = f + i; - if ((Data[FormDex + FormLen*2 + (bit>>3)] & (byte)(1 << (bit&7))) != 0) // Nonshiny + if ((Data[FormDex + (FormLen * 2) + (bit>>3)] & (byte)(1 << (bit&7))) != 0) // Nonshiny return; // already set - if ((Data[FormDex + FormLen*3 + (bit>>3)] & (byte)(1 << (bit&7))) != 0) // Shiny + if ((Data[FormDex + (FormLen * 3) + (bit>>3)] & (byte)(1 << (bit&7))) != 0) // Shiny return; // already set } bit = f + pkm.AltForm; - Data[FormDex + FormLen * (2 + shiny) + (bit>>3)] |= (byte)(1 << (bit&7)); + Data[FormDex + (FormLen * (2 + shiny)) + (bit>>3)] |= (byte)(1 << (bit&7)); } public override bool GetCaught(int species) @@ -486,6 +526,7 @@ public override bool GetCaught(int species) + 0x08; // Magic + Flags return (1 << bm & Data[ofs + bd]) != 0; } + public override bool GetSeen(int species) { const int brSize = 0x54; @@ -497,12 +538,16 @@ public override bool GetSeen(int species) + 0x08; // Magic + Flags for (int i = 1; i <= 4; i++) - if ((1 << bm & Data[ofs + bd + i * brSize]) != 0) + { + if ((1 << bm & Data[ofs + bd + (i * brSize)]) != 0) return true; + } + return false; } public override string GetString(int Offset, int Length) => StringConverter.GetString5(Data, Offset, Length); + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (PadToSize == 0) @@ -512,11 +557,13 @@ public override byte[] SetString(string value, int maxLength, int PadToSize = 0, // DLC private int CGearSkinInfoOffset => CGearInfoOffset + (B2W2 ? 0x10 : 0) + 0x24; + private bool CGearSkinPresent { get => Data[CGearSkinInfoOffset + 2] == 1; set => Data[CGearSkinInfoOffset + 2] = Data[Trainer1 + (B2W2 ? 0x6C : 0x54)] = (byte) (value ? 1 : 0); } + public byte[] CGearSkinData { get diff --git a/PKHeX.Core/Saves/SAV6.cs b/PKHeX.Core/Saves/SAV6.cs index ad146bbe3..2dc42343c 100644 --- a/PKHeX.Core/Saves/SAV6.cs +++ b/PKHeX.Core/Saves/SAV6.cs @@ -13,6 +13,7 @@ public sealed class SAV6 : SaveFile, ITrainerStatRecord protected override string BAKText => $"{OT} ({Version}) - {LastSavedTime}"; public override string Filter => "Main SAV|*.*"; public override string Extension => ""; + public SAV6(byte[] data = null) { Data = data ?? new byte[SaveUtil.SIZE_G6ORAS]; @@ -68,6 +69,7 @@ public SAV6(byte[] data = null) get => BitConverter.ToUInt64(Data, BlockInfoOffset - 0x14); set => BitConverter.GetBytes(value ?? 0).CopyTo(Data, BlockInfoOffset - 0x14); } + public override ulong? Secure2 { get => BitConverter.ToUInt64(Data, BlockInfoOffset - 0xC); @@ -201,7 +203,7 @@ private void GetSAVOffsets() else // Empty input { Party = 0x0; - Box = Party + SIZE_PARTY * 6 + 0x1000; + Box = Party + (SIZE_PARTY * 6) + 0x1000; } } @@ -251,27 +253,33 @@ public override int TID get => BitConverter.ToUInt16(Data, TrainerCard + 0); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, TrainerCard + 0); } + public override int SID { get => BitConverter.ToUInt16(Data, TrainerCard + 2); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, TrainerCard + 2); } + public override int Game { get => Data[TrainerCard + 4]; set => Data[TrainerCard + 4] = (byte)value; } + public override int Gender { get => Data[TrainerCard + 5]; set => Data[TrainerCard + 5] = (byte)value; } + public override int MultiplayerSpriteID { get => Data[TrainerCard + 7]; set => Data[TrainerCard + 7] = (byte)value; } + public override int GameSyncIDSize => 16; // 64 bits + public override string GameSyncID { get @@ -292,60 +300,71 @@ public override string GameSyncID .ToArray().CopyTo(Data, TrainerCard + 8); } } + public override int SubRegion { get => Data[TrainerCard + 0x26]; set => Data[TrainerCard + 0x26] = (byte)value; } + public override int Country { get => Data[TrainerCard + 0x27]; set => Data[TrainerCard + 0x27] = (byte)value; } + public override int ConsoleRegion { get => Data[TrainerCard + 0x2C]; set => Data[TrainerCard + 0x2C] = (byte)value; } + public override int Language { get => Data[TrainerCard + 0x2D]; set => Data[TrainerCard + 0x2D] = (byte)value; } + public override string OT { get => GetString(TrainerCard + 0x48, 0x1A); set => SetString(value, OTLength).CopyTo(Data, TrainerCard + 0x48); } + public string OT_Nick { get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x62, 0x1A)); set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x62); } + public string Saying1 { - get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + 0x22 * 0, 0x22)); - set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + 0x22 * 0); + get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + (0x22 * 0), 0x22)); + set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + (0x22 * 0)); } + public string Saying2 { - get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + 0x22 * 1, 0x22)); - set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + 0x22 * 1); + get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + (0x22 * 1), 0x22)); + set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + (0x22 * 1)); } + public string Saying3 { - get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + 0x22 * 2, 0x22)); - set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + 0x22 * 2); + get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + (0x22 * 2), 0x22)); + set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + (0x22 * 2)); } + public string Saying4 { - get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + 0x22 * 3, 0x22)); - set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + 0x22 * 3); + get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + (0x22 * 3), 0x22)); + set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + (0x22 * 3)); } + public string Saying5 { - get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + 0x22 * 4, 0x22)); - set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + 0x22 * 4); + get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, TrainerCard + 0x7C + (0x22 * 4), 0x22)); + set => Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, TrainerCard + 0x7C + (0x22 * 4)); } public short EyeColor @@ -353,11 +372,13 @@ public short EyeColor get => BitConverter.ToInt16(Data, TrainerCard + 0x148); set => BitConverter.GetBytes(value).CopyTo(Data, TrainerCard + 0x148); } + public bool IsMegaEvolutionUnlocked { get => (Data[TrainerCard + 0x14A] & 0x01) != 0; set => Data[TrainerCard + 0x14A] = (byte)((Data[TrainerCard + 0x14A] & 0xFE) | (value ? 1 : 0)); // in battle } + public bool IsMegaRayquazaUnlocked { get => (Data[TrainerCard + 0x14A] & 0x02) != 0; @@ -374,6 +395,7 @@ public int M val.CopyTo(Data, Trainer1 + 0x02 + 0xF4); } } + public float X { get => BitConverter.ToSingle(Data, Trainer1 + 0x10) / 18; @@ -384,6 +406,7 @@ public float X val.CopyTo(Data, Trainer1 + 0x10 + 0xF4); } } + public float Z { get => BitConverter.ToSingle(Data, Trainer1 + 0x14); @@ -394,6 +417,7 @@ public float Z val.CopyTo(Data, Trainer1 + 0x14 + 0xF4); } } + public float Y { get => BitConverter.ToSingle(Data, Trainer1 + 0x18) / 18; @@ -404,21 +428,25 @@ public float Y val.CopyTo(Data, Trainer1 + 0x18 + 0xF4); } } + public int Style { get => Data[Trainer1 + 0x14D]; set => Data[Trainer1 + 0x14D] = (byte)value; } + public override uint Money { get => BitConverter.ToUInt32(Data, Trainer2 + 0x8); set => BitConverter.GetBytes(value).CopyTo(Data, Trainer2 + 0x8); } + public int Badges { get => Data[Trainer2 + 0xC]; set => Data[Trainer2 + 0xC] = (byte)value; } + public int BP { get @@ -434,6 +462,7 @@ public int BP BitConverter.GetBytes((ushort)value).CopyTo(Data, offset); } } + public int Vivillon { get @@ -455,23 +484,27 @@ public override int PlayedHours get => BitConverter.ToUInt16(Data, PlayTime); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, PlayTime); } + public override int PlayedMinutes { get => Data[PlayTime + 2]; set => Data[PlayTime + 2] = (byte)value; } + public override int PlayedSeconds { get => Data[PlayTime + 3]; set => Data[PlayTime + 3] = (byte)value; } + private uint LastSaved { get => BitConverter.ToUInt32(Data, PlayTime + 0x4); set => BitConverter.GetBytes(value).CopyTo(Data, PlayTime + 0x4); } - private int LastSavedYear { get => (int)(LastSaved & 0xFFF); set => LastSaved = LastSaved & 0xFFFFF000 | (uint)value; } - private int LastSavedMonth { get => (int)(LastSaved >> 12 & 0xF); set => LastSaved = LastSaved & 0xFFFF0FFF | ((uint)value & 0xF) << 12; } - private int LastSavedDay { get => (int)(LastSaved >> 16 & 0x1F); set => LastSaved = LastSaved & 0xFFE0FFFF | ((uint)value & 0x1F) << 16; } - private int LastSavedHour { get => (int)(LastSaved >> 21 & 0x1F); set => LastSaved = LastSaved & 0xFC1FFFFF | ((uint)value & 0x1F) << 21; } - private int LastSavedMinute { get => (int)(LastSaved >> 26 & 0x3F); set => LastSaved = LastSaved & 0x03FFFFFF | ((uint)value & 0x3F) << 26; } + private int LastSavedYear { get => (int)(LastSaved & 0xFFF); set => LastSaved = (LastSaved & 0xFFFFF000) | (uint)value; } + private int LastSavedMonth { get => (int)(LastSaved >> 12 & 0xF); set => LastSaved = (LastSaved & 0xFFFF0FFF) | ((uint)value & 0xF) << 12; } + private int LastSavedDay { get => (int)(LastSaved >> 16 & 0x1F); set => LastSaved = (LastSaved & 0xFFE0FFFF) | ((uint)value & 0x1F) << 16; } + private int LastSavedHour { get => (int)(LastSaved >> 21 & 0x1F); set => LastSaved = (LastSaved & 0xFC1FFFFF) | ((uint)value & 0x1F) << 21; } + private int LastSavedMinute { get => (int)(LastSaved >> 26 & 0x3F); set => LastSaved = (LastSaved & 0x03FFFFFF) | ((uint)value & 0x3F) << 26; } private string LastSavedTime => $"{LastSavedYear:0000}{LastSavedMonth:00}{LastSavedDay:00}{LastSavedHour:00}{LastSavedMinute:00}"; + public DateTime? LastSavedDate { get => !Util.IsDateValid(LastSavedYear, LastSavedMonth, LastSavedDay) @@ -510,35 +543,39 @@ public override int PlayedSeconds public override int SecondsToStart { get => BitConverter.ToInt32(Data, AdventureInfo + 0x18); set => BitConverter.GetBytes(value).CopyTo(Data, AdventureInfo + 0x18); } public override int SecondsToFame { get => BitConverter.ToInt32(Data, AdventureInfo + 0x20); set => BitConverter.GetBytes(value).CopyTo(Data, AdventureInfo + 0x20); } - public ushort GetMaisonStat(int index) { return BitConverter.ToUInt16(Data, MaisonStats + 2 * index); } - public void SetMaisonStat(int index, ushort value) { BitConverter.GetBytes(value).CopyTo(Data, MaisonStats + 2*index); } - public uint GetEncounterCount(int index) { return BitConverter.ToUInt16(Data, EncounterCount + 2*index); } - public void SetEncounterCount(int index, ushort value) { BitConverter.GetBytes(value).CopyTo(Data, EncounterCount + 2*index); } + public ushort GetMaisonStat(int index) { return BitConverter.ToUInt16(Data, MaisonStats + (2 * index)); } + public void SetMaisonStat(int index, ushort value) { BitConverter.GetBytes(value).CopyTo(Data, MaisonStats + (2 * index)); } + public uint GetEncounterCount(int index) { return BitConverter.ToUInt16(Data, EncounterCount + (2 * index)); } + public void SetEncounterCount(int index, ushort value) { BitConverter.GetBytes(value).CopyTo(Data, EncounterCount + (2 * index)); } // Daycare public override int DaycareSeedSize => 16; public override bool HasTwoDaycares => ORAS; + public override int GetDaycareSlotOffset(int loc, int slot) { int ofs = loc == 0 ? Daycare : Daycare2; if (ofs < 0) return -1; - return ofs + 8 + slot*(SIZE_STORED + 8); + return ofs + 8 + (slot *(SIZE_STORED + 8)); } + public override uint? GetDaycareEXP(int loc, int slot) { int ofs = loc == 0 ? Daycare : Daycare2; if (ofs > -1) - return BitConverter.ToUInt32(Data, ofs + (SIZE_STORED + 8)*slot + 4); + return BitConverter.ToUInt32(Data, ofs + ((SIZE_STORED + 8)*slot) + 4); return null; } + public override bool? IsDaycareOccupied(int loc, int slot) { int ofs = loc == 0 ? Daycare : Daycare2; if (ofs > -1) - return Data[ofs + (SIZE_STORED + 8) * slot] == 1; + return Data[ofs + ((SIZE_STORED + 8) * slot)] == 1; return null; } + public override string GetDaycareRNGSeed(int loc) { int ofs = loc == 0 ? Daycare : Daycare2; @@ -548,6 +585,7 @@ public override string GetDaycareRNGSeed(int loc) var data = Data.Skip(ofs + 0x1E8).Take(DaycareSeedSize/2).Reverse().ToArray(); return BitConverter.ToString(data).Replace("-", ""); } + public override bool? IsDaycareHasEgg(int loc) { int ofs = loc == 0 ? Daycare : Daycare2; @@ -555,18 +593,21 @@ public override string GetDaycareRNGSeed(int loc) return Data[ofs + 0x1E0] == 1; return null; } + public override void SetDaycareEXP(int loc, int slot, uint EXP) { int ofs = loc == 0 ? Daycare : Daycare2; if (ofs > -1) - BitConverter.GetBytes(EXP).CopyTo(Data, ofs + (SIZE_STORED + 8)*slot + 4); + BitConverter.GetBytes(EXP).CopyTo(Data, ofs + ((SIZE_STORED + 8)*slot) + 4); } + public override void SetDaycareOccupied(int loc, int slot, bool occupied) { int ofs = loc == 0 ? Daycare : Daycare2; if (ofs > -1) - Data[ofs + (SIZE_STORED + 8)*slot] = (byte) (occupied ? 1 : 0); + Data[ofs + ((SIZE_STORED + 8)*slot)] = (byte) (occupied ? 1 : 0); } + public override void SetDaycareRNGSeed(int loc, string seed) { if (loc != 0) @@ -583,6 +624,7 @@ public override void SetDaycareRNGSeed(int loc, string seed) .Select(x => Convert.ToByte(seed.Substring(x, 2), 16)) .Reverse().ToArray().CopyTo(Data, Daycare + 0x1E8); } + public override void SetDaycareHasEgg(int loc, bool hasEgg) { int ofs = loc == 0 ? Daycare : Daycare2; @@ -600,7 +642,7 @@ public int[] SelectItems { int[] list = new int[4]; for (int i = 0; i < list.Length; i++) - list[i] = BitConverter.ToUInt16(Data, ItemInfo + 10 + 2 * i); + list[i] = BitConverter.ToUInt16(Data, ItemInfo + 10 + (2 * i)); return list; } set @@ -608,9 +650,10 @@ public int[] SelectItems if (value == null || value.Length > 4) return; for (int i = 0; i < value.Length; i++) - BitConverter.GetBytes((ushort)value[i]).CopyTo(Data, ItemInfo + 10 + 2 * i); + BitConverter.GetBytes((ushort)value[i]).CopyTo(Data, ItemInfo + 10 + (2 * i)); } } + public int[] RecentItems { // Items recently interacted with (Give, Use) @@ -618,7 +661,7 @@ public int[] RecentItems { int[] list = new int[12]; for (int i = 0; i < list.Length; i++) - list[i] = BitConverter.ToUInt16(Data, ItemInfo + 20 + 2 * i); + list[i] = BitConverter.ToUInt16(Data, ItemInfo + 20 + (2 * i)); return list; } set @@ -626,7 +669,7 @@ public int[] RecentItems if (value == null || value.Length > 12) return; for (int i = 0; i < value.Length; i++) - BitConverter.GetBytes((ushort)value[i]).CopyTo(Data, ItemInfo + 20 + 2 * i); + BitConverter.GetBytes((ushort)value[i]).CopyTo(Data, ItemInfo + 20 + (2 * i)); } } @@ -663,14 +706,17 @@ public override InventoryPouch[] Inventory // Storage public override int CurrentBox { get => Data[LastViewedBox]; set => Data[LastViewedBox] = (byte)value; } + public override int GetPartyOffset(int slot) { - return Party + SIZE_PARTY * slot; + return Party + (SIZE_PARTY * slot); } + public override int GetBoxOffset(int box) { - return Box + SIZE_STORED*box*30; + return Box + (SIZE_STORED *box*30); } + protected override int GetBoxWallpaperOffset(int box) { int ofs = PCBackgrounds > 0 && PCBackgrounds < Data.Length ? PCBackgrounds : -1; @@ -678,21 +724,25 @@ protected override int GetBoxWallpaperOffset(int box) return ofs + box; return ofs; } + public override string GetBoxName(int box) { if (PCLayout < 0) return "B" + (box + 1); - return Util.TrimFromZero(Encoding.Unicode.GetString(Data, PCLayout + 0x22*box, 0x22)); + return Util.TrimFromZero(Encoding.Unicode.GetString(Data, PCLayout + (0x22 * box), 0x22)); } + public override void SetBoxName(int box, string value) { - Encoding.Unicode.GetBytes(value.PadRight(0x11, '\0')).CopyTo(Data, PCLayout + 0x22*box); + Encoding.Unicode.GetBytes(value.PadRight(0x11, '\0')).CopyTo(Data, PCLayout + (0x22 * box)); Edited = true; } + public override PKM GetPKM(byte[] data) { return new PK6(data); } + protected override void SetPKM(PKM pkm) { PK6 pk6 = (PK6)pkm; @@ -710,6 +760,7 @@ protected override void SetPKM(PKM pkm) } pkm.RefreshChecksum(); } + protected override void SetDex(PKM pkm) { if (PokeDex < 0) @@ -727,7 +778,7 @@ protected override void SetDex(PKM pkm) int origin = pkm.Version; int gender = pkm.Gender % 2; // genderless -> male int shiny = pkm.IsShiny ? 1 : 0; - int shiftoff = brSize*(1 + gender + 2*shiny); // after the Owned region + int shiftoff = brSize*(1 + gender + (2 * shiny)); // after the Owned region int bd = bit >> 3; // div8 int bm = bit & 7; // mod8 byte mask = (byte)(1 << bm); @@ -737,23 +788,23 @@ protected override void SetDex(PKM pkm) if (origin < 0x18 && bit < 649 && !ORAS) // Species: 1-649 for X/Y, and not for ORAS; Set the Foreign Owned Flag Data[ofs + 0x644] |= mask; else if (origin >= 0x18 || ORAS) // Set Native Owned Flag (should always happen) - Data[ofs + brSize * 0] |= mask; + Data[ofs + (brSize * 0)] |= mask; // Set the [Species/Gender/Shiny] Seen Flag Data[ofs + shiftoff] |= mask; // Set the Display flag if none are set bool Displayed = false; - Displayed |= (Data[ofs + brSize * 5] & mask) != 0; - Displayed |= (Data[ofs + brSize * 6] & mask) != 0; - Displayed |= (Data[ofs + brSize * 7] & mask) != 0; - Displayed |= (Data[ofs + brSize * 8] & mask) != 0; + Displayed |= (Data[ofs + (brSize * 5)] & mask) != 0; + Displayed |= (Data[ofs + (brSize * 6)] & mask) != 0; + Displayed |= (Data[ofs + (brSize * 7)] & mask) != 0; + Displayed |= (Data[ofs + (brSize * 8)] & mask) != 0; if (!Displayed) // offset is already biased by brSize, reuse shiftoff but for the display flags. - Data[ofs + brSize * 4 + shiftoff] |= mask; + Data[ofs + (brSize * 4) + shiftoff] |= mask; // Set the Language if (lang < 0) lang = 1; - Data[PokeDexLanguageFlags + (bit * 7 + lang) / 8] |= (byte)(1 << ((bit * 7 + lang) % 8)); + Data[PokeDexLanguageFlags + (((bit * 7) + lang) / 8)] |= (byte)(1 << (((bit * 7) + lang) % 8)); // Set DexNav count (only if not encountered previously) if (ORAS && GetEncounterCount(pkm.Species - 1) == 0) @@ -765,29 +816,31 @@ protected override void SetDex(PKM pkm) if (f < 0) return; int FormLen = ORAS ? 0x26 : 0x18; - int FormDex = PokeDex + 0x8 + brSize*9; + int FormDex = PokeDex + 0x8 + (brSize * 9); bit = f + pkm.AltForm; // Set Form Seen Flag - Data[FormDex + FormLen*shiny + bit/8] |= (byte)(1 << (bit%8)); + 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 + 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 + 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)); + Data[FormDex + (FormLen * (2 + shiny)) + (bit / 8)] |= (byte)(1 << (bit % 8)); } + protected override void SetPartyValues(PKM pkm, bool isParty) { base.SetPartyValues(pkm, isParty); ((PK6)pkm).FormDuration = GetFormDuration(pkm, isParty); } + private static uint GetFormDuration(PKM pkm, bool isParty) { if (!isParty || pkm.AltForm == 0) @@ -828,25 +881,30 @@ public override bool GetSeen(int species) + 0x08; // Magic + Flags for (int i = 1; i <= 4; i++) // check all 4 seen flags (gender/shiny) - if ((Data[ofs + bd + i * brSize] & mask) != 0) + if ((Data[ofs + bd + (i * brSize)] & mask) != 0) return true; return false; } + public override byte[] DecryptPKM(byte[] data) { return PKX.DecryptArray(data); } + public override int PartyCount { - get => Data[Party + 6 * SIZE_PARTY]; - protected set => Data[Party + 6 * SIZE_PARTY] = (byte)value; + get => Data[Party + (6 * SIZE_PARTY)]; + protected set => Data[Party + (6 * SIZE_PARTY)] = (byte)value; } + public override bool BattleBoxLocked { - get => Data[BattleBox + 6 * SIZE_STORED] != 0; - set => Data[BattleBox + 6 * SIZE_STORED] = (byte)(value ? 1 : 0); + get => Data[BattleBox + (6 * SIZE_STORED)] != 0; + set => Data[BattleBox + (6 * SIZE_STORED)] = (byte)(value ? 1 : 0); } + public override int BoxesUnlocked { get => Data[PCFlags + 1] - 1; set => Data[PCFlags + 1] = (byte)(value + 1); } + public override byte[] BoxFlags { get => new[] { Data[PCFlags] }; // 7 bits for wallpaper unlocks, top bit to unlock final box (delta episode) @@ -887,6 +945,7 @@ protected override bool[] MysteryGiftReceivedFlags Edited = true; } } + protected override MysteryGift[] MysteryGiftCards { get @@ -938,8 +997,9 @@ private MysteryGift GetWC6(int index) if (index < 0 || index > GiftCountMax) return null; - return new WC6(GetData(WondercardData + index * WC6.Size, WC6.Size)); + return new WC6(GetData(WondercardData + (index * WC6.Size), WC6.Size)); } + private void SetWC6(MysteryGift wc6, int index) { if (WondercardData < 0) @@ -947,7 +1007,7 @@ private void SetWC6(MysteryGift wc6, int index) if (index < 0 || index > GiftCountMax) return; - wc6.Data.CopyTo(Data, WondercardData + index * WC6.Size); + wc6.Data.CopyTo(Data, WondercardData + (index * WC6.Size)); Edited = true; } @@ -1008,9 +1068,11 @@ public override string MiscSaveChecks() } return r; } + public override string MiscSaveInfo() => string.Join(Environment.NewLine, Blocks.Select(b => b.Summary)); public override string GetString(int Offset, int Length) => StringConverter.GetString6(Data, Offset, Length); + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (PadToSize == 0) @@ -1059,6 +1121,7 @@ public void UnlockAllAccessories() } public int RecordCount => 200; + public int GetRecord(int recordID) { int ofs = Records.GetOffset(Record, recordID); @@ -1068,6 +1131,7 @@ public int GetRecord(int recordID) return BitConverter.ToInt16(Data, ofs); return 0; } + public void SetRecord(int recordID, int value) { int ofs = Records.GetOffset(Record, recordID); @@ -1080,6 +1144,7 @@ public void SetRecord(int recordID, int value) if (recordID < 200) BitConverter.GetBytes((ushort)value).CopyTo(Data, ofs); } + public int GetRecordMax(int recordID) => Records.GetMax(recordID, XY ? Records.MaxType_XY : Records.MaxType_AO); public int GetRecordOffset(int recordID) => Records.GetOffset(Record, recordID); } diff --git a/PKHeX.Core/Saves/SAV7.cs b/PKHeX.Core/Saves/SAV7.cs index 6662b1780..562d14b8c 100644 --- a/PKHeX.Core/Saves/SAV7.cs +++ b/PKHeX.Core/Saves/SAV7.cs @@ -14,6 +14,7 @@ public sealed class SAV7 : SaveFile, ITrainerStatRecord protected override string BAKText => $"{OT} ({Version}) - {LastSavedTime}"; public override string Filter => "Main SAV|*.*"; public override string Extension => ""; + public override string[] PKMExtensions => PKM.Extensions.Where(f => { int gen = f.Last() - 0x30; @@ -86,6 +87,7 @@ public SAV7(byte[] data = null) private const int MemeCryptoBlock = 36; public override bool ChecksumsValid => CanReadChecksums() && Blocks.GetChecksumsValid(Data); public override string ChecksumInfo => CanReadChecksums() ? Blocks.GetChecksumInfo(Data) : string.Empty; + private bool CanReadChecksums() { if (Blocks.Length <= MemeCryptoBlock) @@ -97,6 +99,7 @@ private bool CanReadChecksums() IsMemeCryptoApplied = false; return true; } + protected override void SetChecksums() { if (!CanReadChecksums()) @@ -111,6 +114,7 @@ protected override void SetChecksums() get => BitConverter.ToUInt64(Data, BlockInfoOffset - 0x14); set => BitConverter.GetBytes(value ?? 0).CopyTo(Data, BlockInfoOffset - 0x14); } + public override ulong? Secure2 { get => BitConverter.ToUInt64(Data, BlockInfoOffset - 0xC); @@ -172,8 +176,8 @@ private void GetSAVOffsets() /* 35 */ QRSaveData = Blocks[35].Offset; // 0x6B800 // [1C8] QRReaderSaveData /* 36 */ // = Blocks[36].Offset; // 0x6BA00 // [200] TurtleSalmonSave - EventFlag = EventConst + EventConstMax * 2; // After Event Const (u16)*n - HoF = EventFlag + EventFlagMax / 8; // After Event Flags (1b)*(1u8/8b)*n + EventFlag = EventConst + (EventConstMax * 2); // After Event Const (u16)*n + HoF = EventFlag + (EventFlagMax / 8); // After Event Flags (1b)*(1u8/8b)*n OFS_PouchHeldItem = Bag + 0; // 430 (Case 0) OFS_PouchKeyItem = Bag + 0x6B8; // 184 (Case 4) @@ -202,12 +206,12 @@ private void GetSAVOffsets() /* 38 */ // = Blocks[38].Offset; FinderStudioSave OFS_PouchHeldItem = Bag + 0; // 427 (Case 0) - OFS_PouchKeyItem = OFS_PouchHeldItem + 4*427; // 198 (Case 4) - OFS_PouchTMHM = OFS_PouchKeyItem + 4*198; // 108 (Case 2) - OFS_PouchMedicine = OFS_PouchTMHM + 4*108; // 60 (Case 1) - OFS_PouchBerry = OFS_PouchMedicine + 4*60; // 67 (Case 3) - OFS_PouchZCrystals = OFS_PouchBerry + 4*67; // 35 (Case 5) - OFS_BattleItems = OFS_PouchZCrystals + 4*35; // 11 (Case 6) + OFS_PouchKeyItem = OFS_PouchHeldItem + (4 * 427); // 198 (Case 4) + OFS_PouchTMHM = OFS_PouchKeyItem + (4 * 198); // 108 (Case 2) + OFS_PouchMedicine = OFS_PouchTMHM + (4 * 108); // 60 (Case 1) + OFS_PouchBerry = OFS_PouchMedicine + (4 * 60); // 67 (Case 3) + OFS_PouchZCrystals = OFS_PouchBerry + (4 * 67); // 35 (Case 5) + OFS_BattleItems = OFS_PouchZCrystals + (4 * 35); // 11 (Case 6) } } @@ -238,7 +242,8 @@ private void GetSAVOffsets() private int Record { get; set; } = int.MinValue; public const int ResortCount = 93; - public int GetResortSlotOffset(int slot) => Resort + 0x16 + slot * SIZE_STORED; + public int GetResortSlotOffset(int slot) => Resort + 0x16 + (slot * SIZE_STORED); + public PKM[] ResortPKM { get @@ -282,22 +287,27 @@ public override int TID get => BitConverter.ToUInt16(Data, TrainerCard + 0); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, TrainerCard + 0); } + public override int SID { get => BitConverter.ToUInt16(Data, TrainerCard + 2); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, TrainerCard + 2); } + public override int Game { get => Data[TrainerCard + 4]; set => Data[TrainerCard + 4] = (byte)value; } + public override int Gender { get => Data[TrainerCard + 5]; set => Data[TrainerCard + 5] = (byte)value; } + public override int GameSyncIDSize => 16; // 64 bits + public override string GameSyncID { get @@ -319,7 +329,9 @@ public override string GameSyncID .ToArray().CopyTo(Data, TrainerCard + 0x10); } } + private const int NexUniqueIDSize = 32; // 128 bits + public string NexUniqueID { get @@ -341,6 +353,7 @@ public string NexUniqueID .ToArray().CopyTo(Data, TrainerCard + 0x18); } } + public byte[] FestaID // 12byte { get => Data.Skip(TrainerCard + 0x28).Take(4).Concat(Data.Skip(TrainerCard + 0x18).Take(8)).ToArray(); @@ -351,51 +364,61 @@ public string NexUniqueID Array.Copy(value, 4, Data, TrainerCard + 0x18, 8); } } + public override int SubRegion { get => Data[TrainerCard + 0x2E]; set => Data[TrainerCard + 0x2E] = (byte)value; } + public override int Country { get => Data[TrainerCard + 0x2F]; set => Data[TrainerCard + 0x2F] = (byte)value; } + public override int ConsoleRegion { get => Data[TrainerCard + 0x34]; set => Data[TrainerCard + 0x34] = (byte)value; } + public override int Language { get => Data[TrainerCard + 0x35]; set => Data[TrainerCard + 0x35] = (byte)value; } + public override string OT { get => GetString(TrainerCard + 0x38, 0x1A); set => SetString(value, OTLength).CopyTo(Data, TrainerCard + 0x38); } + public int DressUpSkinColor { get => (Data[TrainerCard + 0x54] >> 2) & 7; set => Data[TrainerCard + 0x54] = (byte)((Data[TrainerCard + 0x54] & ~(7 << 2)) | (value << 2)); } + public override int MultiplayerSpriteID { get => Data[TrainerCard + 0x58]; set => Data[TrainerCard + 0x58] = (byte)value; } + public int BallThrowType { get => Data[TrainerCard + 0x7A]; set => Data[TrainerCard + 0x7A] = (byte)(value > 8 ? 0 : value); } + public int M // "StartLocation" { get => BitConverter.ToUInt16(Data, Trainer1 + 0x00); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x00); } + public float X { get => BitConverter.ToSingle(Data, Trainer1 + 0x08); @@ -405,6 +428,7 @@ public float X BitConverter.GetBytes(value).CopyTo(Data, Overworld + 0x08); } } + public float Z { get => BitConverter.ToSingle(Data, Trainer1 + 0x10); @@ -414,6 +438,7 @@ public float Z BitConverter.GetBytes(value).CopyTo(Data, Overworld + 0x10); } } + public float Y { get => (int)BitConverter.ToSingle(Data, Trainer1 + 0x18); @@ -423,6 +448,7 @@ public float Y BitConverter.GetBytes(value).CopyTo(Data, Overworld + 0x18); } } + public float R { get => (int)BitConverter.ToSingle(Data, Trainer1 + 0x20); @@ -432,31 +458,37 @@ public float R BitConverter.GetBytes(value).CopyTo(Data, Overworld + 0x20); } } + public int SpecialLocation { get => Data[Trainer1 + 0x24]; set => Data[Trainer1 + 0x24] = (byte)value; } + public int WarpContinueRequest { get => Data[Trainer1 + 0x6E]; set => Data[Trainer1 + 0x6E] = (byte)value; } + public int StepCountEgg { get => BitConverter.ToInt32(Data, Trainer1 + 0x70); set => BitConverter.GetBytes(value).CopyTo(Data, Trainer1 + 0x70); } + public int LastZoneID { get => BitConverter.ToUInt16(Data, Trainer1 + 0x74); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x74); } + public int StepCountFriendship { get => BitConverter.ToUInt16(Data, Trainer1 + 0x76); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0x76); } + public int StepCountAffection // Kawaigari { get => BitConverter.ToUInt16(Data, Trainer1 + 0x78); @@ -468,33 +500,38 @@ public int ConfigValue get => BitConverter.ToInt32(Data, ConfigSave); set => BitConverter.GetBytes(value).CopyTo(Data, ConfigSave); } + public int TalkingSpeed { get => ConfigValue & 3; - set => ConfigValue = ConfigValue & ~3 | (value & 3); + set => ConfigValue = (ConfigValue & ~3) | (value & 3); } + public int BattleAnimation { // Effects OFF = 1, Effects ON = 0 get => (ConfigValue >> 2) & 1; - set => ConfigValue = ConfigValue & ~(1<<2) | (value << 2); + set => ConfigValue = (ConfigValue & ~(1<<2)) | (value << 2); } + public int BattleStyle { // SET = 1, SWITCH = 0 get => (ConfigValue >> 3) & 1; - set => ConfigValue = ConfigValue & ~(1 << 3) | (value << 3); + set => ConfigValue = (ConfigValue & ~(1 << 3)) | (value << 3); } + public int ButtonMode { get => (ConfigValue >> 13) & 3; - set => ConfigValue = ConfigValue & ~(1 << 13) | (value << 13); + set => ConfigValue = (ConfigValue & ~(1 << 13)) | (value << 13); } + public int BoxStatus { // MANUAL = 1, AUTOMATIC = 0 get => (ConfigValue >> 15) & 1; - set => ConfigValue = ConfigValue & ~(1 << 15) | (value << 15); + set => ConfigValue = (ConfigValue & ~(1 << 15)) | (value << 15); } public override uint Money @@ -506,6 +543,7 @@ public override uint Money BitConverter.GetBytes(value).CopyTo(Data, Misc + 0x4); } } + public uint Stamps { get => (BitConverter.ToUInt32(Data, Misc + 0x08) << 13) >> 17; // 15 stamps; discard top13, lowest4 @@ -516,6 +554,7 @@ public uint Stamps BitConverter.GetBytes(flags).CopyTo(Data, Misc + 0x08); } } + public uint BP { get => BitConverter.ToUInt32(Data, Misc + 0x11C); @@ -525,21 +564,25 @@ public uint BP BitConverter.GetBytes(value).CopyTo(Data, Misc + 0x11C); } } + public int Vivillon { get => Data[Misc + 0x130] & 0x1F; set => Data[Misc + 0x130] = (byte)((Data[Misc + 0x130] & ~0x1F) | (value & 0x1F)); } + public uint StarterEncryptionConstant { get => BitConverter.ToUInt32(Data, Misc + 0x148); set => SetData(BitConverter.GetBytes(value), Misc + 0x148); } + public int DaysFromRefreshed { get => Data[Misc + 0x123]; set => Data[Misc + 0x123] = (byte)value; } + public uint UsedFestaCoins { get => BitConverter.ToUInt32(Data, Record + (38 << 2)); //Record[038] @@ -549,6 +592,7 @@ public uint UsedFestaCoins BitConverter.GetBytes(value).CopyTo(Data, Record + (38 << 2)); } } + public uint FestaCoins { get => BitConverter.ToUInt32(Data, JoinFestaData + 0x508); @@ -560,6 +604,7 @@ public uint FestaCoins TotalFestaCoins = UsedFestaCoins + value; } } + private uint TotalFestaCoins { get => BitConverter.ToUInt32(Data, JoinFestaData + 0x50C); @@ -569,6 +614,7 @@ private uint TotalFestaCoins BitConverter.GetBytes(value).CopyTo(Data, JoinFestaData + 0x50C); } } + public string FestivalPlazaName { get => Util.TrimFromZero(Encoding.Unicode.GetString(Data, JoinFestaData + 0x510, 0x2A)); @@ -579,14 +625,17 @@ public string FestivalPlazaName Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, JoinFestaData + 0x510); } } + public ushort FestaRank { get => BitConverter.ToUInt16(Data, JoinFestaData + 0x53A); set => BitConverter.GetBytes(value).CopyTo(Data, JoinFestaData + 0x53A); } - public ushort GetFestaMessage(int index) => BitConverter.ToUInt16(Data, JoinFestaData + index * 2); - public void SetFestaMessage(int index, ushort value) => BitConverter.GetBytes(value).CopyTo(Data, JoinFestaData + index * 2); + public ushort GetFestaMessage(int index) => BitConverter.ToUInt16(Data, JoinFestaData + (index * 2)); + public void SetFestaMessage(int index, ushort value) => BitConverter.GetBytes(value).CopyTo(Data, JoinFestaData + (index * 2)); public bool GetFestaPhraseUnlocked(int index) => Data[JoinFestaData + 0x2A50 + index] != 0; //index: 0 to 105:commonPhrases, 106:Lv100! + public void SetFestaPhraseUnlocked(int index, bool value) { if (GetFestaPhraseUnlocked(index) != value) Data[JoinFestaData + 0x2A50 + index] = (byte)(value ? 1 : 0); } + public byte GetFestPrizeReceived(int index) => Data[JoinFestaData + 0x53C + index]; public void SetFestaPrizeReceived(int index, byte value) => Data[JoinFestaData + 0x53C + index] = value; private int FestaYear { get => BitConverter.ToInt32(Data, JoinFestaData + 0x2F0); set => BitConverter.GetBytes(value).CopyTo(Data, JoinFestaData + 0x2F0); } @@ -595,6 +644,7 @@ public void SetFestaPhraseUnlocked(int index, bool value) private int FestaHour { get => BitConverter.ToInt32(Data, JoinFestaData + 0x300); set => BitConverter.GetBytes(value).CopyTo(Data, JoinFestaData + 0x300); } private int FestaMinute { get => BitConverter.ToInt32(Data, JoinFestaData + 0x304); set => BitConverter.GetBytes(value).CopyTo(Data, JoinFestaData + 0x304); } private int FestaSecond { get => BitConverter.ToInt32(Data, JoinFestaData + 0x308); set => BitConverter.GetBytes(value).CopyTo(Data, JoinFestaData + 0x308); } + public DateTime? FestaDate { get => FestaYear >= 0 && FestaMonth > 0 && FestaDay > 0 && FestaHour >= 0 && FestaMinute >= 0 && FestaSecond >= 0 && Util.IsDateValid(FestaYear, FestaMonth, FestaDay) @@ -614,11 +664,13 @@ public void SetFestaPhraseUnlocked(int index, bool value) } } } + public sealed class FashionItem { public bool IsOwned; public bool IsNew; } + public FashionItem[] Wardrobe { get @@ -639,23 +691,27 @@ public override int PlayedHours get => BitConverter.ToUInt16(Data, PlayTime); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, PlayTime); } + public override int PlayedMinutes { get => Data[PlayTime + 2]; set => Data[PlayTime + 2] = (byte)value; } + public override int PlayedSeconds { get => Data[PlayTime + 3]; set => Data[PlayTime + 3] = (byte)value; } + private uint LastSaved { get => BitConverter.ToUInt32(Data, PlayTime + 0x4); set => BitConverter.GetBytes(value).CopyTo(Data, PlayTime + 0x4); } - private int LastSavedYear { get => (int)(LastSaved & 0xFFF); set => LastSaved = LastSaved & 0xFFFFF000 | (uint)value; } - private int LastSavedMonth { get => (int)(LastSaved >> 12 & 0xF); set => LastSaved = LastSaved & 0xFFFF0FFF | ((uint)value & 0xF) << 12; } - private int LastSavedDay { get => (int)(LastSaved >> 16 & 0x1F); set => LastSaved = LastSaved & 0xFFE0FFFF | ((uint)value & 0x1F) << 16; } - private int LastSavedHour { get => (int)(LastSaved >> 21 & 0x1F); set => LastSaved = LastSaved & 0xFC1FFFFF | ((uint)value & 0x1F) << 21; } - private int LastSavedMinute { get => (int)(LastSaved >> 26 & 0x3F); set => LastSaved = LastSaved & 0x03FFFFFF | ((uint)value & 0x3F) << 26; } + private int LastSavedYear { get => (int)(LastSaved & 0xFFF); set => LastSaved = (LastSaved & 0xFFFFF000) | (uint)value; } + private int LastSavedMonth { get => (int)(LastSaved >> 12 & 0xF); set => LastSaved = (LastSaved & 0xFFFF0FFF) | ((uint)value & 0xF) << 12; } + private int LastSavedDay { get => (int)(LastSaved >> 16 & 0x1F); set => LastSaved = (LastSaved & 0xFFE0FFFF) | ((uint)value & 0x1F) << 16; } + private int LastSavedHour { get => (int)(LastSaved >> 21 & 0x1F); set => LastSaved = (LastSaved & 0xFC1FFFFF) | ((uint)value & 0x1F) << 21; } + private int LastSavedMinute { get => (int)(LastSaved >> 26 & 0x3F); set => LastSaved = (LastSaved & 0x03FFFFFF) | ((uint)value & 0x3F) << 26; } private string LastSavedTime => $"{LastSavedYear:0000}{LastSavedMonth:00}{LastSavedDay:00}{LastSavedHour:00}{LastSavedMinute:00}"; + public DateTime? LastSavedDate { get => !Util.IsDateValid(LastSavedYear, LastSavedMonth, LastSavedDay) @@ -698,6 +754,7 @@ public override int PlayedSeconds // Stat Records public int RecordCount => 200; + public int GetRecord(int recordID) { int ofs = Records.GetOffset(Record, recordID); @@ -707,6 +764,7 @@ public int GetRecord(int recordID) return BitConverter.ToInt16(Data, ofs); return 0; } + public void SetRecord(int recordID, int value) { int ofs = Records.GetOffset(Record, recordID); @@ -719,6 +777,7 @@ public void SetRecord(int recordID, int value) if (recordID < 200) BitConverter.GetBytes((ushort)value).CopyTo(Data, ofs); } + public int GetRecordMax(int recordID) => Records.GetMax(recordID, USUM ? Records.MaxType_USUM : Records.MaxType_SM); public int GetRecordOffset(int recordID) => Records.GetOffset(Record, recordID); @@ -727,11 +786,13 @@ public ushort PokeFinderCameraVersion get => BitConverter.ToUInt16(Data, PokeFinderSave + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, PokeFinderSave + 0x00); } + public bool PokeFinderGyroFlag { get => BitConverter.ToUInt16(Data, PokeFinderSave + 0x02) == 1; set => BitConverter.GetBytes((ushort)(value ? 1 : 0)).CopyTo(Data, PokeFinderSave + 0x02); } + public uint PokeFinderSnapCount { get => BitConverter.ToUInt32(Data, PokeFinderSave + 0x04); @@ -742,11 +803,13 @@ public uint PokeFinderSnapCount BitConverter.GetBytes(value).CopyTo(Data, PokeFinderSave + 0x04); } } + public uint PokeFinderThumbsTotalValue { get => BitConverter.ToUInt32(Data, PokeFinderSave + 0x0C); set => BitConverter.GetBytes(value).CopyTo(Data, PokeFinderSave + 0x0C); } + public uint PokeFinderThumbsHighValue { get => BitConverter.ToUInt32(Data, PokeFinderSave + 0x10); @@ -760,6 +823,7 @@ public uint PokeFinderThumbsHighValue PokeFinderThumbsTotalValue = value; } } + public ushort PokeFinderTutorialFlags { get => BitConverter.ToUInt16(Data, PokeFinderSave + 0x14); @@ -818,6 +882,7 @@ public int GetTreeStreak(int battletype, bool super, bool max) return BitConverter.ToUInt16(Data, BattleTree + offset); } + public void SetTreeStreak(int value, int battletype, bool super, bool max) { if (battletype > 3) @@ -842,6 +907,7 @@ public int GetPokebeanCount(int bean_id) throw new ArgumentException("Invalid bean id!"); return Data[Resort + 0x564C + bean_id]; } + public void SetPokebeanCount(int bean_id, int count) { if (bean_id < 0 || bean_id > 14) @@ -855,14 +921,17 @@ public void SetPokebeanCount(int bean_id, int count) // Storage public override int CurrentBox { get => Data[LastViewedBox]; set => Data[LastViewedBox] = (byte)value; } + public override int GetPartyOffset(int slot) { - return Party + SIZE_PARTY * slot; + return Party + (SIZE_PARTY * slot); } + public override int GetBoxOffset(int box) { - return Box + SIZE_STORED*box*30; + return Box + (SIZE_STORED *box*30); } + protected override int GetBoxWallpaperOffset(int box) { int ofs = PCBackgrounds > 0 && PCBackgrounds < Data.Length ? PCBackgrounds : -1; @@ -870,6 +939,7 @@ protected override int GetBoxWallpaperOffset(int box) return ofs + box; return ofs; } + public override void SetBoxWallpaper(int box, int value) { if (PCBackgrounds < 0) @@ -877,21 +947,25 @@ public override void SetBoxWallpaper(int box, int value) int ofs = PCBackgrounds > 0 && PCBackgrounds < Data.Length ? PCBackgrounds : 0; Data[ofs + box] = (byte)value; } + public override string GetBoxName(int box) { if (PCLayout < 0) return $"B{box + 1}"; - return Util.TrimFromZero(Encoding.Unicode.GetString(Data, PCLayout + 0x22*box, 0x22)); + return Util.TrimFromZero(Encoding.Unicode.GetString(Data, PCLayout + (0x22 * box), 0x22)); } + public override void SetBoxName(int box, string value) { - Encoding.Unicode.GetBytes(value.PadRight(0x11, '\0')).CopyTo(Data, PCLayout + 0x22*box); + Encoding.Unicode.GetBytes(value.PadRight(0x11, '\0')).CopyTo(Data, PCLayout + (0x22 * box)); Edited = true; } + public override PKM GetPKM(byte[] data) { return new PK7(data); } + protected override void SetPKM(PKM pkm) { PK7 pk7 = (PK7)pkm; @@ -909,6 +983,7 @@ protected override void SetPKM(PKM pkm) } pkm.RefreshChecksum(); } + protected override void SetDex(PKM pkm) { if (PokeDex < 0 || Version == GameVersion.Invalid) // sanity @@ -930,7 +1005,7 @@ protected override void SetDex(PKM pkm) { if ((Data[PokeDex + 0x84] & (1 << (shift + 4))) != 0) // Already 2 { - BitConverter.GetBytes(pkm.EncryptionConstant).CopyTo(Data, PokeDex + 0x8E8 + shift * 4); + BitConverter.GetBytes(pkm.EncryptionConstant).CopyTo(Data, PokeDex + 0x8E8 + (shift * 4)); // Data[PokeDex + 0x84] |= (byte)(1 << (shift + 4)); // 2 -- pointless Data[PokeDex + 0x84] |= (byte)(1 << shift); // 1 } @@ -983,16 +1058,18 @@ protected override void SetDex(PKM pkm) lang--; lang--; // 0-8 languages if (lang < 0) lang = 1; - int lbit = bit * langCount + lang; + int lbit = (bit * langCount) + lang; if (lbit >> 3 < 920) // Sanity check for max length of region Data[PokeDexLanguageFlags + (lbit >> 3)] |= (byte)(1 << (lbit & 7)); } } + protected override void SetPartyValues(PKM pkm, bool isParty) { base.SetPartyValues(pkm, isParty); ((PK7)pkm).FormDuration = GetFormDuration(pkm, isParty); } + private static uint GetFormDuration(PKM pkm, bool isParty) { if (!isParty || pkm.AltForm == 0) @@ -1004,6 +1081,7 @@ private static uint GetFormDuration(PKM pkm, bool isParty) default: return 0; } } + public static bool SanitizeFormsToIterate(int species, out int formStart, out int formEnd, int formIn, bool USUM) { // 004AA370 in Moon @@ -1055,6 +1133,7 @@ public static bool SanitizeFormsToIterate(int species, out int formStart, out in formEnd = 0; return true; } + private void SetDexFlags(int index, int gender, int shiny, int baseSpecies) { const int brSize = 0x8C; @@ -1093,8 +1172,9 @@ private void SetDexFlags(int index, int gender, int shiny, int baseSpecies) return; // Set the Display flag if none are set - Data[ofs + (4 + shift) * brSize + bd] |= (byte)(1 << bm); + Data[ofs + ((4 + shift) * brSize) + bd] |= (byte)(1 << bm); } + public bool NationalDex { get => (Data[PokeDex + 4] & 1) == 1; @@ -1116,6 +1196,7 @@ public override bool GetCaught(int species) + 0x80; // Misc Data (1024 bits) return (1 << bm & Data[ofs + bd]) != 0; } + public override bool GetSeen(int species) { const int brSize = 0x8C; @@ -1129,36 +1210,42 @@ public override bool GetSeen(int species) + 0x80; // Misc Data (1024 bits) for (int i = 1; i <= 4; i++) // check all 4 seen flags (gender/shiny) - if ((Data[ofs + bd + i * brSize] & mask) != 0) + if ((Data[ofs + bd + (i * brSize)] & mask) != 0) return true; return false; } + public override byte[] DecryptPKM(byte[] data) { return PKX.DecryptArray(data); } + public override int PartyCount { - get => Data[Party + 6 * SIZE_PARTY]; - protected set => Data[Party + 6 * SIZE_PARTY] = (byte)value; + get => Data[Party + (6 * SIZE_PARTY)]; + protected set => Data[Party + (6 * SIZE_PARTY)] = (byte)value; } + public override int BoxesUnlocked { get => Data[PCFlags + 1]; set => Data[PCFlags + 1] = (byte)value; } + public override bool IsSlotLocked(int box, int slot) { if (slot >= 30 || box >= BoxCount) return false; - int slotIndex = slot + BoxSlotCount*box; + int slotIndex = slot + (BoxSlotCount * box); return LockedSlots.Any(s => s == slotIndex); } + public override bool IsSlotInBattleTeam(int box, int slot) { if (slot >= 30 || box >= BoxCount) return false; - int slotIndex = slot + BoxSlotCount * box; + int slotIndex = slot + (BoxSlotCount * box); return TeamSlots.Any(s => s == slotIndex); } + private void LoadLockedSlots() { int lockedCount = 0, teamCount = 0; @@ -1167,11 +1254,11 @@ private void LoadLockedSlots() bool locked = Data[PCBackgrounds - TeamCount - i] == 1; for (int j = 0; j < 6; j++) { - short val = BitConverter.ToInt16(Data, BattleBoxFlags + (i * 6 + j) * 2); + short val = BitConverter.ToInt16(Data, BattleBoxFlags + (((i * 6) + j) * 2)); if (val < 0) continue; - var slotVal = (BoxSlotCount * (val >> 8) + (val & 0xFF)) & 0xFFFF; + var slotVal = ((BoxSlotCount * (val >> 8)) + (val & 0xFF)) & 0xFFFF; if (locked) LockedSlots[lockedCount++] = slotVal; @@ -1183,25 +1270,28 @@ private void LoadLockedSlots() } private int FusedCount => USUM ? 3 : 1; + public int GetFusedSlotOffset(int slot) { if (Fused < 0 || slot < 0 || slot >= FusedCount) return -1; - return Fused + SIZE_PARTY * slot; // 0x104*slot + return Fused + (SIZE_PARTY * slot); // 0x104*slot } public int GetSurfScore(int recordID) { if (recordID < 0 || recordID > 4) recordID = 0; - return BitConverter.ToInt32(Data, Misc + 0x138 + 4 * recordID); + return BitConverter.ToInt32(Data, Misc + 0x138 + (4 * recordID)); } + public void SetSurfScore(int recordID, int score) { if (recordID < 0 || recordID > 4) recordID = 0; - SetData(BitConverter.GetBytes(score), Misc + 0x138 + 4 * recordID); + SetData(BitConverter.GetBytes(score), Misc + 0x138 + (4 * recordID)); } + public string RotomOT { get => GetString(Trainer2 + 0x30, 0x1A); @@ -1209,14 +1299,16 @@ public string RotomOT } public override int DaycareSeedSize => 32; // 128 bits + public override int GetDaycareSlotOffset(int loc, int slot) { if (loc != 0) return -1; if (Daycare < 0) return -1; - return Daycare + 1 + slot * (SIZE_STORED + 1); + return Daycare + 1 + (slot * (SIZE_STORED + 1)); } + public override bool? IsDaycareOccupied(int loc, int slot) { if (loc != 0) @@ -1224,8 +1316,9 @@ public override int GetDaycareSlotOffset(int loc, int slot) if (Daycare < 0) return null; - return Data[Daycare + (SIZE_STORED + 1) * slot] != 0; + return Data[Daycare + ((SIZE_STORED + 1) * slot)] != 0; } + public override string GetDaycareRNGSeed(int loc) { if (loc != 0) @@ -1236,6 +1329,7 @@ public override string GetDaycareRNGSeed(int loc) var data = Data.Skip(Daycare + 0x1DC).Take(DaycareSeedSize / 2).Reverse().ToArray(); return BitConverter.ToString(data).Replace("-", ""); } + public override bool? IsDaycareHasEgg(int loc) { if (loc != 0) @@ -1245,6 +1339,7 @@ public override string GetDaycareRNGSeed(int loc) return Data[Daycare + 0x1D8] == 1; } + public override void SetDaycareOccupied(int loc, int slot, bool occupied) { if (loc != 0) @@ -1252,8 +1347,9 @@ public override void SetDaycareOccupied(int loc, int slot, bool occupied) if (Daycare < 0) return; - Data[Daycare + (SIZE_STORED + 1) * slot] = (byte)(occupied ? 1 : 0); + Data[Daycare + ((SIZE_STORED + 1) * slot)] = (byte)(occupied ? 1 : 0); } + public override void SetDaycareRNGSeed(int loc, string seed) { if (loc != 0) @@ -1271,6 +1367,7 @@ public override void SetDaycareRNGSeed(int loc, string seed) .Select(x => Convert.ToByte(seed.Substring(x, 2), 16)) .ToArray().CopyTo(Data, Daycare + 0x1DC); } + public override void SetDaycareHasEgg(int loc, bool hasEgg) { if (loc != 0) @@ -1310,6 +1407,7 @@ protected override bool[] MysteryGiftReceivedFlags Edited = true; } } + protected override MysteryGift[] MysteryGiftCards { get @@ -1343,8 +1441,9 @@ private WC7 GetWC7(int index) if (index < 0 || index > GiftCountMax) return null; - return new WC7(GetData(WondercardData + index * WC7.Size, WC7.Size)); + return new WC7(GetData(WondercardData + (index * WC7.Size), WC7.Size)); } + private void SetWC7(MysteryGift wc7, int index) { if (WondercardData < 0) @@ -1352,7 +1451,7 @@ private void SetWC7(MysteryGift wc7, int index) if (index < 0 || index > GiftCountMax) return; - wc7.Data.CopyTo(Data, WondercardData + index * WC7.Size); + wc7.Data.CopyTo(Data, WondercardData + (index * WC7.Size)); Edited = true; } @@ -1382,13 +1481,16 @@ public override string MiscSaveChecks() } return r.ToString(); } + public override string MiscSaveInfo() => string.Join(Environment.NewLine, Blocks.Select(b => b.Summary)); + public bool MegaUnlocked { get => (Data[TrainerCard + 0x78] & 0x01) != 0; set => Data[TrainerCard + 0x78] = (byte)((Data[TrainerCard + 0x78] & 0xFE) | (value ? 1 : 0)); // in battle // Data[0x1F22] = (byte)((Data[0x1F22] & 0xFE) | (value ? 1 : 0)); // event } + public bool ZMoveUnlocked { get => (Data[TrainerCard + 0x78] & 2) != 0; @@ -1396,6 +1498,7 @@ public bool ZMoveUnlocked } public override string GetString(int Offset, int Length) => StringConverter.GetString7(Data, Offset, Length); + public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) { if (PadToSize == 0) diff --git a/PKHeX.Core/Saves/Substructures/Battle Videos/BV6.cs b/PKHeX.Core/Saves/Substructures/Battle Videos/BV6.cs index 1a73935d2..1f4406943 100644 --- a/PKHeX.Core/Saves/Substructures/Battle Videos/BV6.cs +++ b/PKHeX.Core/Saves/Substructures/Battle Videos/BV6.cs @@ -60,7 +60,7 @@ public string[] PlayerNames string[] trainers = new string[4]; for (int i = 0; i < 4; i++) { - trainers[i] = Util.TrimFromZero(Encoding.Unicode.GetString(Data, 0xEC + 0x1A*i, 0x1A)); + trainers[i] = Util.TrimFromZero(Encoding.Unicode.GetString(Data, 0xEC + (0x1A * i), 0x1A)); if (string.IsNullOrWhiteSpace(trainers[i])) trainers[i] = NPC; } @@ -74,7 +74,7 @@ public string[] PlayerNames for (int i = 0; i < 4; i++) { string tr = value[i] == NPC ? "" : value[i]; - Encoding.Unicode.GetBytes(tr.PadRight(0x1A/2)).CopyTo(Data, 0xEC + 0x1A*i); + Encoding.Unicode.GetBytes(tr.PadRight(0x1A/2)).CopyTo(Data, 0xEC + (0x1A * i)); } } } @@ -90,8 +90,8 @@ public PKM[][] PlayerTeams Teams[t] = new PKM[6]; for (int p = 0; p < 6; p++) { - int offset = start + PKX.SIZE_6PARTY*(t*6 + p); - offset += 8*((t*6 + p)/6); // 8 bytes padding between teams + int offset = start + (PKX.SIZE_6PARTY*((t * 6) + p)); + offset += 8*(((t * 6) + p)/6); // 8 bytes padding between teams Teams[t][p] = new PK6(Data.Skip(offset).Take(PKX.SIZE_6PARTY).ToArray(), $"Team {t}, Slot {p}"); } } @@ -105,8 +105,8 @@ public PKM[][] PlayerTeams { for (int p = 0; p < 6; p++) { - int offset = start + PKX.SIZE_6PARTY*(t*6 + p); - offset += 8*((t*6 + p)/6); // 8 bytes padding between teams + int offset = start + (PKX.SIZE_6PARTY*((t * 6) + p)); + offset += 8*(((t * 6) + p)/6); // 8 bytes padding between teams Teams[t][p].EncryptedPartyData.CopyTo(Data, offset); } } @@ -197,6 +197,7 @@ public PKM[][] PlayerTeams "Link", "Maison", "Super Maison", "Battle Spot - Free", "Battle Spot - Rating", "Battle Spot - Special", "UNUSED", "JP-1", "JP-2", "BROKEN", }; + public static readonly string[] BVstyle = { "Single", "Double", "Triple", "Rotation", "Multi", }; } } diff --git a/PKHeX.Core/Saves/Substructures/Battle Videos/BV7.cs b/PKHeX.Core/Saves/Substructures/Battle Videos/BV7.cs index 565917bc3..07487f0f1 100644 --- a/PKHeX.Core/Saves/Substructures/Battle Videos/BV7.cs +++ b/PKHeX.Core/Saves/Substructures/Battle Videos/BV7.cs @@ -5,6 +5,7 @@ namespace PKHeX.Core public class BV7 : BattleVideo { internal const int SIZE = 0x2BC0; + internal new static bool IsValid(byte[] data) { return data.Length == SIZE; @@ -30,7 +31,7 @@ private PKM[][] PlayerTeams Teams[t] = new PKM[6]; for (int p = 0; p < 6; p++) { - int offset = offsets[t] + PKX.SIZE_6PARTY * p; + int offset = offsets[t] + (PKX.SIZE_6PARTY * p); Teams[t][p] = new PK7(Data.Skip(offset).Take(PKX.SIZE_6STORED).ToArray(), $"Team {t}, Slot {p}"); } } @@ -44,7 +45,7 @@ private PKM[][] PlayerTeams { for (int p = 0; p < 6; p++) { - int offset = offsets[t] + PKX.SIZE_6PARTY * p; + int offset = offsets[t] + (PKX.SIZE_6PARTY * p); Teams[t][p].EncryptedPartyData.CopyTo(Data, offset); } } diff --git a/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3.cs b/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3.cs index f86b62c26..5425823eb 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3.cs @@ -31,6 +31,7 @@ public void Maximize(bool create = false) } public void SetBlock(byte[] data, int offset) => Data.CopyTo(data, offset); + public static PokeBlock3 GetBlock(byte[] data, int offset) { byte[] result = new byte[SIZE]; diff --git a/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3Case.cs b/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3Case.cs index 2671fdd50..d5ca3fe2f 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3Case.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/PokeBlock3Case.cs @@ -25,6 +25,7 @@ public void DeleteAll() foreach (var b in Blocks) b.Delete(); } + public void MaximizeAll(bool createMissing = false) { foreach (var b in Blocks) diff --git a/PKHeX.Core/Saves/Substructures/Gen3/Roamer3.cs b/PKHeX.Core/Saves/Substructures/Gen3/Roamer3.cs index 8ee8db810..bafbbad73 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/Roamer3.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/Roamer3.cs @@ -26,26 +26,31 @@ private uint IV32 get => BitConverter.ToUInt32(SAV.Data, Offset); set => SAV.SetData(BitConverter.GetBytes(value), Offset); } + public uint PID { get => BitConverter.ToUInt32(SAV.Data, Offset + 4); set => SAV.SetData(BitConverter.GetBytes(value), Offset + 4); } + public int Species { get => SpeciesConverter.GetG4Species(BitConverter.ToInt16(SAV.Data, Offset + 8)); set => SAV.SetData(BitConverter.GetBytes((ushort)SpeciesConverter.GetG3Species(value)), Offset + 8); } + public int HP_Current { get => BitConverter.ToInt16(SAV.Data, Offset + 10); set => SAV.SetData(BitConverter.GetBytes((short)value), Offset + 10); } + public int CurrentLevel { get => SAV.Data[Offset + 12]; set => SAV.Data[Offset + 12] = (byte)value; } + public int Status { get => SAV.Data[Offset + 0x0D]; set => SAV.Data[Offset + 0x0D] = (byte)value; } public int CNT_Cool { get => SAV.Data[Offset + 0x0E]; set => SAV.Data[Offset + 0x0E] = (byte)value; } diff --git a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs index 27866e624..0aaeda9e8 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs @@ -16,6 +16,7 @@ public SecretBase3(byte[] data, int offset) } public int SecretBaseLocation { get => Data[Offset + 0]; set => Data[Offset + 0] = (byte) value; } + public int OT_Gender { get => (Data[Offset + 1] >> 4) & 1; @@ -27,11 +28,13 @@ public string OT_Name get => StringConverter.GetString3(Data, Offset + 2, 7, Japanese); set => StringConverter.SetString3(value, 7, Japanese, 7).CopyTo(Data, Offset + 2); } + public uint OT_ID { get => BitConverter.ToUInt32(Data, Offset + 9); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 9); } + public int OT_Class { get => Data[Offset + 9] % 5; } public int Language { get => Data[Offset + 0x0D]; set => Data[Offset + 0x0D] = (byte)value; } public int _E { get => Data[Offset + 0x0E]; set => Data[Offset + 0x0E] = (byte)value; } @@ -44,6 +47,7 @@ public byte[] Decorations get => Data.Skip(Offset + 0x12).Take(0x10).ToArray(); set => value.CopyTo(Data, Offset + 0x12); } + public byte[] DecorationCoordinates { get => Data.Skip(Offset + 0x22).Take(0x10).ToArray(); diff --git a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3Team.cs b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3Team.cs index 3796a7582..df813eac5 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3Team.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3Team.cs @@ -18,6 +18,7 @@ public class SecretBase3Team public readonly SecretBase3PKM[] Team; private readonly byte[] Data; + public SecretBase3Team(byte[] data) { Team = new SecretBase3PKM[6]; diff --git a/PKHeX.Core/Saves/Substructures/Gen5/EntreeForest.cs b/PKHeX.Core/Saves/Substructures/Gen5/EntreeForest.cs index 0226b3831..449c7a12f 100644 --- a/PKHeX.Core/Saves/Substructures/Gen5/EntreeForest.cs +++ b/PKHeX.Core/Saves/Substructures/Gen5/EntreeForest.cs @@ -31,6 +31,7 @@ public EntreeForest(byte[] data) Data = data; PKX.CryptArray(data, EncryptionSeed, 0, EncryptionSeedOffset); } + public byte[] Write() { byte[] data = (byte[])Data.Clone(); @@ -75,6 +76,7 @@ public uint EncryptionSeed get => BitConverter.ToUInt32(Data, EncryptionSeedOffset); private set => BitConverter.GetBytes(value).CopyTo(Data, EncryptionSeedOffset); } + public void UnlockAllAreas() { Unlock38Areas = MaxUnlock38Areas; diff --git a/PKHeX.Core/Saves/Substructures/OPower/OPower6.cs b/PKHeX.Core/Saves/Substructures/OPower/OPower6.cs index 9c17107b4..35e1a8f3d 100644 --- a/PKHeX.Core/Saves/Substructures/OPower/OPower6.cs +++ b/PKHeX.Core/Saves/Substructures/OPower/OPower6.cs @@ -30,6 +30,7 @@ public class OPower6 new OPowerFlagSet(3, Critical), new OPowerFlagSet(3, Accuracy), }; + static OPower6() { int index = 1; // Skip unused byte @@ -42,6 +43,7 @@ static OPower6() private readonly byte[] Data; private readonly int Offset; + public OPower6(byte[] data, int offset) { Offset = offset; @@ -71,6 +73,7 @@ public bool MasterFlag public void UnlockAll() => ToggleFlags(allEvents: true); public void UnlockRegular() => ToggleFlags(); public void ClearAll() => ToggleFlags(clearOnly: true); + private void ToggleFlags(bool allEvents = false, bool clearOnly = false) { foreach (var m in Mapping) diff --git a/PKHeX.Core/Saves/Substructures/OPower/OPowerFlagSet.cs b/PKHeX.Core/Saves/Substructures/OPower/OPowerFlagSet.cs index 9fe7ef26c..fb4e9ddc6 100644 --- a/PKHeX.Core/Saves/Substructures/OPower/OPowerFlagSet.cs +++ b/PKHeX.Core/Saves/Substructures/OPower/OPowerFlagSet.cs @@ -31,6 +31,7 @@ public int GetOPowerLevel(byte[] data, int offset) Debug.WriteLine($"Fetched {Identifier}: {BaseCount}"); return BaseCount; } + public void SetOPowerLevel(byte[] data, int offset, int value) { Debug.WriteLine($"Setting {Identifier}: {value}"); @@ -48,6 +49,7 @@ private bool GetFlag(byte[] data, int offset, int index) { return data[Offset + offset + index] == (byte)OPowerFlagState.Unlocked; } + private void SetFlag(byte[] data, int offset, int index, bool value) { if (index < Count) diff --git a/PKHeX.Core/Saves/Substructures/Records.cs b/PKHeX.Core/Saves/Substructures/Records.cs index 76dbb934a..039c1a954 100644 --- a/PKHeX.Core/Saves/Substructures/Records.cs +++ b/PKHeX.Core/Saves/Substructures/Records.cs @@ -511,9 +511,7 @@ public static int GetOffset(int baseOfs, int recordID) {189, "Mantine Surf Plays"}, {190, "Photo Club Photos saved"}, {191, "Battle Agency Battles"}, - - - + // 192-194 unknown {195, "Photo Club Sticker usage"}, {196, "Photo Club Photo Shoots"}, {197, "Highest Wormhole Travel Distance"}, diff --git a/PKHeX.Core/Util/FileUtil.cs b/PKHeX.Core/Util/FileUtil.cs index 580247bc0..8bf7edb9d 100644 --- a/PKHeX.Core/Util/FileUtil.cs +++ b/PKHeX.Core/Util/FileUtil.cs @@ -130,6 +130,7 @@ public static bool TryGetPKM(byte[] data, out PKM pk, string ext, ITrainerInfo s pk = PKMConverter.GetPKMfromBytes(data, prefer: format); return pk != null; } + /// /// Tries to get an object from the input parameters. ///