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 ;
using System.Collections.Generic ;
2017-08-05 08:51:29 +00:00
using System.Runtime.CompilerServices ;
2017-08-03 07:59:39 +00:00
namespace PKHeX.Core
2017-04-23 16:18:42 +00:00
{
2020-09-03 21:28:51 +00:00
/// <summary>
/// 32 Bit Linear Congruential Random Number Generator
/// </summary>
/// <remarks>
/// Provides common RNG algorithms used by Generation 3 & 4.
/// https://en.wikipedia.org/wiki/Linear_congruential_generator
/// </remarks>
2018-08-03 03:11:42 +00:00
public sealed class RNG
2017-04-23 16:18:42 +00:00
{
2020-09-03 21:28:51 +00:00
/// <summary> LCRNG used for Encryption and mainline game RNG calls. </summary>
2020-12-22 01:17:56 +00:00
public static readonly RNG LCRNG = new ( 0x41C64E6D , 0x00006073 , 0xEEB9EB65 , 0x0A3561A1 ) ;
2020-09-03 21:28:51 +00:00
/// <summary> LCRNG used by Colosseum & XD for game RNG calls. </summary>
2020-12-22 01:17:56 +00:00
public static readonly RNG XDRNG = new ( 0x000343FD , 0x00269EC3 , 0xB9B33155 , 0xA170F641 ) ;
2020-09-03 21:28:51 +00:00
/// <summary> Alternate LCRNG used by mainline game RNG calls to disassociate the seed from the <see cref="LCRNG"/>, for anti-shiny and other purposes. </summary>
2020-12-22 01:17:56 +00:00
public static readonly RNG ARNG = new ( 0x6C078965 , 0x00000001 , 0x9638806D , 0x69C77F93 ) ;
2017-04-23 16:18:42 +00:00
private readonly uint Mult , Add , rMult , rAdd ;
2017-08-03 07:59:39 +00:00
// Bruteforce cache for searching seeds
private const int cacheSize = 1 < < 16 ;
2017-08-04 04:35:41 +00:00
// 1,2 (no gap)
private readonly uint k2 ; // Mult<<8
2017-08-03 07:59:39 +00:00
private readonly byte [ ] low8 = new byte [ cacheSize ] ;
private readonly bool [ ] flags = new bool [ cacheSize ] ;
2017-08-04 04:35:41 +00:00
// 1,3 (single gap)
private readonly uint k0g ; // Mult*Mult
private readonly uint k2s ; // Mult*Mult<<8
private readonly byte [ ] g_low8 = new byte [ cacheSize ] ;
private readonly bool [ ] g_flags = new bool [ cacheSize ] ;
2017-08-05 08:51:29 +00:00
// Euclidean division approach
private readonly long t0 ; // Add - 0xFFFF
private readonly long t1 ; // 0xFFFF * ((long)Mult + 1)
2017-08-03 07:59:39 +00:00
2017-04-29 23:22:32 +00:00
private RNG ( uint f_mult , uint f_add , uint r_mult , uint r_add )
2017-04-23 16:18:42 +00:00
{
Mult = f_mult ;
Add = f_add ;
rMult = r_mult ;
rAdd = r_add ;
2017-08-03 07:59:39 +00:00
// Set up bruteforce utility
k2 = Mult < < 8 ;
2017-08-04 04:35:41 +00:00
k0g = Mult * Mult ;
k2s = k0g < < 8 ;
2017-08-03 07:59:39 +00:00
PopulateMeetMiddleArrays ( ) ;
2017-08-05 08:51:29 +00:00
t0 = Add - 0xFFFF ;
t1 = 0xFFFF * ( ( long ) Mult + 1 ) ;
2017-08-03 07:59:39 +00:00
}
private void PopulateMeetMiddleArrays ( )
{
2017-08-04 04:35:41 +00:00
uint k4g = Add * ( Mult + 1 ) ; // 1,3's multiplier
2017-08-03 07:59:39 +00:00
for ( uint i = 0 ; i < = byte . MaxValue ; i + + )
{
2017-08-04 04:35:41 +00:00
SetFlagData ( i , Mult , Add , flags , low8 ) ; // 1,2
SetFlagData ( i , k0g , k4g , g_flags , g_low8 ) ; // 1,3
2017-08-03 07:59:39 +00:00
}
2017-04-23 16:18:42 +00:00
}
2017-08-04 04:35:41 +00:00
private static void SetFlagData ( uint i , uint mult , uint add , bool [ ] f , byte [ ] v )
{
// the second rand() also has 16 bits that aren't known. It is a 16 bit value added to either side.
// to consider these bits and their impact, they can at most increment/decrement the result by 1.
// with the current calc setup, the search loop's calculated value may be -1 (loop does subtraction)
// since LCGs are linear (hence the name), there's no values in adjacent cells. (no collisions)
// if we mark the prior adjacent cell, we eliminate the need to check flags twice on each loop.
2018-08-03 03:11:42 +00:00
uint right = ( mult * i ) + add ;
2017-08-04 04:35:41 +00:00
ushort val = ( ushort ) ( right > > 16 ) ;
f [ val ] = true ; v [ val ] = ( byte ) i ;
- - val ;
f [ val ] = true ; v [ val ] = ( byte ) i ;
// now the search only has to access the flags array once per loop.
}
2020-09-03 21:28:51 +00:00
/// <summary>
/// Advances the RNG seed to the next state value.
/// </summary>
/// <param name="seed">Current seed</param>
/// <returns>Seed advanced a single time.</returns>
2017-08-05 08:51:29 +00:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2018-08-03 03:11:42 +00:00
public uint Next ( uint seed ) = > ( seed * Mult ) + Add ;
2020-09-03 21:28:51 +00:00
/// <summary>
/// Reverses the RNG seed to the previous state value.
/// </summary>
/// <param name="seed">Current seed</param>
/// <returns>Seed reversed a single time.</returns>
2017-08-05 08:51:29 +00:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2018-08-03 03:11:42 +00:00
public uint Prev ( uint seed ) = > ( seed * rMult ) + rAdd ;
2017-04-23 16:18:42 +00:00
2020-09-03 21:28:51 +00:00
/// <summary>
/// Advances the RNG seed to the next state value a specified amount of times.
/// </summary>
/// <param name="seed">Current seed</param>
/// <param name="frames">Amount of times to advance.</param>
/// <returns>Seed advanced the specified amount of times.</returns>
2017-08-05 08:51:29 +00:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2017-04-29 23:22:32 +00:00
public uint Advance ( uint seed , int frames )
2017-04-23 16:18:42 +00:00
{
for ( int i = 0 ; i < frames ; i + + )
seed = Next ( seed ) ;
return seed ;
}
2018-08-03 03:11:42 +00:00
2020-09-03 21:28:51 +00:00
/// <summary>
/// Reverses the RNG seed to the previous state value a specified amount of times.
/// </summary>
/// <param name="seed">Current seed</param>
/// <param name="frames">Amount of times to reverse.</param>
/// <returns>Seed reversed the specified amount of times.</returns>
2017-08-05 08:51:29 +00:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2017-04-29 23:22:32 +00:00
public uint Reverse ( uint seed , int frames )
2017-04-23 16:18:42 +00:00
{
for ( int i = 0 ; i < frames ; i + + )
seed = Prev ( seed ) ;
return seed ;
}
2017-07-16 01:36:55 +00:00
/// <summary>
/// Generates an IV for each RNG call using the top 5 bits of frame seeds.
/// </summary>
/// <param name="seed">RNG seed</param>
2020-09-03 21:28:51 +00:00
/// <returns>Array of 6 IVs as <see cref="uint"/>.</returns>
2017-08-05 08:51:29 +00:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2017-07-16 01:36:55 +00:00
internal uint [ ] GetSequentialIVsUInt32 ( uint seed )
{
uint [ ] ivs = new uint [ 6 ] ;
for ( int i = 0 ; i < 6 ; i + + )
{
seed = Next ( seed ) ;
ivs [ i ] = seed > > 27 ;
}
return ivs ;
}
2018-08-03 03:11:42 +00:00
2020-09-03 21:28:51 +00:00
/// <summary>
/// Generates an IV for each RNG call using the top 5 bits of frame seeds.
/// </summary>
/// <param name="seed">RNG seed</param>
/// <returns>Array of 6 IVs as <see cref="int"/>.</returns>
2017-08-05 08:51:29 +00:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2017-07-16 01:36:55 +00:00
internal int [ ] GetSequentialIVsInt32 ( uint seed )
{
int [ ] ivs = new int [ 6 ] ;
for ( int i = 0 ; i < 6 ; i + + )
{
seed = Next ( seed ) ;
ivs [ i ] = ( int ) ( seed > > 27 ) ;
}
return ivs ;
}
2017-08-03 07:59:39 +00:00
/// <summary>
2017-08-05 08:51:29 +00:00
/// Gets the origin seeds for two successive 16 bit rand() calls using a meet-in-the-middle approach.
2017-08-03 07:59:39 +00:00
/// </summary>
/// <param name="first">First rand() call, 16 bits, already shifted left 16 bits.</param>
/// <param name="second">Second rand() call, 16 bits, already shifted left 16 bits.</param>
/// <remarks>
/// Use a meet-in-the-middle attack to reduce the search space to 2^8 instead of 2^16
/// flag/2^8 tables are precomputed and constant (unrelated to rand pairs)
2017-08-05 08:51:29 +00:00
/// https://crypto.stackexchange.com/a/10609
2017-08-03 07:59:39 +00:00
/// </remarks>
/// <returns>Possible origin seeds that generate the 2 random numbers</returns>
2017-08-05 08:51:29 +00:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2017-08-03 07:59:39 +00:00
internal IEnumerable < uint > RecoverLower16Bits ( uint first , uint second )
{
2018-08-03 03:11:42 +00:00
uint k1 = second - ( first * Mult ) ;
2017-08-03 07:59:39 +00:00
for ( uint i = 0 , k3 = k1 ; i < = 255 ; + + i , k3 - = k2 )
{
ushort val = ( ushort ) ( k3 > > 16 ) ;
if ( flags [ val ] )
yield return Prev ( first | i < < 8 | low8 [ val ] ) ;
}
}
2018-08-03 03:11:42 +00:00
2017-08-04 04:35:41 +00:00
/// <summary>
2017-08-05 08:51:29 +00:00
/// Gets the origin seeds for two 16 bit rand() calls (ignoring a rand() in between) using a meet-in-the-middle approach.
2017-08-04 04:35:41 +00:00
/// </summary>
/// <param name="first">First rand() call, 16 bits, already shifted left 16 bits.</param>
/// <param name="third">Third rand() call, 16 bits, already shifted left 16 bits.</param>
/// <remarks>
/// Use a meet-in-the-middle attack to reduce the search space to 2^8 instead of 2^16
/// flag/2^8 tables are precomputed and constant (unrelated to rand pairs)
2017-08-05 08:51:29 +00:00
/// https://crypto.stackexchange.com/a/10609
2017-08-04 04:35:41 +00:00
/// </remarks>
/// <returns>Possible origin seeds that generate the 2 random numbers</returns>
2017-08-05 08:51:29 +00:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2017-08-04 04:35:41 +00:00
internal IEnumerable < uint > RecoverLower16BitsGap ( uint first , uint third )
{
2018-08-03 03:11:42 +00:00
uint k1 = third - ( first * k0g ) ;
2017-08-04 04:35:41 +00:00
for ( uint i = 0 , k3 = k1 ; i < = 255 ; + + i , k3 - = k2s )
{
ushort val = ( ushort ) ( k3 > > 16 ) ;
if ( g_flags [ val ] )
yield return Prev ( first | i < < 8 | g_low8 [ val ] ) ;
}
}
2018-08-03 03:11:42 +00:00
2017-08-05 08:51:29 +00:00
/// <summary>
/// Gets the origin seeds for two successive 16 bit rand() calls using a Euclidean division approach.
/// </summary>
/// <param name="first">First rand() call, 16 bits, already shifted left 16 bits.</param>
/// <param name="second">Second rand() call, 16 bits, already shifted left 16 bits.</param>
/// <remarks>
/// For favorable multiplier values, this k_max gives a search space less than 2^8 (meet-in-the-middle)
/// For the programmed methods in this program, it is only advantageous to use this with <see cref="XDRNG"/>.
/// https://crypto.stackexchange.com/a/10629
/// </remarks>
/// <returns>Possible origin seeds that generate the 2 random numbers</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal IEnumerable < uint > RecoverLower16BitsEuclid16 ( uint first , uint second )
{
const int bitshift = 32 ;
2019-02-23 23:36:26 +00:00
const long inc = 1L < < bitshift ;
2017-08-05 08:51:29 +00:00
return GetPossibleSeedsEuclid ( first , second , bitshift , inc ) ;
}
2018-08-03 03:11:42 +00:00
2017-08-05 08:51:29 +00:00
/// <summary>
/// Gets the origin seeds for two successive 15 bit rand() calls using a Euclidean division approach.
/// </summary>
/// <param name="first">First rand() call, 15 bits, already shifted left 16 bits.</param>
/// <param name="second">Second rand() call, 15 bits, already shifted left 16 bits.</param>
/// <remarks>
/// Calculate the quotient of the Euclidean division (k_max) attack to reduce the search space.
/// For favorable multiplier values, this k_max gives a search space less than 2^8 (meet-in-the-middle)
/// For the programmed methods in this program, it is only advantageous to use this with <see cref="XDRNG"/>.
/// https://crypto.stackexchange.com/a/10629
/// </remarks>
/// <returns>Possible origin seeds that generate the 2 random numbers</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal IEnumerable < uint > RecoverLower16BitsEuclid15 ( uint first , uint second )
{
const int bitshift = 31 ;
2019-02-23 23:36:26 +00:00
const long inc = 1L < < bitshift ;
2017-08-05 08:51:29 +00:00
return GetPossibleSeedsEuclid ( first , second , bitshift , inc ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private IEnumerable < uint > GetPossibleSeedsEuclid ( uint first , uint second , int bitshift , long inc )
{
2018-08-03 03:11:42 +00:00
long t = second - ( Mult * first ) - t0 ;
2017-08-05 08:51:29 +00:00
long kmax = ( ( ( t1 - t ) > > bitshift ) < < bitshift ) + t ;
for ( long k = t ; k < = kmax ; k + = inc )
{
// compute modulo in steps for reuse in yielded value (x % Mult)
long fix = k / Mult ;
2018-08-03 03:11:42 +00:00
long remainder = k - ( Mult * fix ) ;
2017-08-05 08:51:29 +00:00
if ( remainder > > 16 = = 0 )
yield return Prev ( first | ( uint ) fix ) ;
}
}
2017-04-23 16:18: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
public enum RNGType
{
2020-09-03 21:28:51 +00:00
/// <summary> No RNG type specified </summary>
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
None ,
2020-09-03 21:28:51 +00:00
/// <summary> <see cref="RNG.LCRNG"/> </summary>
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
LCRNG ,
2020-09-03 21:28:51 +00:00
/// <summary> <see cref="RNG.XDRNG"/> </summary>
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
XDRNG ,
2020-09-03 21:28:51 +00:00
/// <summary> <see cref="RNG.ARNG"/> </summary>
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
ARNG ,
}
public static class RNGTypeUtil
{
2021-01-02 01:08:49 +00:00
public static RNG GetRNG ( this RNGType type ) = > type switch
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
{
2021-01-02 01:08:49 +00:00
RNGType . LCRNG = > RNG . LCRNG ,
RNGType . XDRNG = > RNG . XDRNG ,
RNGType . ARNG = > RNG . ARNG ,
_ = > throw new ArgumentException ( nameof ( type ) )
} ;
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
}
2017-04-23 16:18:42 +00:00
}