Ejemplo n.º 1
0
        public SAV3(GameVersion version = GameVersion.FRLG, bool japanese = false) : base(SaveUtil.SIZE_G3RAW)
        {
            if (version == GameVersion.FR || version == GameVersion.LG)
            {
                Version = GameVersion.FRLG;
            }
            else if (version == GameVersion.R || version == GameVersion.S)
            {
                Version = GameVersion.RS;
            }
            else
            {
                Version = version;
            }
            _personal = SaveUtil.GetG3Personal(Version) ?? PersonalTable.RS;
            Japanese  = japanese;

            LoadBlocks(out BlockOrder, out BlockOfs);
            // spoof block offsets
            BlockOfs = Enumerable.Range(0, BLOCK_COUNT).ToArray();

            LegalKeyItems = Version switch
            {
                GameVersion.RS => Legal.Pouch_Key_RS,
                GameVersion.E => Legal.Pouch_Key_E,
                _ => Legal.Pouch_Key_FRLG
            };
            PokeDex         = BlockOfs[0] + 0x18;
            SeenFlagOffsets = Array.Empty <int>();

            Initialize();
            ClearBoxes();
        }
Ejemplo n.º 2
0
        public SAV3(byte[] data, GameVersion versionOverride = GameVersion.Any) : base(data)
        {
            LoadBlocks(out BlockOrder, out BlockOfs);
            Version   = versionOverride != GameVersion.Any ? versionOverride : GetVersion(Data, BlockOfs[0]);
            _personal = SaveUtil.GetG3Personal(Version) ?? PersonalTable.RS;

            // Japanese games are limited to 5 character OT names; any unused characters are 0xFF.
            // 5 for JP, 7 for INT. There's always 1 terminator, thus we can check 0x6-0x7 being 0xFFFF = INT
            // OT name is stored at the top of the first block.
            Japanese = BitConverter.ToInt16(Data, BlockOfs[0] + 0x6) == 0;

            LegalKeyItems = Version switch
            {
                GameVersion.RS => Legal.Pouch_Key_RS,
                GameVersion.E => Legal.Pouch_Key_E,
                _ => Legal.Pouch_Key_FRLG
            };

            PokeDex         = BlockOfs[0] + 0x18;
            SeenFlagOffsets = Version switch
            {
                GameVersion.RS => new[] { PokeDex + 0x44, BlockOfs[1] + 0x938, BlockOfs[4] + 0xC0C },
                GameVersion.E => new[] { PokeDex + 0x44, BlockOfs[1] + 0x988, BlockOfs[4] + 0xCA4 },
                _ => new[] { PokeDex + 0x44, BlockOfs[1] + 0x5F8, BlockOfs[4] + 0xB98 }
            };

            Initialize();
        }
Ejemplo n.º 3
0
Archivo: SAV3.cs Proyecto: nixhex/PKHeX
        public SAV3(GameVersion version = GameVersion.FRLG, bool japanese = false)
        {
            Version = version switch
            {
                GameVersion.FR or GameVersion.LG => GameVersion.FRLG,
                                              GameVersion.R or GameVersion.S => GameVersion.RS,
                                              _ => version
            };
            _personal = SaveUtil.GetG3Personal(Version);
            Japanese  = japanese;

            BlockOrder = Array.Empty <short>();

            LegalKeyItems = Version switch
            {
                GameVersion.RS => Legal.Pouch_Key_RS,
                GameVersion.E => Legal.Pouch_Key_E,
                _ => Legal.Pouch_Key_FRLG
            };
            PokeDex         = 0x18;
            SeenFlagOffsets = Array.Empty <int>();

            Initialize();
            ClearBoxes();
        }
Ejemplo n.º 4
0
Archivo: SAV3.cs Proyecto: nixhex/PKHeX
        public SAV3(byte[] data, GameVersion versionOverride = GameVersion.Any) : base(data)
        {
            LoadBlocks(out BlockOrder);

            // Copy chunk to the allocated location
            LoadBlocks(Small, 0, 1);
            LoadBlocks(Large, 1, 5);
            LoadBlocks(Storage, 5, BLOCK_COUNT);

            Version   = versionOverride != GameVersion.Any ? versionOverride : GetVersion(Small);
            _personal = SaveUtil.GetG3Personal(Version);

            // Japanese games are limited to 5 character OT names; any unused characters are 0xFF.
            // 5 for JP, 7 for INT. There's always 1 terminator, thus we can check 0x6-0x7 being 0xFFFF = INT
            // OT name is stored at the top of the first block.
            Japanese = BitConverter.ToInt16(Small, 0x6) == 0;

            LegalKeyItems = Version switch
            {
                GameVersion.RS => Legal.Pouch_Key_RS,
                GameVersion.E => Legal.Pouch_Key_E,
                _ => Legal.Pouch_Key_FRLG
            };

            PokeDex         = 0x18;
            SeenFlagOffsets = Version switch
            {
                GameVersion.RS => new[] { 0x938, 0x3A8C },
                GameVersion.E => new[] { 0x988, 0x3B24 },
                _ => new[] { 0x5F8, 0x3A18 }
            };

            Initialize();
        }
Ejemplo n.º 5
0
        public SAV3(byte[] data, GameVersion versionOverride = GameVersion.Any) : base(data)
        {
            LoadBlocks();
            Version  = versionOverride != GameVersion.Any ? versionOverride : GetVersion(Data, BlockOfs[0]);
            Personal = SaveUtil.GetG3Personal(Version) ?? PersonalTable.RS;

            // Japanese games are limited to 5 character OT names; any unused characters are 0xFF.
            // 5 for JP, 7 for INT. There's always 1 terminator, thus we can check 0x6-0x7 being 0xFFFF = INT
            // OT name is stored at the top of the first block.
            Japanese = BitConverter.ToInt16(Data, BlockOfs[0] + 0x6) == 0;

            Initialize();
        }
