mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 22:54:14 +00:00
Disassociate Shiny enum from WC6 PIDType (#3461)
Have `Shiny.Random` be `0`, so we can skip init on this field for EncounterStatic. Plus makes it a little less brittle for future expansion if shiny qualities change.
This commit is contained in:
parent
85b7541c9f
commit
93255efcb8
12 changed files with 201 additions and 192 deletions
|
@ -20,7 +20,7 @@ namespace PKHeX.Core
|
|||
|
||||
public virtual int Location { get; init; }
|
||||
public AbilityPermission Ability { get; init; }
|
||||
public Shiny Shiny { get; init; } = Shiny.Random;
|
||||
public Shiny Shiny { get; init; }
|
||||
public Nature Nature { get; init; } = Nature.Random;
|
||||
public sbyte Gender { get; init; } = -1;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace PKHeX.Core
|
|||
|
||||
/// <summary> End result's nature. </summary>
|
||||
/// <remarks> Leave as <see cref="Core.Shiny.Random"/> to not restrict shininess. </remarks>
|
||||
public Shiny Shiny { get; init; } = Shiny.Random;
|
||||
public Shiny Shiny { get; init; }
|
||||
|
||||
public int IV_HP { get; init; } = RandomIV;
|
||||
public int IV_ATK { get; init; } = RandomIV;
|
||||
|
|
|
@ -1,58 +1,45 @@
|
|||
namespace PKHeX.Core
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Specification for <see cref="PKM.IsShiny"/>, used for creating and validating.
|
||||
/// </summary>
|
||||
public enum Shiny : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Specification for <see cref="PKM.IsShiny"/>, used for creating and validating.
|
||||
/// </summary>
|
||||
public enum Shiny : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// PID is fixed to a specified value.
|
||||
/// </summary>
|
||||
FixedValue = 0,
|
||||
/// <summary> PID is purely random; can be shiny or not shiny. </summary>
|
||||
Random = 0,
|
||||
|
||||
/// <summary>
|
||||
/// PID is purely random; can be shiny or not shiny.
|
||||
/// </summary>
|
||||
Random = 1,
|
||||
/// <summary> PID is randomly created and forced to be shiny. </summary>
|
||||
Always,
|
||||
|
||||
/// <summary>
|
||||
/// PID is randomly created and forced to be shiny.
|
||||
/// </summary>
|
||||
Always = 2,
|
||||
/// <summary> PID is randomly created and forced to be not shiny. </summary>
|
||||
Never,
|
||||
|
||||
/// <summary>
|
||||
/// PID is randomly created and forced to be not shiny.
|
||||
/// </summary>
|
||||
Never = 3,
|
||||
/// <summary> PID is randomly created and forced to be shiny as Stars. </summary>
|
||||
AlwaysStar,
|
||||
|
||||
/// <summary>
|
||||
/// PID is randomly created and forced to be shiny as Stars.
|
||||
/// </summary>
|
||||
AlwaysStar = 5,
|
||||
/// <summary> PID is randomly created and forced to be shiny as Squares. </summary>
|
||||
AlwaysSquare,
|
||||
|
||||
/// <summary>
|
||||
/// PID is randomly created and forced to be shiny as Squares.
|
||||
/// </summary>
|
||||
AlwaysSquare = 6,
|
||||
}
|
||||
|
||||
public static partial class Extensions
|
||||
{
|
||||
public static bool IsValid(this Shiny s, PKM pkm) => s switch
|
||||
{
|
||||
Shiny.Always => pkm.IsShiny,
|
||||
Shiny.Never => !pkm.IsShiny,
|
||||
Shiny.AlwaysSquare => pkm.ShinyXor == 0,
|
||||
Shiny.AlwaysStar => pkm.ShinyXor == 1,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
public static bool IsShiny(this Shiny s) => s switch
|
||||
{
|
||||
Shiny.Always => true,
|
||||
Shiny.AlwaysSquare => true,
|
||||
Shiny.AlwaysStar => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
/// <summary> PID is fixed to a specified value. </summary>
|
||||
FixedValue,
|
||||
}
|
||||
|
||||
public static class ShinyExtensions
|
||||
{
|
||||
public static bool IsValid(this Shiny s, PKM pkm) => s switch
|
||||
{
|
||||
Shiny.Always => pkm.IsShiny,
|
||||
Shiny.Never => !pkm.IsShiny,
|
||||
Shiny.AlwaysSquare => pkm.ShinyXor == 0,
|
||||
Shiny.AlwaysStar => pkm.ShinyXor == 1,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
public static bool IsShiny(this Shiny s) => s switch
|
||||
{
|
||||
Shiny.Always => true,
|
||||
Shiny.AlwaysSquare => true,
|
||||
Shiny.AlwaysStar => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
|
22
PKHeX.Core/MysteryGifts/ShinyType6.cs
Normal file
22
PKHeX.Core/MysteryGifts/ShinyType6.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Specification for Generation 6/7 Mystery Gift shiny indications.
|
||||
/// </summary>
|
||||
/// <see cref="WC6.PIDType"/>
|
||||
/// <see cref="WC7.PIDType"/>
|
||||
/// <see cref="WB7.PIDType"/>
|
||||
public enum ShinyType6 : byte
|
||||
{
|
||||
/// <summary> PID is fixed to a specified value. </summary>
|
||||
FixedValue = 0,
|
||||
|
||||
/// <summary> PID is purely random; can be shiny or not shiny. </summary>
|
||||
Random = 1,
|
||||
|
||||
/// <summary> PID is randomly created and forced to be shiny. </summary>
|
||||
Always = 2,
|
||||
|
||||
/// <summary> PID is randomly created and forced to be not shiny. </summary>
|
||||
Never = 3,
|
||||
}
|
25
PKHeX.Core/MysteryGifts/ShinyType8.cs
Normal file
25
PKHeX.Core/MysteryGifts/ShinyType8.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Specification for Generation 6/7 Mystery Gift shiny indications.
|
||||
/// </summary>
|
||||
/// <see cref="WA8.PIDType"/>
|
||||
/// <see cref="WB8.PIDType"/>
|
||||
/// <see cref="WC8.PIDType"/>
|
||||
public enum ShinyType8
|
||||
{
|
||||
/// <summary> PID is randomly created and forced to be not shiny. </summary>
|
||||
Never = 0,
|
||||
|
||||
/// <summary> PID is purely random; can be shiny or not shiny. </summary>
|
||||
Random = 1,
|
||||
|
||||
/// <summary> PID is randomly created and forced to be shiny as Stars. </summary>
|
||||
AlwaysStar = 2,
|
||||
|
||||
/// <summary> PID is randomly created and forced to be shiny as Squares. </summary>
|
||||
AlwaysSquare = 3,
|
||||
|
||||
/// <summary> PID is fixed to a specified value. </summary>
|
||||
FixedValue = 4,
|
||||
}
|
|
@ -76,21 +76,20 @@ namespace PKHeX.Core
|
|||
|
||||
public override bool IsShiny => Shiny.IsShiny();
|
||||
|
||||
public override Shiny Shiny
|
||||
public override Shiny Shiny => PIDType switch
|
||||
{
|
||||
get
|
||||
ShinyType8.FixedValue => GetShinyXor() switch
|
||||
{
|
||||
var type = PIDType;
|
||||
if (type is not Shiny.FixedValue)
|
||||
return type;
|
||||
return GetShinyXor() switch
|
||||
{
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
};
|
||||
}
|
||||
}
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
},
|
||||
ShinyType8.Random => Shiny.Random,
|
||||
ShinyType8.Never => Shiny.Never,
|
||||
ShinyType8.AlwaysStar => Shiny.AlwaysStar,
|
||||
ShinyType8.AlwaysSquare => Shiny.AlwaysSquare,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
private int GetShinyXor()
|
||||
{
|
||||
|
@ -168,13 +167,13 @@ namespace PKHeX.Core
|
|||
|
||||
private byte PIDTypeValue => Data[0x240];
|
||||
|
||||
public Shiny PIDType => PIDTypeValue switch
|
||||
public ShinyType8 PIDType => PIDTypeValue switch
|
||||
{
|
||||
0 => Shiny.Never,
|
||||
1 => Shiny.Random,
|
||||
2 => Shiny.AlwaysStar,
|
||||
3 => Shiny.AlwaysSquare,
|
||||
4 => Shiny.FixedValue,
|
||||
0 => ShinyType8.Never,
|
||||
1 => ShinyType8.Random,
|
||||
2 => ShinyType8.AlwaysStar,
|
||||
3 => ShinyType8.AlwaysSquare,
|
||||
4 => ShinyType8.FixedValue,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(PIDType)),
|
||||
};
|
||||
|
||||
|
@ -593,10 +592,10 @@ namespace PKHeX.Core
|
|||
{
|
||||
if (pkm.Egg_Location != Locations.LinkTrade6)
|
||||
return false;
|
||||
if (PIDType == Shiny.Random && pkm.IsShiny && pkm.ShinyXor > 1)
|
||||
if (PIDType == ShinyType8.Random && pkm.IsShiny && pkm.ShinyXor > 1)
|
||||
return false; // shiny traded egg will always have xor0/1.
|
||||
}
|
||||
if (!PIDType.IsValid(pkm))
|
||||
if (!Shiny.IsValid(pkm))
|
||||
{
|
||||
return false; // can't be traded away for unshiny
|
||||
}
|
||||
|
@ -606,7 +605,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!PIDType.IsValid(pkm)) return false;
|
||||
if (!Shiny.IsValid(pkm)) return false;
|
||||
if (EggLocation != pkm.Egg_Location) return false;
|
||||
if (MetLocation != pkm.Met_Location) return false;
|
||||
}
|
||||
|
|
|
@ -133,8 +133,16 @@ namespace PKHeX.Core
|
|||
|
||||
// Pokémon Properties
|
||||
public override bool IsPokémon { get => CardType == 0; set { if (value) CardType = 0; } }
|
||||
public override bool IsShiny => PIDType == Shiny.Always;
|
||||
public override Shiny Shiny => PIDType;
|
||||
public override bool IsShiny => PIDType == ShinyType6.Always;
|
||||
|
||||
public override Shiny Shiny => PIDType switch
|
||||
{
|
||||
ShinyType6.FixedValue => Shiny.FixedValue,
|
||||
ShinyType6.Random => Shiny.Random,
|
||||
ShinyType6.Always => Shiny.Always,
|
||||
ShinyType6.Never => Shiny.Never,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
public override int TID
|
||||
{
|
||||
|
@ -187,7 +195,7 @@ namespace PKHeX.Core
|
|||
public int Nature { get => (sbyte)Data[CardStart + 0xA0]; set => Data[CardStart + 0xA0] = (byte)value; }
|
||||
public override int Gender { get => Data[CardStart + 0xA1]; set => Data[CardStart + 0xA1] = (byte)value; }
|
||||
public override int AbilityType { get => 3; set => Data[CardStart + 0xA2] = (byte)value; } // no references, always ability 0/1
|
||||
public Shiny PIDType { get => (Shiny)Data[CardStart + 0xA3]; set => Data[CardStart + 0xA3] = (byte)value; }
|
||||
public ShinyType6 PIDType { get => (ShinyType6)Data[CardStart + 0xA3]; set => Data[CardStart + 0xA3] = (byte)value; }
|
||||
public override int EggLocation { get => ReadUInt16LittleEndian(Data.AsSpan(CardStart + 0xA4)); set => WriteUInt16LittleEndian(Data.AsSpan(CardStart + 0xA4), (ushort)value); }
|
||||
public int MetLocation { get => ReadUInt16LittleEndian(Data.AsSpan(CardStart + 0xA6)); set => WriteUInt16LittleEndian(Data.AsSpan(CardStart + 0xA6), (ushort)value); }
|
||||
public int MetLevel { get => Data[CardStart + 0xA8]; set => Data[CardStart + 0xA8] = (byte)value; }
|
||||
|
@ -441,17 +449,17 @@ namespace PKHeX.Core
|
|||
{
|
||||
switch (PIDType)
|
||||
{
|
||||
case Shiny.FixedValue: // Specified
|
||||
case ShinyType6.FixedValue: // Specified
|
||||
pk.PID = PID;
|
||||
break;
|
||||
case Shiny.Random: // Random
|
||||
case ShinyType6.Random: // Random
|
||||
pk.PID = Util.Rand32();
|
||||
break;
|
||||
case Shiny.Always: // Random Shiny
|
||||
case ShinyType6.Always: // Random Shiny
|
||||
pk.PID = Util.Rand32();
|
||||
pk.PID = (uint)(((pk.TID ^ pk.SID ^ (pk.PID & 0xFFFF)) << 16) | (pk.PID & 0xFFFF));
|
||||
break;
|
||||
case Shiny.Never: // Random Nonshiny
|
||||
case ShinyType6.Never: // Random Nonshiny
|
||||
pk.PID = Util.Rand32();
|
||||
if (pk.IsShiny) pk.PID ^= 0x10000000;
|
||||
break;
|
||||
|
@ -541,7 +549,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!PIDType.IsValid(pkm)) return false;
|
||||
if (!Shiny.IsValid(pkm)) return false;
|
||||
if (EggLocation != pkm.Egg_Location) return false;
|
||||
if (MetLocation != pkm.Met_Location) return false;
|
||||
}
|
||||
|
|
|
@ -87,21 +87,20 @@ namespace PKHeX.Core
|
|||
|
||||
public override bool IsShiny => Shiny.IsShiny();
|
||||
|
||||
public override Shiny Shiny
|
||||
public override Shiny Shiny => PIDType switch
|
||||
{
|
||||
get
|
||||
ShinyType8.FixedValue => GetShinyXor() switch
|
||||
{
|
||||
var type = PIDType;
|
||||
if (type is not Shiny.FixedValue)
|
||||
return type;
|
||||
return GetShinyXor() switch
|
||||
{
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
};
|
||||
}
|
||||
}
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
},
|
||||
ShinyType8.Random => Shiny.Random,
|
||||
ShinyType8.Never => Shiny.Never,
|
||||
ShinyType8.AlwaysStar => Shiny.AlwaysStar,
|
||||
ShinyType8.AlwaysSquare => Shiny.AlwaysSquare,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
private int GetShinyXor()
|
||||
{
|
||||
|
@ -179,15 +178,7 @@ namespace PKHeX.Core
|
|||
|
||||
private byte PIDTypeValue => Data[CardStart + 0x290];
|
||||
|
||||
public Shiny PIDType => PIDTypeValue switch
|
||||
{
|
||||
0 => Shiny.Never,
|
||||
1 => Shiny.Random,
|
||||
2 => Shiny.AlwaysStar,
|
||||
3 => Shiny.AlwaysSquare,
|
||||
4 => Shiny.FixedValue,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(PIDType)),
|
||||
};
|
||||
public ShinyType8 PIDType => (ShinyType8)PIDTypeValue;
|
||||
|
||||
public int MetLevel { get => Data[CardStart + 0x291]; set => Data[CardStart + 0x291] = (byte)value; }
|
||||
|
||||
|
@ -598,10 +589,10 @@ namespace PKHeX.Core
|
|||
{
|
||||
if (pkm.Egg_Location != Locations.LinkTrade6NPC)
|
||||
return false;
|
||||
if (PIDType == Shiny.Random && pkm.IsShiny && pkm.ShinyXor > 1)
|
||||
if (PIDType == ShinyType8.Random && pkm.IsShiny && pkm.ShinyXor > 1)
|
||||
return false; // shiny traded egg will always have xor0/1.
|
||||
}
|
||||
if (!PIDType.IsValid(pkm))
|
||||
if (!Shiny.IsValid(pkm))
|
||||
{
|
||||
return false; // can't be traded away for unshiny
|
||||
}
|
||||
|
@ -611,7 +602,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!PIDType.IsValid(pkm)) return false;
|
||||
if (!Shiny.IsValid(pkm)) return false;
|
||||
if (EggLocation != pkm.Egg_Location) return false;
|
||||
if (MetLocation != pkm.Met_Location) return false;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace PKHeX.Core
|
|||
public override bool IsEgg { get; set; }
|
||||
public override IReadOnlyList<int> Moves { get; set; } = Array.Empty<int>();
|
||||
public bool NotDistributed { get; init; }
|
||||
public override Shiny Shiny { get; init; } = Shiny.Random;
|
||||
public override Shiny Shiny { get; init; }
|
||||
public bool Fateful { get; init; } // Obedience Flag
|
||||
|
||||
// Mystery Gift Properties
|
||||
|
|
|
@ -124,24 +124,19 @@ namespace PKHeX.Core
|
|||
public override bool IsPokémon { get => CardType == 0; set { if (value) CardType = 0; } }
|
||||
public override bool IsShiny => Shiny.IsShiny();
|
||||
|
||||
public override Shiny Shiny
|
||||
public override Shiny Shiny => IsEgg ? Shiny.Random : PIDType switch
|
||||
{
|
||||
get
|
||||
ShinyType6.FixedValue => GetShinyXor() switch
|
||||
{
|
||||
if (IsEgg)
|
||||
return Shiny.Random;
|
||||
|
||||
var type = PIDType;
|
||||
if (type is not Shiny.FixedValue)
|
||||
return type;
|
||||
return GetShinyXor() switch
|
||||
{
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
};
|
||||
}
|
||||
}
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
},
|
||||
ShinyType6.Random => Shiny.Random,
|
||||
ShinyType6.Never => Shiny.Never,
|
||||
ShinyType6.Always => Shiny.Always,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
private int GetShinyXor()
|
||||
{
|
||||
|
@ -180,7 +175,7 @@ namespace PKHeX.Core
|
|||
public int Nature { get => (sbyte)Data[0xA0]; set => Data[0xA0] = (byte)value; }
|
||||
public override int Gender { get => Data[0xA1]; set => Data[0xA1] = (byte)value; }
|
||||
public override int AbilityType { get => Data[0xA2]; set => Data[0xA2] = (byte)value; }
|
||||
public Shiny PIDType { get => (Shiny)Data[0xA3]; set => Data[0xA3] = (byte)value; }
|
||||
public ShinyType6 PIDType { get => (ShinyType6)Data[0xA3]; set => Data[0xA3] = (byte)value; }
|
||||
public override int EggLocation { get => ReadUInt16LittleEndian(Data.AsSpan(0xA4)); set => WriteUInt16LittleEndian(Data.AsSpan(0xA4), (ushort)value); }
|
||||
public int MetLocation { get => ReadUInt16LittleEndian(Data.AsSpan(0xA6)); set => WriteUInt16LittleEndian(Data.AsSpan(0xA6), (ushort)value); }
|
||||
|
||||
|
@ -461,17 +456,17 @@ namespace PKHeX.Core
|
|||
{
|
||||
switch (PIDType)
|
||||
{
|
||||
case Shiny.FixedValue: // Specified
|
||||
case ShinyType6.FixedValue: // Specified
|
||||
pk.PID = PID;
|
||||
break;
|
||||
case Shiny.Random: // Random
|
||||
case ShinyType6.Random: // Random
|
||||
pk.PID = Util.Rand32();
|
||||
break;
|
||||
case Shiny.Always: // Random Shiny
|
||||
case ShinyType6.Always: // Random Shiny
|
||||
pk.PID = Util.Rand32();
|
||||
pk.PID = (uint)(((pk.TID ^ pk.SID ^ (pk.PID & 0xFFFF)) << 16) | (pk.PID & 0xFFFF));
|
||||
break;
|
||||
case Shiny.Never: // Random Nonshiny
|
||||
case ShinyType6.Never: // Random Nonshiny
|
||||
pk.PID = Util.Rand32();
|
||||
if (pk.IsShiny) pk.PID ^= 0x10000000;
|
||||
break;
|
||||
|
@ -514,8 +509,8 @@ namespace PKHeX.Core
|
|||
if (OTGender != pkm.OT_Gender) return false;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(OT_Name) && OT_Name != pkm.OT_Name) return false;
|
||||
if (PIDType == Shiny.FixedValue && pkm.PID != PID) return false;
|
||||
if (!PIDType.IsValid(pkm)) return false;
|
||||
if (PIDType == ShinyType6.FixedValue && pkm.PID != PID) return false;
|
||||
if (!Shiny.IsValid(pkm)) return false;
|
||||
if (OriginGame != 0 && OriginGame != pkm.Version) return false;
|
||||
if (EncryptionConstant != 0 && EncryptionConstant != pkm.EncryptionConstant) return false;
|
||||
if (Language != 0 && Language != pkm.Language) return false;
|
||||
|
|
|
@ -139,24 +139,19 @@ namespace PKHeX.Core
|
|||
public override bool IsPokémon { get => CardType == 0; set { if (value) CardType = 0; } }
|
||||
public override bool IsShiny => Shiny.IsShiny();
|
||||
|
||||
public override Shiny Shiny
|
||||
public override Shiny Shiny => IsEgg ? Shiny.Random : PIDType switch
|
||||
{
|
||||
get
|
||||
ShinyType6.FixedValue => GetShinyXor() switch
|
||||
{
|
||||
if (IsEgg)
|
||||
return Shiny.Random;
|
||||
|
||||
var type = PIDType;
|
||||
if (type is not Shiny.FixedValue)
|
||||
return type;
|
||||
return GetShinyXor() switch
|
||||
{
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
};
|
||||
}
|
||||
}
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
},
|
||||
ShinyType6.Random => Shiny.Random,
|
||||
ShinyType6.Never => Shiny.Never,
|
||||
ShinyType6.Always => Shiny.Always,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
private int GetShinyXor()
|
||||
{
|
||||
|
@ -220,7 +215,7 @@ namespace PKHeX.Core
|
|||
public int Nature { get => (sbyte)Data[0xA0]; set => Data[0xA0] = (byte)value; }
|
||||
public override int Gender { get => Data[0xA1]; set => Data[0xA1] = (byte)value; }
|
||||
public override int AbilityType { get => Data[0xA2]; set => Data[0xA2] = (byte)value; }
|
||||
public Shiny PIDType { get => (Shiny)Data[0xA3]; set => Data[0xA3] = (byte)value; }
|
||||
public ShinyType6 PIDType { get => (ShinyType6)Data[0xA3]; set => Data[0xA3] = (byte)value; }
|
||||
public override int EggLocation { get => ReadUInt16LittleEndian(Data.AsSpan(0xA4)); set => WriteUInt16LittleEndian(Data.AsSpan(0xA4), (ushort)value); }
|
||||
public int MetLocation { get => ReadUInt16LittleEndian(Data.AsSpan(0xA6)); set => WriteUInt16LittleEndian(Data.AsSpan(0xA6), (ushort)value); }
|
||||
public int MetLevel { get => Data[0xA8]; set => Data[0xA8] = (byte)value; }
|
||||
|
@ -492,17 +487,17 @@ namespace PKHeX.Core
|
|||
{
|
||||
switch (PIDType)
|
||||
{
|
||||
case Shiny.FixedValue: // Specified
|
||||
case ShinyType6.FixedValue: // Specified
|
||||
pk.PID = PID;
|
||||
break;
|
||||
case Shiny.Random: // Random
|
||||
case ShinyType6.Random: // Random
|
||||
pk.PID = Util.Rand32();
|
||||
break;
|
||||
case Shiny.Always: // Random Shiny
|
||||
case ShinyType6.Always: // Random Shiny
|
||||
pk.PID = Util.Rand32();
|
||||
pk.PID = (uint)(((pk.TID ^ pk.SID ^ (pk.PID & 0xFFFF)) << 16) | (pk.PID & 0xFFFF));
|
||||
break;
|
||||
case Shiny.Never: // Random Nonshiny
|
||||
case ShinyType6.Never: // Random Nonshiny
|
||||
pk.PID = Util.Rand32();
|
||||
if (pk.IsShiny) pk.PID ^= 0x10000000;
|
||||
break;
|
||||
|
@ -571,7 +566,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!PIDType.IsValid(pkm)) return false;
|
||||
if (!Shiny.IsValid(pkm)) return false;
|
||||
if (EggLocation != pkm.Egg_Location) return false;
|
||||
if (MetLocation != pkm.Met_Location) return false;
|
||||
}
|
||||
|
|
|
@ -81,23 +81,20 @@ namespace PKHeX.Core
|
|||
|
||||
public override bool IsShiny => Shiny.IsShiny();
|
||||
|
||||
public override Shiny Shiny
|
||||
public override Shiny Shiny => PIDType switch
|
||||
{
|
||||
get
|
||||
ShinyType8.FixedValue => IsHOMEGift && IsHOMEShinyPossible() ? Shiny.Random : GetShinyXor() switch
|
||||
{
|
||||
var type = PIDType;
|
||||
if (type is not Shiny.FixedValue)
|
||||
return type;
|
||||
if (IsHOMEGift && IsHOMEShinyPossible())
|
||||
return Shiny.Random;
|
||||
return GetShinyXor() switch
|
||||
{
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
};
|
||||
}
|
||||
}
|
||||
0 => Shiny.AlwaysSquare,
|
||||
<= 15 => Shiny.AlwaysStar,
|
||||
_ => Shiny.Never,
|
||||
},
|
||||
ShinyType8.Random => Shiny.Random,
|
||||
ShinyType8.Never => Shiny.Never,
|
||||
ShinyType8.AlwaysStar => Shiny.AlwaysStar,
|
||||
ShinyType8.AlwaysSquare => Shiny.AlwaysSquare,
|
||||
_ => throw new ArgumentOutOfRangeException(),
|
||||
};
|
||||
|
||||
private int GetShinyXor()
|
||||
{
|
||||
|
@ -173,17 +170,7 @@ namespace PKHeX.Core
|
|||
public int Nature { get => (sbyte)Data[CardStart + 0x246]; set => Data[CardStart + 0x246] = (byte)value; }
|
||||
public override int AbilityType { get => Data[CardStart + 0x247]; set => Data[CardStart + 0x247] = (byte)value; }
|
||||
|
||||
private byte PIDTypeValue => Data[CardStart + 0x248];
|
||||
|
||||
public Shiny PIDType => PIDTypeValue switch
|
||||
{
|
||||
0 => Shiny.Never,
|
||||
1 => Shiny.Random,
|
||||
2 => Shiny.AlwaysStar,
|
||||
3 => Shiny.AlwaysSquare,
|
||||
4 => Shiny.FixedValue,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(PIDType)),
|
||||
};
|
||||
public ShinyType8 PIDType { get => (ShinyType8)Data[CardStart + 0x248]; set => Data[CardStart + 0x248] = (byte)value; }
|
||||
|
||||
public int MetLevel { get => Data[CardStart + 0x249]; set => Data[CardStart + 0x249] = (byte)value; }
|
||||
public byte DynamaxLevel { get => Data[CardStart + 0x24A]; set => Data[CardStart + 0x24A] = value; }
|
||||
|
@ -524,15 +511,15 @@ namespace PKHeX.Core
|
|||
_ => AbilityPermission.Any12H,
|
||||
};
|
||||
|
||||
private uint GetPID(ITrainerID tr, byte type)
|
||||
private uint GetPID(ITrainerID tr, ShinyType8 type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
0 => GetAntishiny(tr), // Random, Never Shiny
|
||||
1 => Util.Rand32(), // Random, Any
|
||||
2 => (uint) (((tr.TID ^ tr.SID ^ (PID & 0xFFFF) ^ 1) << 16) | (PID & 0xFFFF)), // Fixed, Force Star
|
||||
3 => (uint) (((tr.TID ^ tr.SID ^ (PID & 0xFFFF) ^ 0) << 16) | (PID & 0xFFFF)), // Fixed, Force Square
|
||||
4 => PID, // Fixed, Force Value
|
||||
ShinyType8.Never => GetAntishiny(tr), // Random, Never Shiny
|
||||
ShinyType8.Random => Util.Rand32(), // Random, Any
|
||||
ShinyType8.AlwaysStar => (uint) (((tr.TID ^ tr.SID ^ (PID & 0xFFFF) ^ 1) << 16) | (PID & 0xFFFF)), // Fixed, Force Star
|
||||
ShinyType8.AlwaysSquare => (uint) (((tr.TID ^ tr.SID ^ (PID & 0xFFFF) ^ 0) << 16) | (PID & 0xFFFF)), // Fixed, Force Square
|
||||
ShinyType8.FixedValue => PID, // Fixed, Force Value
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type)),
|
||||
};
|
||||
|
||||
|
@ -547,7 +534,7 @@ namespace PKHeX.Core
|
|||
|
||||
private void SetPID(PKM pk)
|
||||
{
|
||||
pk.PID = GetPID(pk, PIDTypeValue);
|
||||
pk.PID = GetPID(pk, PIDType);
|
||||
}
|
||||
|
||||
private void SetIVs(PKM pk)
|
||||
|
@ -624,10 +611,10 @@ namespace PKHeX.Core
|
|||
{
|
||||
if (pkm.Egg_Location != Locations.LinkTrade6)
|
||||
return false;
|
||||
if (PIDType == Shiny.Random && pkm.IsShiny && pkm.ShinyXor > 1)
|
||||
if (PIDType == ShinyType8.Random && pkm.IsShiny && pkm.ShinyXor > 1)
|
||||
return false; // shiny traded egg will always have xor0/1.
|
||||
}
|
||||
if (!PIDType.IsValid(pkm))
|
||||
if (!Shiny.IsValid(pkm))
|
||||
{
|
||||
return false; // can't be traded away for unshiny
|
||||
}
|
||||
|
@ -637,7 +624,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!PIDType.IsValid(pkm)) return false;
|
||||
if (!Shiny.IsValid(pkm)) return false;
|
||||
if (EggLocation != pkm.Egg_Location) return false;
|
||||
if (MetLocation != pkm.Met_Location) return false;
|
||||
}
|
||||
|
@ -669,8 +656,8 @@ namespace PKHeX.Core
|
|||
// PID Types 0 and 1 do not use the fixed PID value.
|
||||
// Values 2,3 are specific shiny states, and 4 is fixed value.
|
||||
// 2,3,4 can change if it is a traded egg to ensure the same shiny state.
|
||||
var type = PIDTypeValue;
|
||||
if (type <= 1)
|
||||
var type = PIDType;
|
||||
if (type is ShinyType8.Never or ShinyType8.Random)
|
||||
return true;
|
||||
return pkm.PID == GetPID(pkm, type);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue