2018-12-30 05:24:38 +00:00
using System ;
using System.Text ;
namespace PKHeX.Core
{
2018-12-30 07:38:59 +00:00
/// <summary>
/// Record of a received <see cref="WB7"/> file.
/// </summary>
/// <remarks>
/// A full <see cref="WB7"/> is not stored in the <see cref="SAV7b"/> structure, as it is immediately converted to <see cref="PKM"/> upon receiving from server.
/// The save file just stores a summary of the received data for the user to look back at.
/// </remarks>
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 sealed class WR7 : DataMysteryGift
2018-12-30 05:24:38 +00:00
{
2018-12-30 07:33:36 +00:00
public const int Size = 0x140 ;
2018-12-30 05:24:38 +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 WR7 ( ) : this ( new byte [ Size ] ) { }
public WR7 ( byte [ ] data ) : base ( data ) { }
2018-12-30 05:24:38 +00:00
public uint Epoch
{
get = > BitConverter . ToUInt32 ( Data , 0x00 ) ;
set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x00 ) ;
}
public DateTime Date = > new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) . AddSeconds ( Epoch ) ;
2018-12-30 06:09:27 +00:00
public override int CardID
2018-12-30 05:24:38 +00:00
{
get = > BitConverter . ToUInt16 ( Data , 0x08 ) ;
2018-12-30 06:09:27 +00:00
set = > BitConverter . GetBytes ( ( ushort ) value ) . CopyTo ( Data , 0x08 ) ;
2018-12-30 05:24:38 +00:00
}
public ushort CardType
{
get = > BitConverter . ToUInt16 ( Data , 0x0A ) ;
set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x0A ) ;
}
2018-12-30 06:09:27 +00:00
public WR7GiftType GiftType
2018-12-30 05:24:38 +00:00
{
2018-12-30 06:09:27 +00:00
get = > ( WR7GiftType ) Data [ 0x0C ] ;
2018-12-30 05:24:38 +00:00
set = > Data [ 0x0C ] = ( byte ) value ;
}
public int ItemCount
{
get = > Data [ 0x0D ] ;
set = > Data [ 0x0D ] = ( byte ) value ;
}
2018-12-30 07:38:59 +00:00
// unknown: region from 0x10 to 0xFF ?
2018-12-30 06:09:27 +00:00
public override int Species
2018-12-30 05:24:38 +00:00
{
get = > BitConverter . ToUInt16 ( Data , 0x10C ) ;
2018-12-30 06:09:27 +00:00
set = > BitConverter . GetBytes ( ( ushort ) value ) . CopyTo ( Data , 0x10C ) ;
2018-12-30 05:24:38 +00:00
}
2018-12-30 06:09:27 +00:00
public override bool GiftUsed { get ; set ; }
2018-12-30 07:38:59 +00:00
public override int Level // are moves stored? mew has '1' but this could be move
2018-12-30 05:24:38 +00:00
{
get = > BitConverter . ToUInt16 ( Data , 0x10E ) ;
2018-12-30 06:09:27 +00:00
set = > BitConverter . GetBytes ( ( ushort ) value ) . CopyTo ( Data , 0x10E ) ;
2018-12-30 05:24:38 +00:00
}
2018-12-30 06:09:27 +00:00
public override int ItemID { get = > BitConverter . ToUInt16 ( Data , 0x110 ) ; set = > BitConverter . GetBytes ( ( ushort ) value ) . CopyTo ( Data , 0x110 ) ; }
public ushort ItemIDCount { get = > BitConverter . ToUInt16 ( Data , 0x112 ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x112 ) ; }
2018-12-30 05:24:38 +00:00
public ushort ItemSet2Item { get = > BitConverter . ToUInt16 ( Data , 0x114 ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x114 ) ; }
public ushort ItemSet2Count { get = > BitConverter . ToUInt16 ( Data , 0x116 ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x116 ) ; }
public ushort ItemSet3Item { get = > BitConverter . ToUInt16 ( Data , 0x118 ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x118 ) ; }
public ushort ItemSet3Count { get = > BitConverter . ToUInt16 ( Data , 0x11A ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x11A ) ; }
public ushort ItemSet4Item { get = > BitConverter . ToUInt16 ( Data , 0x11C ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x11C ) ; }
public ushort ItemSet4Count { get = > BitConverter . ToUInt16 ( Data , 0x11E ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x11E ) ; }
public ushort ItemSet5Item { get = > BitConverter . ToUInt16 ( Data , 0x120 ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x120 ) ; } // struct union overlaps OT Name data, beware!
public ushort ItemSet5Count { get = > BitConverter . ToUInt16 ( Data , 0x122 ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x122 ) ; }
public ushort ItemSet6Item { get = > BitConverter . ToUInt16 ( Data , 0x124 ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x124 ) ; }
public ushort ItemSet6Count { get = > BitConverter . ToUInt16 ( Data , 0x126 ) ; set = > BitConverter . GetBytes ( value ) . CopyTo ( Data , 0x126 ) ; }
2018-12-30 06:09:27 +00:00
public override int Gender { get ; set ; }
public override int Form { get ; set ; }
public override int TID { get ; set ; }
public override int SID { get ; set ; }
public override string OT_Name
2018-12-30 05:24:38 +00:00
{
get = > Util . TrimFromZero ( Encoding . Unicode . GetString ( Data , 0x120 , 0x1A ) ) ;
set = > Encoding . Unicode . GetBytes ( value . PadRight ( value . Length + 1 , '\0' ) ) . CopyTo ( Data , 0x120 + 0xB6 ) ; // careful with length
}
public LanguageID LanguageReceived
{
get = > ( LanguageID ) Data [ 0x13A ] ;
set = > Data [ 0x13A ] = ( byte ) value ;
}
2018-12-30 06:09:27 +00:00
// Mystery Gift implementation
public override int Format = > 7 ;
2019-12-29 03:00:01 +00:00
protected override bool IsMatchExact ( PKM pkm ) = > false ;
2018-12-30 06:09:27 +00:00
protected override bool IsMatchDeferred ( PKM pkm ) = > false ;
public override int Location { get ; set ; }
public override int EggLocation { get ; set ; }
public override int Ball { get ; set ; } = 4 ;
2018-12-30 06:15:40 +00:00
public override string CardTitle { get = > $"{nameof(WB7)} Record ({OT_Name}) [{LanguageReceived}]" ; set { } }
2018-12-30 06:09:27 +00:00
public override bool IsItem
{
get = > GiftType = = WR7GiftType . Item ;
set
{
if ( value )
GiftType = WR7GiftType . Item ;
}
}
public override bool IsPokémon
{
get = > GiftType = = WR7GiftType . Pokemon ;
set
{
if ( value )
GiftType = WR7GiftType . Pokemon ;
}
}
2018-12-30 07:33:36 +00:00
2020-06-17 02:46:22 +00:00
public override PKM ConvertToPKM ( ITrainerInfo sav , EncounterCriteria criteria )
2018-12-30 07:33:36 +00:00
{
2018-12-30 07:38:59 +00:00
// this method shouldn't really be called, use the WB7 data not the WR7 data.
2018-12-30 07:33:36 +00:00
if ( ! IsPokémon )
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
throw new ArgumentException ( nameof ( IsPokémon ) ) ;
2018-12-30 07:33:36 +00:00
2018-12-30 07:38:59 +00:00
// we'll just generate something as close as we can, since we must return something!
2018-12-30 07:33:36 +00:00
var pk = new PB7 ( ) ;
2020-06-17 02:46:22 +00:00
sav . ApplyTo ( pk ) ;
if ( ! GameVersion . GG . Contains ( ( GameVersion ) sav . Game ) )
2018-12-30 07:33:36 +00:00
pk . Version = ( int ) GameVersion . GP ;
pk . Species = Species ;
pk . Met_Level = pk . CurrentLevel = Level ;
2018-12-30 07:38:59 +00:00
pk . MetDate = Date ;
2018-12-30 07:33:36 +00:00
2018-12-30 07:38:59 +00:00
return pk ; // can't really do much more, just return the rough data
2018-12-30 07:33:36 +00:00
}
2018-12-30 05:24:38 +00:00
}
}