Ejemplo n.º 6
0
        public SAV3(GameVersion version = GameVersion.FRLG, bool japanese = false) : base(SaveUtil.SIZE_G3RAW)
        {
            if (version == GameVersion.FR || version == GameVersion.LG)
            {
                Version = GameVersion.FRLG;
            }
            else if (version == GameVersion.R || version == GameVersion.S)
            {
                Version = GameVersion.RS;
            }
            else
            {
                Version = version;
            }
            Personal = SaveUtil.GetG3Personal(Version) ?? PersonalTable.RS;
            Japanese = japanese;

            LoadBlocks();
            // spoof block offsets
            BlockOfs = Enumerable.Range(0, BLOCK_COUNT).ToArray();

            Initialize();
            ClearBoxes();
        }
Ejemplo n.º 7
0
Archivo: SAV3.cs Proyecto: Zovrah/PKHeX
        public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any)
        {
            Data       = data ?? new byte[SaveUtil.SIZE_G3RAW];
            BAK        = (byte[])Data.Clone();
            Exportable = !IsRangeEmpty(0, Data.Length);

            int[] BlockOrder1 = GetBlockOrder(0);
            if (Data.Length > SaveUtil.SIZE_G3RAWHALF)
            {
                int[] BlockOrder2 = GetBlockOrder(0xE000);
                ActiveSAV  = GetActiveSaveIndex(BlockOrder1, BlockOrder2);
                BlockOrder = ActiveSAV == 0 ? BlockOrder1 : BlockOrder2;
            }
            else
            {
                ActiveSAV  = 0;
                BlockOrder = BlockOrder1;
            }

            BlockOfs = new int[BLOCK_COUNT];
            for (int i = 0; i < BLOCK_COUNT; i++)
            {
                int index = Array.IndexOf(BlockOrder, i);
                BlockOfs[i] = index < 0 ? int.MinValue : (index * SIZE_BLOCK) + ABO;
            }

            if (versionOverride != GameVersion.Any)
            {
                Version = versionOverride;
            }
            else if (data == null)
            {
                Version = GameVersion.FRLG;
            }
            else
            {
                Version = GetVersion(Data, BlockOfs[0]);
            }

            Personal = SaveUtil.GetG3Personal(Version);
            if (data == null) // spoof block offsets
            {
                BlockOfs = Enumerable.Range(0, BLOCK_COUNT).ToArray();
                if (Version == GameVersion.FR || Version == GameVersion.LG)
                {
                    Version = GameVersion.FRLG;
                }
                else if (Version == GameVersion.R || Version == GameVersion.LG)
                {
                    Version = GameVersion.RS;
                }
            }

            // Set up PC data buffer beyond end of save file.
            Box = Data.Length;
            Array.Resize(ref Data, Data.Length + SIZE_RESERVED); // More than enough empty space.

            // Copy chunk to the allocated location
            for (int i = 5; i < BLOCK_COUNT; i++)
            {
                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]);
            }

            // Japanese games are limited to 5 character OT names; any unused characters are 0xFF.
            // 5 for JP, 7 for INT. There's always 1 terminator, thus we can check 0x6-0x7 being 0xFFFF = INT
            // OT name is stored at the top of the first block.
            Japanese = BitConverter.ToInt16(Data, BlockOfs[0] + 0x6) == 0 && Exportable;

            PokeDex = BlockOfs[0] + 0x18;
            switch (Version)
            {
            case GameVersion.RS:
                LegalKeyItems     = Legal.Pouch_Key_RS;
                OFS_PCItem        = BlockOfs[1] + 0x0498;
                OFS_PouchHeldItem = BlockOfs[1] + 0x0560;
                OFS_PouchKeyItem  = BlockOfs[1] + 0x05B0;
                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 };
                EventFlag         = BlockOfs[2] + 0x2A0;
                EventConst        = EventFlag + (EventFlagMax / 8);
                Daycare           = BlockOfs[4] + 0x11C;
                break;

            case GameVersion.E:
                LegalKeyItems     = Legal.Pouch_Key_E;
                OFS_PCItem        = BlockOfs[1] + 0x0498;
                OFS_PouchHeldItem = BlockOfs[1] + 0x0560;
                OFS_PouchKeyItem  = BlockOfs[1] + 0x05D8;
                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 };
                EventFlag         = BlockOfs[2] + 0x2F0;
                EventConst        = EventFlag + (EventFlagMax / 8);
                Daycare           = BlockOfs[4] + 0x1B0;
                break;

            case GameVersion.FRLG:
                LegalKeyItems     = Legal.Pouch_Key_FRLG;
                OFS_PCItem        = BlockOfs[1] + 0x0298;
                OFS_PouchHeldItem = BlockOfs[1] + 0x0310;
                OFS_PouchKeyItem  = BlockOfs[1] + 0x03B8;
                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 };
                EventFlag         = BlockOfs[1] + 0xEE0;
                EventConst        = BlockOfs[2] + 0x80;
                Daycare           = BlockOfs[4] + 0x100;
                break;
            }
            LoadEReaderBerryData();
            LegalItems   = Legal.Pouch_Items_RS;
            LegalBalls   = Legal.Pouch_Ball_RS;
            LegalTMHMs   = Legal.Pouch_TMHM_RS;
            LegalBerries = Legal.Pouch_Berries_RS;
            HeldItems    = Legal.HeldItems_RS;

            // Sanity Check SeenFlagOffsets -- early saves may not have block 4 initialized yet
            SeenFlagOffsets = SeenFlagOffsets?.Where(z => z >= 0).ToArray();

            if (!Exportable)
            {
                ClearBoxes();
            }
        }