2016-09-19 05:47:31 +00:00
|
|
|
|
using System;
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
using System.Collections.Generic;
|
2016-09-19 05:47:31 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
2017-01-08 07:54:09 +00:00
|
|
|
|
namespace PKHeX.Core
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
2017-10-24 06:12:58 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Generation 3 <see cref="SaveFile"/> object for Pokémon Ruby Sapphire Box saves.
|
|
|
|
|
/// </summary>
|
2019-02-19 05:59:57 +00:00
|
|
|
|
public sealed class SAV3RSBox : SaveFile, IGCSaveFile
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
2018-07-30 04:51:45 +00:00
|
|
|
|
protected override string BAKText => $"{Version} #{SaveCount:0000}";
|
2019-02-19 05:59:57 +00:00
|
|
|
|
public override string Filter => this.GCFilter();
|
|
|
|
|
public override string Extension => this.GCExtension();
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
public override PersonalTable Personal => PersonalTable.RS;
|
|
|
|
|
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_RS;
|
2019-02-19 05:59:57 +00:00
|
|
|
|
public bool IsMemoryCardSave => MC != null;
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
private readonly SAV3GCMemoryCard? MC;
|
|
|
|
|
public readonly bool Japanese = false; // todo?
|
2019-02-19 05:59:57 +00:00
|
|
|
|
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
public SAV3RSBox(byte[] data, SAV3GCMemoryCard MC) : this(data, MC.Data) { this.MC = MC; }
|
|
|
|
|
public SAV3RSBox(byte[] data) : this(data, (byte[])data.Clone()) { }
|
2018-09-15 05:37:47 +00:00
|
|
|
|
|
2019-06-09 02:56:11 +00:00
|
|
|
|
public SAV3RSBox() : base(SaveUtil.SIZE_G3BOX)
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
2019-06-09 02:56:11 +00:00
|
|
|
|
Box = 0;
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
Blocks = Array.Empty<BlockInfoRSBOX>();
|
2019-06-09 02:56:11 +00:00
|
|
|
|
ClearBoxes();
|
|
|
|
|
}
|
2017-10-31 16:24:54 +00:00
|
|
|
|
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
private SAV3RSBox(byte[] data, byte[] bak) : base(data, bak)
|
2019-06-09 02:56:11 +00:00
|
|
|
|
{
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
Blocks = ReadBlocks(data);
|
2019-06-09 02:56:11 +00:00
|
|
|
|
InitializeData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void InitializeData()
|
|
|
|
|
{
|
2016-09-19 05:47:31 +00:00
|
|
|
|
// Detect active save
|
2019-06-09 02:56:11 +00:00
|
|
|
|
int[] SaveCounts = Blocks.Select(block => (int) block.SaveCount).ToArray();
|
2016-09-19 05:47:31 +00:00
|
|
|
|
SaveCount = SaveCounts.Max();
|
|
|
|
|
int ActiveSAV = Array.IndexOf(SaveCounts, SaveCount) / BLOCK_COUNT;
|
2019-06-09 02:56:11 +00:00
|
|
|
|
Blocks = Blocks.Skip(ActiveSAV * BLOCK_COUNT).Take(BLOCK_COUNT).OrderBy(b => b.ID).ToArray();
|
2018-05-12 15:13:39 +00:00
|
|
|
|
|
2016-09-19 05:47:31 +00:00
|
|
|
|
// 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 block to the allocated location
|
2018-02-19 19:33:37 +00:00
|
|
|
|
const int copySize = BLOCK_SIZE - 0x10;
|
|
|
|
|
foreach (var b in Blocks)
|
2019-06-09 02:56:11 +00:00
|
|
|
|
Array.Copy(Data, b.Offset + 0xC, Data, (int) (Box + (b.ID * copySize)), copySize);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
private static BlockInfoRSBOX[] ReadBlocks(byte[] data)
|
|
|
|
|
{
|
|
|
|
|
var blocks = new BlockInfoRSBOX[2 * BLOCK_COUNT];
|
|
|
|
|
for (int i = 0; i < blocks.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
int offset = BLOCK_SIZE + (i * BLOCK_SIZE);
|
|
|
|
|
blocks[i] = new BlockInfoRSBOX(data, offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return blocks;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-09 02:56:11 +00:00
|
|
|
|
private BlockInfoRSBOX[] Blocks;
|
|
|
|
|
private int SaveCount;
|
2016-09-19 05:47:31 +00:00
|
|
|
|
private const int BLOCK_COUNT = 23;
|
|
|
|
|
private const int BLOCK_SIZE = 0x2000;
|
|
|
|
|
private const int SIZE_RESERVED = BLOCK_COUNT * BLOCK_SIZE; // unpacked box data
|
2018-09-15 05:37:47 +00:00
|
|
|
|
|
2019-02-19 05:59:57 +00:00
|
|
|
|
protected override byte[] GetFinalData()
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
2019-03-08 02:05:55 +00:00
|
|
|
|
var newFile = GetInnerData();
|
2017-04-02 20:42:42 +00:00
|
|
|
|
|
|
|
|
|
// Return the gci if Memory Card is not being exported
|
2019-02-19 05:59:57 +00:00
|
|
|
|
if (!IsMemoryCardSave)
|
|
|
|
|
return newFile;
|
2017-04-02 20:42:42 +00:00
|
|
|
|
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
MC!.SelectedSaveData = newFile;
|
2017-04-02 20:42:42 +00:00
|
|
|
|
return MC.Data;
|
2016-09-19 05:47:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-08 02:05:55 +00:00
|
|
|
|
private byte[] GetInnerData()
|
|
|
|
|
{
|
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
|
|
SetChecksums();
|
|
|
|
|
|
|
|
|
|
return GetData(0, Data.Length - SIZE_RESERVED);
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-19 05:47:31 +00:00
|
|
|
|
// Configuration
|
2019-03-08 02:05:55 +00:00
|
|
|
|
public override SaveFile Clone()
|
|
|
|
|
{
|
|
|
|
|
var data = GetInnerData();
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
var sav = IsMemoryCardSave ? new SAV3RSBox(data, MC!) : new SAV3RSBox(data);
|
2019-03-08 02:05:55 +00:00
|
|
|
|
sav.Header = (byte[])Header.Clone();
|
|
|
|
|
return sav;
|
|
|
|
|
}
|
2016-09-19 05:47:31 +00:00
|
|
|
|
|
|
|
|
|
public override int SIZE_STORED => PKX.SIZE_3STORED + 4;
|
2017-06-18 01:37:19 +00:00
|
|
|
|
protected override int SIZE_PARTY => PKX.SIZE_3PARTY; // unused
|
2016-09-19 05:47:31 +00:00
|
|
|
|
public override PKM BlankPKM => new PK3();
|
2016-09-26 23:14:11 +00:00
|
|
|
|
public override Type PKMType => typeof(PK3);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
|
2017-12-28 00:36:24 +00:00
|
|
|
|
public override int MaxMoveID => Legal.MaxMoveID_3;
|
2016-10-24 04:59:27 +00:00
|
|
|
|
public override int MaxSpeciesID => Legal.MaxSpeciesID_3;
|
2017-12-28 00:36:24 +00:00
|
|
|
|
public override int MaxAbilityID => Legal.MaxAbilityID_3;
|
|
|
|
|
public override int MaxItemID => Legal.MaxItemID_3;
|
|
|
|
|
public override int MaxBallID => Legal.MaxBallID_3;
|
|
|
|
|
public override int MaxGameID => Legal.MaxGameID_3;
|
|
|
|
|
|
2016-09-25 20:42:03 +00:00
|
|
|
|
public override int MaxEV => 255;
|
2016-09-19 05:47:31 +00:00
|
|
|
|
public override int Generation => 3;
|
|
|
|
|
protected override int GiftCountMax => 1;
|
2017-04-10 04:53:53 +00:00
|
|
|
|
public override int OTLength => 7;
|
2016-09-19 05:47:31 +00:00
|
|
|
|
public override int NickLength => 10;
|
|
|
|
|
public override int MaxMoney => 999999;
|
2017-01-03 06:16:15 +00:00
|
|
|
|
public override bool HasBoxWallpapers => false;
|
2016-09-19 05:47:31 +00:00
|
|
|
|
|
|
|
|
|
public override int BoxCount => 50;
|
|
|
|
|
public override bool HasParty => false;
|
2019-09-03 02:30:58 +00:00
|
|
|
|
public override bool IsPKMPresent(byte[] data, int offset) => PKX.IsPKMPresentGBA(data, offset);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
|
|
|
|
|
// Checksums
|
2018-02-19 19:33:37 +00:00
|
|
|
|
protected override void SetChecksums() => Blocks.SetChecksums(Data);
|
|
|
|
|
public override bool ChecksumsValid => Blocks.GetChecksumsValid(Data);
|
|
|
|
|
public override string ChecksumInfo => Blocks.GetChecksumInfo(Data);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
|
|
|
|
|
// Trainer Info
|
2017-05-13 03:32:36 +00:00
|
|
|
|
public override GameVersion Version { get => GameVersion.RSBOX; protected set { } }
|
2016-09-19 05:47:31 +00:00
|
|
|
|
|
|
|
|
|
// Storage
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public override int GetPartyOffset(int slot) => -1;
|
2018-09-15 05:37:47 +00:00
|
|
|
|
public override int GetBoxOffset(int box) => Box + 8 + (SIZE_STORED * box * 30);
|
|
|
|
|
|
2016-09-19 05:47:31 +00:00
|
|
|
|
public override int CurrentBox
|
|
|
|
|
{
|
2017-05-13 03:32:36 +00:00
|
|
|
|
get => Data[Box + 4] * 2;
|
|
|
|
|
set => Data[Box + 4] = (byte)(value / 2);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
}
|
2018-09-15 05:37:47 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
protected override int GetBoxWallpaperOffset(int box)
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
|
|
|
|
// Box Wallpaper is directly after the Box Names
|
2018-09-15 05:37:47 +00:00
|
|
|
|
int offset = Box + 0x1ED19 + (box / 2);
|
2016-10-29 18:32:21 +00:00
|
|
|
|
return offset;
|
2016-09-19 05:47:31 +00:00
|
|
|
|
}
|
2018-09-15 05:37:47 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public override string GetBoxName(int box)
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
|
|
|
|
// Tweaked for the 1-30/31-60 box showing
|
2018-09-15 05:37:47 +00:00
|
|
|
|
int lo = (30 *(box%2)) + 1;
|
|
|
|
|
int hi = 30*((box % 2) + 1);
|
2017-01-19 03:57:42 +00:00
|
|
|
|
string boxName = $"[{lo:00}-{hi:00}] ";
|
|
|
|
|
box /= 2;
|
2016-09-19 05:47:31 +00:00
|
|
|
|
|
2018-09-15 05:37:47 +00:00
|
|
|
|
int offset = Box + 0x1EC38 + (9 * box);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
if (Data[offset] == 0 || Data[offset] == 0xFF)
|
|
|
|
|
boxName += $"BOX {box + 1}";
|
2017-06-18 01:37:19 +00:00
|
|
|
|
boxName += GetString(offset, 9);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
|
|
|
|
|
return boxName;
|
|
|
|
|
}
|
2018-09-15 05:37:47 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public override void SetBoxName(int box, string value)
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
2018-09-15 05:37:47 +00:00
|
|
|
|
int offset = Box + 0x1EC38 + (9 * box);
|
2018-05-12 15:13:39 +00:00
|
|
|
|
byte[] data = value == $"BOX {box + 1}" ? new byte[9] : SetString(value, 8);
|
2017-06-18 01:37:19 +00:00
|
|
|
|
SetData(data, offset);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
}
|
2018-09-15 05:37:47 +00:00
|
|
|
|
|
2019-03-30 02:43:33 +00:00
|
|
|
|
protected override PKM GetPKM(byte[] data)
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
2017-06-11 07:23:04 +00:00
|
|
|
|
if (data.Length != PKX.SIZE_3STORED)
|
|
|
|
|
Array.Resize(ref data, PKX.SIZE_3STORED);
|
|
|
|
|
return new PK3(data);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
}
|
2018-09-15 05:37:47 +00:00
|
|
|
|
|
2019-03-30 02:43:33 +00:00
|
|
|
|
protected override byte[] DecryptPKM(byte[] data)
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
2017-06-11 07:23:04 +00:00
|
|
|
|
if (data.Length != PKX.SIZE_3STORED)
|
|
|
|
|
Array.Resize(ref data, PKX.SIZE_3STORED);
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return PKX.DecryptArray3(data);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-02 18:19:41 +00:00
|
|
|
|
protected override void SetDex(PKM pkm) { /* No Pokedex for this game, do nothing */ }
|
2018-05-12 15:13:39 +00:00
|
|
|
|
|
2019-09-03 02:30:58 +00:00
|
|
|
|
protected override void WriteBoxSlot(PKM pkm, int offset)
|
2016-09-19 05:47:31 +00:00
|
|
|
|
{
|
2019-09-22 20:56:13 +00:00
|
|
|
|
base.WriteBoxSlot(pkm, offset);
|
2019-03-30 00:52:26 +00:00
|
|
|
|
BitConverter.GetBytes((ushort)pkm.TID).CopyTo(Data, offset + PKX.SIZE_3STORED + 0);
|
|
|
|
|
BitConverter.GetBytes((ushort)pkm.SID).CopyTo(Data, offset + PKX.SIZE_3STORED + 2);
|
2016-09-19 05:47:31 +00:00
|
|
|
|
}
|
2017-04-09 21:06:50 +00:00
|
|
|
|
|
2019-03-21 04:50:44 +00:00
|
|
|
|
public override string GetString(byte[] data, int offset, int length) => StringConverter3.GetString3(data, offset, length, Japanese);
|
2018-09-15 05:37:47 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0)
|
2017-04-09 21:06:50 +00:00
|
|
|
|
{
|
|
|
|
|
if (PadToSize == 0)
|
|
|
|
|
PadToSize = maxLength + 1;
|
2019-03-21 04:50:44 +00:00
|
|
|
|
return StringConverter3.SetString3(value, maxLength, Japanese, PadToSize, PadWith);
|
2017-04-09 21:06:50 +00:00
|
|
|
|
}
|
2016-09-19 05:47:31 +00:00
|
|
|
|
}
|
|
|
|
|
}
|