ArgumentOutOfRangeException

Use the new NET8 API
This commit is contained in:
Kurt
2023-12-09 15:21:10 -08:00
parent edf28f74ff
commit 1fe2b4f29b
82 changed files with 281 additions and 299 deletions

View File

@@ -93,8 +93,7 @@ public static bool IsRandomRange(ReadOnlySpan<char> str)
public void SetRandomRange(ReadOnlySpan<char> str)
{
var index = str.IndexOf(SplitRange);
if (index <= 0)
throw new ArgumentException($"Invalid Random Range: {str.ToString()}", nameof(str));
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(index);
var min = str[..index];
var max = str[(index + 1)..];

View File

@@ -33,6 +33,39 @@ public static int GetType(ReadOnlySpan<int> IVs)
return SixBitType[hp];
}
/// <summary>
/// Gets the current Hidden Power Type of the input IVs for Generations 3+
/// </summary>
/// <param name="u32">32-bit value of the IVs</param>
/// <returns>Hidden Power Type of the IVs</returns>
public static int GetType(uint u32)
{
uint hp = 0;
for (int i = 0; i < 6; i++)
{
hp |= (u32 & 1) << i;
u32 >>= 5;
}
return SixBitType[(int)hp];
}
/// <summary>
/// Gets the current Hidden Power Type of the input IVs for Generations 3+
/// </summary>
/// <param name="u32">32-bit value of the IVs</param>
/// <remarks>IVs are stored in reverse order in the 32-bit value</remarks>
/// <returns>Hidden Power Type of the IVs</returns>
public static int GetTypeBigEndian(uint u32)
{
uint hp = 0;
for (int i = 0; i < 6; i++)
{
hp |= (u32 & 1) << (5 - i);
u32 >>= 5;
}
return SixBitType[(int)hp];
}
private static ReadOnlySpan<byte> SixBitType =>
[
// (low-bit mash) * 15 / 63
@@ -193,6 +226,41 @@ private static void ForceLowBits(Span<int> ivs, byte bits)
ivs[i] = (ivs[i] & 0b11110) | ((bits >> i) & 1);
}
/// <inheritdoc cref="SetIVs(int,Span{int},EntityContext)"/>
public static uint SetIVs(int type, uint ivs)
{
var bits = DefaultLowBits[type];
for (int i = 0; i < 6; i++)
{
var bit = (bits >> i) & 1;
var bitIndex = i * 5;
var mask = (1u << bitIndex);
if (bit == 0)
ivs &= ~mask;
else
ivs |= mask;
}
return ivs;
}
/// <inheritdoc cref="SetIVs(int,uint)"/>
/// <remarks>IVs are stored in reverse order in the 32-bit value</remarks>
public static uint SetIVsBigEndian(int type, uint ivs)
{
var bits = DefaultLowBits[type];
for (int i = 0; i < 6; i++)
{
var bit = (bits >> i) & 1;
var bitIndex = (5 - i) * 5;
var mask = (1u << bitIndex);
if (bit == 0)
ivs &= ~mask;
else
ivs |= mask;
}
return ivs;
}
/// <summary>
/// Hidden Power IV values (even or odd) to achieve a specified Hidden Power Type
/// </summary>

View File

@@ -44,7 +44,7 @@ public void Save()
FR or LG or FRLG => "frlg",
C => "c",
GD or SI or GS => "gs",
_ => throw new ArgumentOutOfRangeException(nameof(GameVersion)),
_ => throw new ArgumentOutOfRangeException(nameof(ver), ver, null),
};
private static GameVersion GetVersion(TSave ver)

View File

@@ -13,8 +13,7 @@ public sealed class BoxEdit(SaveFile SAV)
public void LoadBox(int box)
{
if ((uint)box >= SAV.BoxCount)
throw new ArgumentOutOfRangeException(nameof(box));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)box, (uint)SAV.BoxCount);
SAV.AddBoxData(CurrentContents, box, 0);
CurrentBox = box;

View File

@@ -118,7 +118,9 @@ private static GameVersion GetOtherGamePair(GameVersion version)
// 32 -> 30 (US -> SN)
// 33 -> 31 (UM -> MN)
// ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
#pragma warning disable RCS1130 // Bitwise operation on enum without Flags attribute.
return version ^ (GameVersion)0b111110;
#pragma warning restore RCS1130 // Bitwise operation on enum without Flags attribute.
}
private static EncounterEgg CreateEggEncounter(ushort species, byte form, GameVersion version)

View File

@@ -275,7 +275,7 @@ private void SetPINGA(PK9 pk, EncounterCriteria criteria, PersonalInfo9SV pi)
const byte undefinedSize = 0;
var param = new GenerateParam9(Species, pi.Gender, FlawlessIVCount, rollCount,
undefinedSize, undefinedSize, ScaleType, Scale,
Ability, Shiny, IVs: IVs, Nature: Nature);
Ability, Shiny, Nature, IVs: IVs);
var init = Util.Rand.Rand64();
var success = this.TryApply32(pk, init, param, criteria);
@@ -326,9 +326,9 @@ public EncounterMatchRating GetMatchRating(PKM pk)
return IsMatchDeferred(pk);
}
private bool IsMatchLocationExact(PKM pk) => pk.Met_Location == Location;
private static bool IsMatchLocationExact(PKM pk) => pk.Met_Location == Location;
private bool IsMatchLocationRemapped(PKM pk)
private static bool IsMatchLocationRemapped(PKM pk)
{
var met = (ushort)pk.Met_Location;
var version = pk.Version;
@@ -380,7 +380,7 @@ private bool IsMatchPartial(PKM pk)
return true;
var pi = PersonalTable.SV.GetFormEntry(Species, Form);
var param = new GenerateParam9(Species, pi.Gender, FlawlessIVCount, 1, 0, 0, ScaleType, Scale, Ability, Shiny, IVs: IVs, Nature: Nature);
var param = new GenerateParam9(Species, pi.Gender, FlawlessIVCount, 1, 0, 0, ScaleType, Scale, Ability, Shiny, Nature, IVs: IVs);
if (!Encounter9RNG.IsMatch(pk, param, seed))
return true;

View File

@@ -340,9 +340,9 @@ public EncounterMatchRating GetMatchRating(PKM pk)
return IsMatchDeferred(pk);
}
private bool IsMatchLocationExact(PKM pk) => pk.Met_Location == Location;
private static bool IsMatchLocationExact(PKM pk) => pk.Met_Location == Location;
private bool IsMatchLocationRemapped(PKM pk)
private static bool IsMatchLocationRemapped(PKM pk)
{
var met = (ushort)pk.Met_Location;
var version = pk.Version;

View File

@@ -30,6 +30,8 @@ public static class PokewalkerRNG
/// <summary> Species slots per course. </summary>
public const int SlotsPerCourse = 6;
public const int GroupsPerCourse = 3;
public const int SlotsPerGroup = 2;
/// <summary>
/// All species for all Pokéwalker courses.
@@ -170,10 +172,8 @@ public static bool IsValidStrollSeed(uint seed, ushort species, PokewalkerCourse
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static ushort GetSpecies(PokewalkerCourse4 course, int group, int rare)
{
if ((uint)group > 2)
throw new ArgumentOutOfRangeException(nameof(group));
if ((uint)rare > 1)
throw new ArgumentOutOfRangeException(nameof(rare));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)group, GroupsPerCourse);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)rare, SlotsPerGroup);
var span = GetSpecies(course);
return span[(group * 2) + rare];
}

View File

@@ -4,6 +4,7 @@
namespace PKHeX.Core;
#if DEBUG
// ReSharper disable once UnusedType.Global
public static class BallContextUtil
{
/// <summary>

View File

@@ -240,8 +240,7 @@ private static void DisallowLevelUpMove(byte level, ushort move, PK9 pk, Legalit
if (m.Info.Method != LearnMethod.LevelUp || m.Info.Argument != level)
return;
var flagIndex = pk.Permit.RecordPermitIndexes.IndexOf(move);
if (flagIndex == -1)
throw new ArgumentOutOfRangeException(nameof(move), move, "Expected a valid TM index.");
ArgumentOutOfRangeException.ThrowIfNegative(flagIndex, nameof(move)); // Always expect it to match.
if (pk.GetMoveRecordFlag(flagIndex))
return;
m = new MoveResult(LearnMethod.None);

View File

@@ -20,7 +20,7 @@ public override void Verify(LegalityAnalysis data)
if (enc.Species == (int)Species.Wurmple)
VerifyECPIDWurmple(data);
else if (enc.Species is (int)Species.Tandemaus or (int)Species.Dunsparce)
VerifyEC100(data);
VerifyEC100(data, enc.Species);
if (pk.PID == 0)
data.AddLine(Get(LPIDZero, Severity.Fishy));
@@ -96,27 +96,29 @@ private static void VerifyECPIDWurmple(LegalityAnalysis data)
}
}
private static void VerifyEC100(LegalityAnalysis data)
private static void VerifyEC100(LegalityAnalysis data, ushort encSpecies)
{
var pk = data.Entity;
var enc = data.EncounterMatch;
if (pk.Species == enc.Species)
{
uint evoVal = pk.EncryptionConstant % 100;
bool rare = evoVal == 0;
var (species, form) = enc.Species switch
{
(int)Species.Tandemaus => ((ushort)Species.Maushold, rare ? 0 : 1),
(int)Species.Dunsparce => ((ushort)Species.Dudunsparce, rare ? 1 : 0),
_ => throw new ArgumentOutOfRangeException(nameof(enc.Species), "Incorrect EC%100 species."),
};
var str = GameInfo.Strings;
var forms = FormConverter.GetFormList(species, str.Types, str.forms, GameInfo.GenderSymbolASCII, EntityContext.Gen9);
var msg = string.Format(L_XRareFormEvo_0_1, forms[form], rare);
data.AddLine(GetValid(msg, CheckIdentifier.EC));
}
if (pk.Species != encSpecies)
return; // Evolved, don't need to calculate the final evolution for the verbose report.
// Indicate the evolution for the user.
uint evoVal = pk.EncryptionConstant % 100;
bool rare = evoVal == 0;
var (species, form) = GetEvolvedSpeciesForm(encSpecies, rare);
var str = GameInfo.Strings;
var forms = FormConverter.GetFormList(species, str.Types, str.forms, GameInfo.GenderSymbolASCII, EntityContext.Gen9);
var msg = string.Format(L_XRareFormEvo_0_1, forms[form], rare);
data.AddLine(GetValid(msg, CheckIdentifier.EC));
}
private static (ushort, int) GetEvolvedSpeciesForm(ushort species, bool rare) => species switch
{
(int)Species.Tandemaus => ((ushort)Species.Maushold, rare ? 0 : 1),
(int)Species.Dunsparce => ((ushort)Species.Dudunsparce, rare ? 1 : 0),
_ => throw new ArgumentOutOfRangeException(nameof(species), species, "Incorrect EC%100 species."),
};
private static void VerifyEC(LegalityAnalysis data)
{
var pk = data.Entity;

View File

@@ -216,15 +216,13 @@ public bool HasMarkEncounter8
public byte GetRibbonAtIndex(int byteIndex)
{
if ((uint)byteIndex >= RibbonBytesCount)
throw new ArgumentOutOfRangeException(nameof(byteIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)byteIndex, RibbonBytesCount);
return Data[RibbonBytesOffset + byteIndex];
}
public void SetRibbonAtIndex(int byteIndex, byte ribbonIndex)
{
if ((uint)byteIndex >= RibbonBytesCount)
throw new ArgumentOutOfRangeException(nameof(byteIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)byteIndex, RibbonBytesCount);
Data[RibbonBytesOffset + byteIndex] = ribbonIndex;
}
@@ -815,16 +813,13 @@ public override bool IsMatchExact(PKM pk, EvoCriteria evo)
public void SetRibbon(int index, bool value = true)
{
if ((uint)index > (uint)MarkSlump)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)index, (uint)MarkSlump);
if (value)
{
if (GetRibbon(index))
return;
var openIndex = Array.IndexOf(Data, RibbonByteNone, RibbonBytesOffset, RibbonBytesCount);
if (openIndex == -1) // Full?
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfNegative(openIndex, nameof(openIndex)); // Full?
SetRibbonAtIndex(openIndex, (byte)index);
}
else

View File

@@ -217,15 +217,13 @@ public bool HasMarkEncounter8
public byte GetRibbonAtIndex(int byteIndex)
{
if ((uint)byteIndex >= RibbonBytesCount)
throw new ArgumentOutOfRangeException(nameof(byteIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)byteIndex, RibbonBytesCount);
return Data[RibbonBytesOffset + byteIndex];
}
public void SetRibbonAtIndex(int byteIndex, byte ribbonIndex)
{
if ((uint)byteIndex >= RibbonBytesCount)
throw new ArgumentOutOfRangeException(nameof(byteIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)byteIndex, RibbonBytesCount);
Data[RibbonBytesOffset + byteIndex] = ribbonIndex;
}
@@ -832,16 +830,13 @@ private bool IsMatchLocationRemapped(PKM pk)
public void SetRibbon(int index, bool value = true)
{
if ((uint)index > (uint)MarkSlump)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)index, (uint)MarkSlump);
if (value)
{
if (GetRibbon(index))
return;
var openIndex = Array.IndexOf(Data, RibbonByteNone, RibbonBytesOffset, RibbonBytesCount);
if (openIndex == -1) // Full?
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfNegative(openIndex, nameof(openIndex)); // Full?
SetRibbonAtIndex(openIndex, (byte)index);
}
else

View File

@@ -214,15 +214,13 @@ public bool HasMarkEncounter8
public byte GetRibbonAtIndex(int byteIndex)
{
if ((uint)byteIndex >= RibbonBytesCount)
throw new ArgumentOutOfRangeException(nameof(byteIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)byteIndex, RibbonBytesCount);
return Data[RibbonBytesOffset + byteIndex];
}
public void SetRibbonAtIndex(int byteIndex, byte ribbonIndex)
{
if ((uint)byteIndex >= RibbonBytesCount)
throw new ArgumentOutOfRangeException(nameof(byteIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)byteIndex, RibbonBytesCount);
Data[RibbonBytesOffset + byteIndex] = ribbonIndex;
}
@@ -889,16 +887,13 @@ private bool IsHOMEShinyPossible()
public void SetRibbon(int index, bool value = true)
{
if ((uint)index > (uint)MarkSlump)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)index, (uint)MarkSlump);
if (value)
{
if (GetRibbon(index))
return;
var openIndex = Array.IndexOf(Data, RibbonByteNone, RibbonBytesOffset, RibbonBytesCount);
if (openIndex == -1) // Full?
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfNegative(openIndex, nameof(openIndex)); // Full?
SetRibbonAtIndex(openIndex, (byte)index);
}
else

View File

@@ -250,15 +250,13 @@ public bool HasMarkEncounter9
public byte GetRibbonAtIndex(int byteIndex)
{
if ((uint)byteIndex >= RibbonBytesCount)
throw new ArgumentOutOfRangeException(nameof(byteIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)byteIndex, RibbonBytesCount);
return Data[RibbonBytesOffset + byteIndex];
}
public void SetRibbonAtIndex(int byteIndex, byte ribbonIndex)
{
if ((uint)byteIndex >= RibbonBytesCount)
throw new ArgumentOutOfRangeException(nameof(byteIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)byteIndex, RibbonBytesCount);
Data[RibbonBytesOffset + byteIndex] = ribbonIndex;
}
@@ -911,16 +909,13 @@ protected override bool IsMatchPartial(PKM pk)
public void SetRibbon(int index, bool value = true)
{
if ((uint)index > (uint)MarkSlump)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)index, (uint)RibbonPartner);
if (value)
{
if (GetRibbon(index))
return;
var openIndex = Array.IndexOf(Data, RibbonByteNone, RibbonBytesOffset, RibbonBytesCount);
if (openIndex == -1) // Full?
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfNegative(openIndex, nameof(openIndex)); // Full?
SetRibbonAtIndex(openIndex, (byte)index);
}
else

View File

@@ -19,9 +19,7 @@ public sealed class GameDataCore : IHomeTrack, ISpeciesForm, ITrainerID, INature
public GameDataCore(Memory<byte> buffer)
{
if (buffer.Length != HomeCrypto.SIZE_CORE)
throw new ArgumentException("Invalid Core Data Size!");
ArgumentOutOfRangeException.ThrowIfNotEqual(buffer.Length, HomeCrypto.SIZE_CORE);
Buffer = buffer;
}

View File

@@ -522,7 +522,9 @@ public static byte GetHeightScalar(float height, int avgHeight)
result *= 255f;
int value = (int)result;
int unsigned = value & ~(value >> 31);
return (byte)Math.Min(255, unsigned);
if (unsigned > 255)
unsigned = 255;
return (byte)unsigned;
}
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
@@ -539,7 +541,9 @@ public static byte GetWeightScalar(float height, float weight, int avgHeight, in
result *= 255f;
int value = (int)result;
int unsigned = value & ~(value >> 31);
return (byte)Math.Min(255, unsigned);
if (unsigned > 255)
unsigned = 255;
return (byte)unsigned;
}
public static int GetRandomIndex(int bits, int characterIndex, int nature)

View File

@@ -102,8 +102,7 @@ public bool GetIsLearnTutorType(int index)
public void SetIsLearnTutorType(int index, bool value)
{
if ((uint)index >= TutorTypeCount)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, TutorTypeCount);
index += CountTMHM;
if (value)
Data[TMHM + (index >> 3)] |= (byte)(1 << (index & 7));

View File

@@ -82,8 +82,7 @@ public bool GetIsLearnTM(int index)
public void SetIsLearnTM(int index, bool value)
{
if ((uint)index >= CountTMHM)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTMHM);
if (value)
Data[TMHM + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -99,8 +98,7 @@ public bool GetIsLearnTutorType(int index)
public void SetIsLearnTutorType(int index, bool value)
{
if ((uint)index >= TypeTutorsCount)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, TypeTutorsCount);
if (value)
Data[TypeTutors + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -152,8 +150,7 @@ public bool GetIsLearnTutor1(ushort move)
public void SetIsLearnTutor1(int index, bool value)
{
if ((uint)index >= CountTutor1)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTutor1);
if (value)
Data[Tutor1 + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -175,8 +172,7 @@ public bool GetIsLearnTutor2(ushort move)
public void SetIsLearnTutor2(int index, bool value)
{
if ((uint)index >= CountTutor2)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTutor2);
if (value)
Data[Tutor2 + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -198,8 +194,7 @@ public bool GetIsLearnTutor3(ushort move)
public void SetIsLearnTutor3(int index, bool value)
{
if ((uint)index >= CountTutor3)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTutor3);
if (value)
Data[Tutor3 + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -221,8 +216,7 @@ public bool GetIsLearnTutor4(ushort move)
public void SetIsLearnTutor4(int index, bool value)
{
if ((uint)index >= CountTutor4)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTutor4);
if (value)
Data[Tutor4 + (index >> 3)] |= (byte)(1 << (index & 7));
else

View File

@@ -80,8 +80,7 @@ public bool GetIsLearnTM(int index)
public void SetIsLearnTM(int index, bool value)
{
if ((uint)index >= CountTMHM)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTMHM);
if (value)
Data[TMHM + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -97,8 +96,7 @@ public bool GetIsLearnTutorType(int index)
public void SetIsLearnTutorType(int index, bool value)
{
if ((uint)index >= TypeTutorsCount)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, TypeTutorsCount);
if (value)
Data[TypeTutors + (index >> 3)] |= (byte)(1 << (index & 7));
else

View File

@@ -109,8 +109,7 @@ public bool GetIsLearnTutorType(int index)
public void SetIsLearnTutorType(int index, bool value)
{
if ((uint)index >= TypeTutorCount)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, TypeTutorCount);
if (value)
Data[TypeTutor + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -152,8 +151,7 @@ public bool GetIsTutor1(ushort move)
public void SetIsLearnTutor1(int index, bool value)
{
if ((uint)index >= CountTutor1)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTutor1);
if (value)
Data[Tutor1 + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -175,8 +173,7 @@ public bool GetIsLearnTutor2(ushort move)
public void SetIsLearnTutor2(int index, bool value)
{
if ((uint)index >= CountTutor2)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTutor2);
if (value)
Data[Tutor2 + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -198,8 +195,7 @@ public bool GetIsLearnTutor3(ushort move)
public void SetIsLearnTutor3(int index, bool value)
{
if ((uint)index >= CountTutor3)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTutor3);
if (value)
Data[Tutor3 + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -221,8 +217,7 @@ public bool GetIsLearnTutor4(ushort move)
public void SetIsLearnTutor4(int index, bool value)
{
if ((uint)index >= CountTutor4)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTutor4);
if (value)
Data[Tutor4 + (index >> 3)] |= (byte)(1 << (index & 7));
else

View File

@@ -109,8 +109,7 @@ public bool GetIsLearnTutorType(int index)
public void SetIsLearnTutorType(int index, bool value)
{
if ((uint)index >= TypeTutorCount)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, TypeTutorCount);
if (value)
Data[TypeTutor + (index >> 3)] |= (byte)(1 << (index & 7));
else

View File

@@ -115,8 +115,7 @@ public bool GetIsLearnTutorType(int index)
public void SetIsLearnTutorType(int index, bool value)
{
if ((uint)index >= TypeTutorCount)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, TypeTutorCount);
if (value)
Data[TypeTutor + (index >> 3)] |= (byte)(1 << (index & 7));
else

View File

@@ -84,8 +84,7 @@ public bool GetIsLearnTM(int index)
public void SetIsLearnTM(int index, bool value)
{
if ((uint)index >= CountTMHM)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTMHM);
if (value)
Data[TMHM + (index >> 3)] |= (byte)(1 << (index & 7));
else

View File

@@ -97,8 +97,7 @@ public bool GetIsLearnTM(int index)
public void SetIsLearnTM(int index, bool value)
{
if ((uint)index >= CountTM)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTM);
if (value)
Data[TMHM + (index >> 3)] |= (byte)(1 << (index & 7));
else
@@ -114,8 +113,7 @@ public bool GetIsLearnTutorType(int index)
public void SetIsLearnTutorType(int index, bool value)
{
if ((uint)index >= TypeTutorsCount)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, TypeTutorsCount);
if (value)
Data[TypeTutors + (index >> 3)] |= (byte)(1 << (index & 7));
else

View File

@@ -95,7 +95,7 @@ public int GetMoveShopIndex(int randIndexFromCount)
}
bits >>= 1;
}
throw new ArgumentOutOfRangeException(nameof(randIndexFromCount));
throw new ArgumentOutOfRangeException(nameof(randIndexFromCount), randIndexFromCount, "Insufficient bits set in the permission list.");
}
public bool IsRecordPermitted(int index)
@@ -182,8 +182,7 @@ public bool GetIsLearnMoveShop(ushort move)
public static ushort GetMoveShopMove(int index)
{
if ((uint)index >= MoveShopCount)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, MoveShopCount);
return MoveShopMoves[index];
}

View File

@@ -148,8 +148,7 @@ public bool GetIsLearnTutorType(int index)
public void SetIsLearnTutorType(int index, bool value)
{
if ((uint)index >= CountTutorType)
throw new ArgumentOutOfRangeException(nameof(index), index, null);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, CountTutorType);
if (value)
Data[TutorType + (index >> 3)] |= (byte)(1 << (index & 7));
else

View File

@@ -122,6 +122,8 @@ public enum RibbonIndex : byte
MarkMightiest,
MarkTitan,
RibbonPartner = MarkTitan, // Todo DLC2
MAX_COUNT,
}

View File

@@ -17,8 +17,7 @@ public static void ReadKeys(ReadOnlySpan<byte> input, Span<ushort> keys)
public static void Decrypt(ReadOnlySpan<byte> input, Span<byte> output, Span<ushort> keys)
{
if (keys.Length != 4)
throw new ArgumentOutOfRangeException(nameof(keys));
ArgumentOutOfRangeException.ThrowIfNotEqual(keys.Length, 4);
var in16 = MemoryMarshal.Cast<byte, ushort>(input);
var out16 = MemoryMarshal.Cast<byte, ushort>(output);
@@ -42,8 +41,7 @@ public static void Decrypt(ReadOnlySpan<byte> input, Span<byte> output, Span<ush
public static void Encrypt(ReadOnlySpan<byte> input, Span<byte> output, Span<ushort> keys)
{
if (keys.Length != 4)
throw new ArgumentOutOfRangeException(nameof(keys));
ArgumentOutOfRangeException.ThrowIfNotEqual(keys.Length, 4);
var in16 = MemoryMarshal.Cast<byte, ushort>(input);
var out16 = MemoryMarshal.Cast<byte, ushort>(output);

View File

@@ -20,8 +20,7 @@ public static class MemeCrypto
public static bool VerifyMemePOKE(ReadOnlySpan<byte> input, out byte[] output)
{
if (input.Length < MemeKey.SignatureLength)
throw new ArgumentException("Invalid POKE buffer!");
ArgumentOutOfRangeException.ThrowIfLessThan(input.Length, MemeKey.SignatureLength);
var memeLen = input.Length - 8;
var memeIndex = MemeKeyIndex.PokedexAndSaveFile;
for (var i = input.Length - 8; i >= 0; i--)
@@ -122,8 +121,7 @@ public static byte[] SignMemeData(ReadOnlySpan<byte> input, MemeKeyIndex keyInde
private static void SignMemeDataInPlace(Span<byte> data, MemeKeyIndex keyIndex = MemeKeyIndex.PokedexAndSaveFile)
{
// Validate Input
if (data.Length < MemeKey.SignatureLength)
throw new ArgumentException("Cannot sign a buffer less than 0x60 bytes in size!");
ArgumentOutOfRangeException.ThrowIfLessThan(data.Length, MemeKey.SignatureLength);
var key = new MemeKey(keyIndex);
if (!key.CanResign)
throw new ArgumentException("Cannot sign with the specified key!");

View File

@@ -620,8 +620,7 @@ public byte[] GetHallOfFameData()
public void SetHallOfFameData(ReadOnlySpan<byte> value)
{
if (value.Length != SIZE_SECTOR_USED * 2)
throw new ArgumentException("Invalid size", nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, SIZE_SECTOR_USED * 2);
// HoF Data is split across two sav sectors
Span<byte> savedata = Data;
value[..SIZE_SECTOR_USED].CopyTo(savedata[0x1C000..]);

View File

@@ -158,8 +158,7 @@ private byte[] GetInnerData()
private static byte[] EncryptColosseum(ReadOnlySpan<byte> input, Span<byte> digest)
{
if (input.Length != SLOT_SIZE)
throw new ArgumentException("Incorrect slot size", nameof(input));
ArgumentOutOfRangeException.ThrowIfNotEqual(input.Length, SLOT_SIZE);
byte[] output = input.ToArray();
@@ -182,8 +181,7 @@ private static byte[] EncryptColosseum(ReadOnlySpan<byte> input, Span<byte> dige
private static byte[] DecryptColosseum(ReadOnlySpan<byte> input, Span<byte> digest)
{
if (input.Length != SLOT_SIZE)
throw new ArgumentException("Incorrect slot size", nameof(input));
ArgumentOutOfRangeException.ThrowIfNotEqual(input.Length, SLOT_SIZE);
byte[] output = input.ToArray();

View File

@@ -228,8 +228,7 @@ public override string ChecksumInfo
private static byte[] SetChecksums(byte[] input, int subOffset0)
{
if (input.Length != SLOT_SIZE)
throw new ArgumentException("Input should be a slot, not the entire save binary.");
ArgumentOutOfRangeException.ThrowIfNotEqual(input.Length, SLOT_SIZE);
byte[] data = (byte[])input.Clone();
const int start = 0xA8; // 0x88 + 0x20

View File

@@ -452,8 +452,7 @@ public IList<PKM> BoxData
}
set
{
if (value.Count != BoxCount * BoxSlotCount)
throw new ArgumentException($"Expected {BoxCount * BoxSlotCount}, got {value.Count}");
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, BoxCount * BoxSlotCount);
for (int b = 0; b < BoxCount; b++)
SetBoxData(value, b, b * BoxSlotCount);

View File

@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
@@ -8,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public sealed class Bank7 : BulkStorage
{
public Bank7(byte[] data, Type t, int start, int slotsPerBox = 30) : base(data, t, start, slotsPerBox) => Version = GameVersion.USUM;
public Bank7(byte[] data, Type t, [ConstantExpected] int start, int slotsPerBox = 30) : base(data, t, start, slotsPerBox) => Version = GameVersion.USUM;
public override PersonalTable7 Personal => PersonalTable.USUM;
public override ReadOnlySpan<ushort> HeldItems => Legal.HeldItems_SM;
@@ -24,8 +25,7 @@ public sealed class Bank7 : BulkStorage
public string GetGroupName(int group)
{
if ((uint)group > 10)
throw new ArgumentOutOfRangeException(nameof(group), $"{nameof(group)} must be 0-10.");
ArgumentOutOfRangeException.ThrowIfGreaterThan<uint>((uint)group, 10);
int offset = 0x8 + (GroupNameSpacing * group) + 2; // skip over " "
return GetString(Data.AsSpan(offset, GroupNameSize / 2));
}

View File

@@ -92,8 +92,7 @@ public SAV4Ranch(byte[] data) : base(data, typeof(RK4), 0)
public RanchToy GetRanchToy(int index)
{
if ((uint)index >= MaxToyCount)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)MaxToyCount);
int toyOffset = ToyBaseOffset + (RanchToy.SIZE * index);
var data = Data.AsSpan(toyOffset, RanchToy.SIZE).ToArray();
@@ -102,8 +101,7 @@ public RanchToy GetRanchToy(int index)
public void SetRanchToy(RanchToy toy, int index)
{
if ((uint)index >= MaxToyCount)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)MaxToyCount);
if (((int)toy.ToyType) > MaxToyID) // Ranch will throw "Corrupt Save" error if ToyId is > expected.
toy = BlankToy;
@@ -113,8 +111,7 @@ public void SetRanchToy(RanchToy toy, int index)
public RanchMii GetRanchMii(int index)
{
if ((uint)index >= MiiCount)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)MiiCount);
int offset = MiiDataOffset + (RanchMii.SIZE * index);
var data = Data.AsSpan(offset, RanchMii.SIZE).ToArray();
@@ -123,8 +120,7 @@ public RanchMii GetRanchMii(int index)
public void SetRanchMii(RanchMii trainer, int index)
{
if ((uint)index >= MiiCount)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)MiiCount);
int offset = MiiDataOffset + (RanchMii.SIZE * index);
SetData(Data.AsSpan(offset), trainer.Data);
@@ -132,8 +128,7 @@ public void SetRanchMii(RanchMii trainer, int index)
public RanchTrainerMii GetRanchTrainerMii(int index)
{
if ((uint)index >= TrainerMiiCount)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)TrainerMiiCount);
int offset = TrainerMiiDataOffset + (RanchTrainerMii.SIZE * index);
var data = Data.AsSpan(offset, RanchTrainerMii.SIZE).ToArray();
@@ -142,8 +137,7 @@ public RanchTrainerMii GetRanchTrainerMii(int index)
public void SetRanchTrainerMii(RanchTrainerMii mii, int index)
{
if ((uint)index >= TrainerMiiCount)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)TrainerMiiCount);
int offset = TrainerMiiDataOffset + (RanchTrainerMii.SIZE * index);
SetData(Data.AsSpan(offset), mii.Data);

View File

@@ -42,8 +42,7 @@ public IReadOnlyList<PK3[]> PlayerTeams
public PK3[] GetTeam(int teamIndex)
{
if ((uint)teamIndex > 2)
throw new ArgumentOutOfRangeException(nameof(teamIndex));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)teamIndex, 2);
var ofs = 6 * PokeCrypto.SIZE_3PARTY * teamIndex;
var team = new PK3[6];

View File

@@ -53,6 +53,7 @@ public G1OverworldSpawner(SAV1 sav)
}
}
#pragma warning disable IDE0052 // Remove unread private members
public const string FlagPropertyPrefix = "Flag"; // reflection
private FlagPairG1 FlagMewtwo { get; }
private FlagPairG1 FlagArticuno { get; }
@@ -75,6 +76,7 @@ public G1OverworldSpawner(SAV1 sav)
private FlagPairG1? FlagBulbasaur { get; }
private FlagPairG1? FlagSquirtle { get; }
private FlagPairG1? FlagCharmander { get; }
#pragma warning restore IDE0052 // Remove unread private members
public void Save()
{

View File

@@ -9,11 +9,7 @@ public class MysteryEvent3 : Gen3MysteryData
{
public const int SIZE = sizeof(uint) + 1000; // total 0x3EC
public MysteryEvent3(byte[] data) : base(data)
{
if (data.Length != SIZE)
throw new ArgumentException("Invalid size.", nameof(data));
}
public MysteryEvent3(byte[] data) : base(data) => ArgumentOutOfRangeException.ThrowIfNotEqual(data.Length, SIZE);
public byte Magic { get => Data[4]; set => Data[4] = value; }
public byte MapGroup { get => Data[5]; set => Data[5] = value; }

View File

@@ -7,11 +7,7 @@ namespace PKHeX.Core;
/// </summary>
public sealed class MysteryEvent3RS : MysteryEvent3
{
public MysteryEvent3RS(byte[] data) : base(data)
{
if (data.Length != SIZE)
throw new ArgumentException("Invalid size.", nameof(data));
}
public MysteryEvent3RS(byte[] data) : base(data) => ArgumentOutOfRangeException.ThrowIfNotEqual(data.Length, SIZE);
protected override ushort ComputeChecksum() => Checksums.CheckSum16(Data.AsSpan(4));
}

View File

@@ -15,10 +15,12 @@ public sealed class WonderCard3 : Gen3MysteryData
/// </summary>
public const int SIZE_JAP = sizeof(uint) + 164;
public WonderCard3(byte[] data) : base(data)
public WonderCard3(byte[] data) : base(data) => AssertLength(data.Length);
private static void AssertLength(int length)
{
if (data.Length is not SIZE and not SIZE_JAP)
throw new ArgumentException("Invalid size.", nameof(data));
if (length is not (SIZE or SIZE_JAP))
throw new ArgumentOutOfRangeException(nameof(length), length, "Invalid size.");
}
public bool Japanese => Data.Length is SIZE_JAP;

View File

@@ -1,4 +1,4 @@
using System;
using System;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
@@ -10,11 +10,7 @@ public sealed class WonderCard3Extra : Gen3MysteryData
/// </summary>
public const int SIZE = sizeof(uint) + 36;
public WonderCard3Extra(byte[] data) : base(data)
{
if (data.Length != SIZE)
throw new ArgumentException("Invalid size.", nameof(data));
}
public WonderCard3Extra(byte[] data) : base(data) => ArgumentOutOfRangeException.ThrowIfNotEqual(data.Length, SIZE);
public ushort Wins { get => ReadUInt16LittleEndian(Data.AsSpan(0x4)); set => WriteUInt16LittleEndian(Data.AsSpan(0x4), value); }
public ushort Losses { get => ReadUInt16LittleEndian(Data.AsSpan(0x6)); set => WriteUInt16LittleEndian(Data.AsSpan(0x6), value); }

View File

@@ -15,10 +15,12 @@ public sealed class WonderNews3 : Gen3MysteryData
/// </summary>
public const int SIZE_JAP = sizeof(uint) + 224;
public WonderNews3(byte[] data) : base(data)
public WonderNews3(byte[] data) : base(data) => AssertLength(data.Length);
private static void AssertLength(int length)
{
if (data.Length is not SIZE and not SIZE_JAP)
throw new ArgumentException("Invalid size.", nameof(data));
if (length is not (SIZE or SIZE_JAP))
throw new ArgumentOutOfRangeException(nameof(length), length, "Invalid size.");
}
public bool Japanese => Data.Length is SIZE_JAP;

View File

@@ -21,7 +21,7 @@ private int GetRecordOffset(int record)
GameVersion.RS or GameVersion.R or GameVersion.S => 0x1540,
GameVersion.E => 0x159C,
GameVersion.FRLG or GameVersion.FR or GameVersion.LG => 0x1200,
_ => throw new ArgumentException(nameof(ver)),
_ => throw new ArgumentOutOfRangeException(nameof(ver), ver, null),
};
private static Type GetEnumType(GameVersion ver) => ver switch
@@ -29,7 +29,7 @@ private int GetRecordOffset(int record)
GameVersion.RS or GameVersion.R or GameVersion.S => typeof(RecID3RuSa),
GameVersion.FRLG or GameVersion.FR or GameVersion.LG => typeof(RecID3FRLG),
GameVersion.E => typeof(RecID3Emerald),
_ => throw new ArgumentException(nameof(ver)),
_ => throw new ArgumentOutOfRangeException(nameof(ver), ver, null),
};
public static int[] GetEnumValues(GameVersion ver) => (int[])Enum.GetValues(GetEnumType(ver));

View File

@@ -17,9 +17,7 @@ public sealed class RecordMixing3Gift
public RecordMixing3Gift(byte[] data)
{
if (data.Length != SIZE)
throw new ArgumentException("Invalid size.", nameof(data));
ArgumentOutOfRangeException.ThrowIfNotEqual(data.Length, SIZE);
Data = data;
}

View File

@@ -26,8 +26,7 @@ public sealed class Dendou4
private Dendou4Record GetRecord(int index)
{
if ((uint)index >= MaxRecords)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, MaxRecords);
var slice = Data.Slice(index * Dendou4Record.SIZE, Dendou4Record.SIZE);
return new Dendou4Record(slice);
}
@@ -80,8 +79,7 @@ private Dendou4Record GetRecord(int index)
private Dendou4Entity GetEntity(int index)
{
if ((uint)index >= Count)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, Count);
var slice = Data.Slice(index * Dendou4Entity.SIZE, Dendou4Entity.SIZE);
return new Dendou4Entity(slice);
}

View File

@@ -40,10 +40,8 @@ public void SetCount(int battleType, ushort species, ushort value)
private static int GetRecordOffset(int battleType, ushort species)
{
if (species > Legal.MaxSpeciesID_4)
throw new ArgumentOutOfRangeException(nameof(species));
if ((uint)battleType > 2)
throw new ArgumentOutOfRangeException(nameof(battleType));
ArgumentOutOfRangeException.ThrowIfGreaterThan(species, Legal.MaxSpeciesID_4);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)battleType, 3);
return sizeof(uint) + (battleType * SIZE_ARRAY) + (species * sizeof(ushort));
}

View File

@@ -157,8 +157,8 @@ private static void WriteColorPalette(Span<byte> data, ReadOnlySpan<int> colors)
public static CGearBackground GetBackground(ReadOnlySpan<byte> data)
{
const int bpp = 4;
if (Width * Height * bpp != data.Length)
throw new ArgumentException("Invalid image data size.");
const int expectLength = Width * Height * bpp;
ArgumentOutOfRangeException.ThrowIfNotEqual(data.Length, expectLength);
var colors = GetColorData(data);
var palette = colors.Distinct().ToArray();
@@ -307,8 +307,7 @@ public sealed class Tile
internal Tile(ReadOnlySpan<byte> data) : this()
{
if (data.Length != SIZE_TILE)
throw new ArgumentException(null, nameof(data));
ArgumentOutOfRangeException.ThrowIfNotEqual(data.Length, SIZE_TILE);
// Unpack the nibbles into the color choice array.
for (int i = 0; i < data.Length; i++)

View File

@@ -23,8 +23,7 @@ public ushort[] SelectItems
}
set
{
if (value.Length != BoundItemCount)
throw new ArgumentException(nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, BoundItemCount);
var span = Data.AsSpan(Offset + 10);
for (int i = 0; i < value.Length; i++)
WriteUInt16LittleEndian(span[(2 * i)..], value[i]);
@@ -44,8 +43,7 @@ public ushort[] RecentItems
}
set
{
if (value.Length != RecentItemCount)
throw new ArgumentException(nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, RecentItemCount);
var span = Data.AsSpan(Offset + 20);
for (int i = 0; i < value.Length; i++)
WriteUInt16LittleEndian(span[(2 * i)..], value[i]);

View File

@@ -9,9 +9,11 @@ public sealed class BattleTree7 : SaveBlock<SAV7>
public BattleTree7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public BattleTree7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;
public const int BattleTypeMax = 4;
public int GetTreeStreak(int battletype, bool super, bool max)
{
ArgumentOutOfRangeException.ThrowIfGreaterThan(battletype, 3);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(battletype, BattleTypeMax);
var offset = GetStreakOffset(battletype, super, max);
return ReadUInt16LittleEndian(Data.AsSpan(Offset + offset));
@@ -19,7 +21,7 @@ public int GetTreeStreak(int battletype, bool super, bool max)
public void SetTreeStreak(int value, int battletype, bool super, bool max)
{
ArgumentOutOfRangeException.ThrowIfGreaterThan(battletype, 3);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(battletype, BattleTypeMax);
if (value > ushort.MaxValue)
value = ushort.MaxValue;
@@ -42,8 +44,7 @@ private static int GetStreakOffset(int battletype, bool super, bool max)
public BattleTreeTrainer GetTrainer(in int index)
{
if ((uint)index >= ScoutCount)
throw new ArgumentOutOfRangeException(nameof(index));
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, ScoutCount);
var id = ReadInt16LittleEndian(Data.AsSpan(Offset + 0x24 + (index * 2)));
var p1 = ReadInt16LittleEndian(Data.AsSpan(Offset + 0x88 + (index * 2)));
@@ -94,20 +95,20 @@ public BattleTreeTrainer[] ScoutedTrainers
}
[TypeConverter(typeof(ValueTypeTypeConverter))]
public sealed class BattleTreeTrainer(short id, BattleTreePokemon poke1, BattleTreePokemon poke2)
public sealed class BattleTreeTrainer(short ID, BattleTreePokemon Poke1, BattleTreePokemon Poke2)
{
public short ID { get; set; } = id;
public BattleTreePokemon Poke1 { get; set; } = poke1;
public BattleTreePokemon Poke2 { get; set; } = poke2;
public short ID { get; set; } = ID;
public BattleTreePokemon Poke1 { get; set; } = Poke1;
public BattleTreePokemon Poke2 { get; set; } = Poke2;
public override string ToString() => $"{ID}: [{Poke1}] & [{Poke2}]";
}
[TypeConverter(typeof(ValueTypeTypeConverter))]
public sealed class BattleTreePokemon(short p1, sbyte a1)
public sealed class BattleTreePokemon(short ID, sbyte AbilityIndex)
{
public short ID { get; set; } = p1;
public sbyte AbilityIndex { get; set; } = a1;
public short ID { get; set; } = ID;
public sbyte AbilityIndex { get; set; } = AbilityIndex;
public override string ToString() => $"{ID},{AbilityIndex}";
}

View File

@@ -43,7 +43,7 @@ public void Reset()
SAV7SM { Gender: 1 } => DefaultFashionOffsetSM_F,
SAV7USUM { Gender: 0 } => DefaultFashionOffsetUU_M,
SAV7USUM { Gender: 1 } => DefaultFashionOffsetUU_F,
_ => throw new ArgumentOutOfRangeException(nameof(SAV)),
_ => throw new ArgumentOutOfRangeException(nameof(sav)),
};
// Offsets that are set to '3' when the game starts for a specific gender.

View File

@@ -48,8 +48,7 @@ public string GameSyncID
get => Util.GetHexStringFromBytes(Data.AsSpan(Offset + 0x10, GameSyncIDSize / 2));
set
{
if (value.Length > 16)
throw new ArgumentException(nameof(value));
ArgumentOutOfRangeException.ThrowIfGreaterThan(value.Length, 16);
var data = Util.GetBytesFromHexString(value);
SAV.SetData(data, Offset + 0x10);

View File

@@ -118,8 +118,7 @@ private void SetPointerData(ReadOnlySpan<int> vals)
public int GetPartyOffset(int slot)
{
if ((uint)slot >= 6)
throw new ArgumentOutOfRangeException(nameof(slot) + " expected to be < 6.");
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)slot, 6);
int position = PokeListInfo[slot];
return SAV.GetBoxSlotOffset(position);
}

View File

@@ -45,8 +45,7 @@ public string GameSyncID
get => Util.GetHexStringFromBytes(Data.AsSpan(Offset + 0x10, GameSyncIDSize / 2));
set
{
if (value.Length != GameSyncIDSize)
throw new ArgumentException(nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, GameSyncIDSize);
var data = Util.GetBytesFromHexString(value);
SAV.SetData(data, Offset + 0x10);
@@ -58,8 +57,7 @@ public string NexUniqueID
get => Util.GetHexStringFromBytes(Data.AsSpan(Offset + 0x18, NexUniqueIDSize / 2));
set
{
if (value.Length != NexUniqueIDSize)
throw new ArgumentException(nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, NexUniqueIDSize);
var data = Util.GetBytesFromHexString(value);
SAV.SetData(data, Offset + 0x18);

View File

@@ -77,8 +77,7 @@ public static void SetQRData(PK7 pk7, Span<byte> span, int box = 0, int slot = 0
box = Math.Clamp(box, 0, 31);
slot = Math.Clamp(slot, 0, 29);
num_copies = Math.Min(num_copies, 1);
if (span.Length < SIZE)
throw new ArgumentException($"Span must be at least {SIZE} bytes long.", nameof(span));
ArgumentOutOfRangeException.ThrowIfLessThan(span.Length, SIZE);
WriteUInt32LittleEndian(span, 0x454B4F50); // POKE magic
span[0x4] = 0xFF; // QR Type

View File

@@ -26,8 +26,7 @@ public PK7[] ResortPKM
}
set
{
if (value.Length != ResortCount)
throw new ArgumentException(nameof(ResortCount));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, ResortCount);
for (int i = 0; i < value.Length; i++)
{

View File

@@ -48,8 +48,7 @@ private BattleTowerClassData8b[] GetRecords()
private static void SetRecords(IReadOnlyList<BattleTowerClassData8b> value)
{
if (value.Count != COUNT_CLASSDATA)
throw new ArgumentException($"Expected {COUNT_CLASSDATA} items, received {value.Count}.", nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, COUNT_CLASSDATA);
// data is already hard-referencing the original byte array. This is mostly a hack for Property Grid displays.
}
}

View File

@@ -94,8 +94,7 @@ private HoneyTree8b[] GetTrees()
private static void SetTrees(IReadOnlyList<HoneyTree8b> value)
{
if (value.Count != COUNT_HONEYTREE)
throw new ArgumentOutOfRangeException(nameof(value.Count));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, COUNT_HONEYTREE);
// data is already hard-referencing the original byte array. This is mostly a hack for Property Grid displays.
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using static System.Buffers.Binary.BinaryPrimitives;
@@ -32,8 +32,7 @@ private FieldObject8b[] GetObjects()
private static void SetObjects(IReadOnlyList<FieldObject8b> value)
{
if (value.Count != COUNT_OBJECTS)
throw new ArgumentOutOfRangeException(nameof(value.Count));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, COUNT_OBJECTS);
// data is already hard-referencing the original byte array. This is mostly a hack for Property Grid displays.
}
}

View File

@@ -94,8 +94,7 @@ private RecvData8b[] GetReceived()
}
private void SetReceived(IReadOnlyList<RecvData8b> value)
{
if (value.Count != RecvDataMax)
throw new ArgumentOutOfRangeException(nameof(value.Count));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, RecvDataMax);
for (int i = 0; i < value.Count; i++)
SetReceived(i, value[i]);
}
@@ -117,8 +116,7 @@ private bool[] GetFlags()
}
private void SetFlags(IReadOnlyList<bool> value)
{
if (value.Count != FlagSize)
throw new ArgumentOutOfRangeException(nameof(value.Count));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, FlagSize);
for (int i = 0; i < value.Count; i++)
SetFlag(i, value[i]);
}
@@ -141,8 +139,7 @@ private OneDay8b[] GetOneDay()
private void SetOneDay(IReadOnlyList<OneDay8b> value)
{
if (value.Count != OneDayMax)
throw new ArgumentOutOfRangeException(nameof(value.Count));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, OneDayMax);
for (int i = 0; i < value.Count; i++)
SetOneDay(i, value[i]);
}

View File

@@ -43,8 +43,7 @@ public Poffin8b[] GetPoffins()
public void SetPoffins(IReadOnlyCollection<Poffin8b> value)
{
if (value.Count != COUNT_POFFIN)
throw new ArgumentException($"Expected {COUNT_POFFIN} items, received {value.Count}.", nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, COUNT_POFFIN);
var ordered = value.OrderBy(z => z.IsNull).ThenBy(z => z.IsNew);
int ctr = 0;
foreach (var p in ordered)

View File

@@ -38,8 +38,7 @@ private SealCapsule8b[] GetCapsules()
private static void SetCapsules(IReadOnlyList<SealCapsule8b> value)
{
if (value.Count != COUNT_CAPSULE)
throw new ArgumentException($"Expected {COUNT_CAPSULE} items, received {value.Count}.", nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, COUNT_CAPSULE);
// data is already hard-referencing the original byte array. This is mostly a hack for Property Grid displays.
}
}
@@ -72,8 +71,7 @@ private AffixSealData8b[] GetSeals()
private static void SetSeals(IReadOnlyList<AffixSealData8b> value)
{
if (value.Count != COUNT_SEAL)
throw new ArgumentException($"Expected {COUNT_SEAL} items, received {value.Count}.", nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, COUNT_SEAL);
// data is already hard-referencing the original byte array. This is mostly a hack for Property Grid displays.
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
namespace PKHeX.Core;
@@ -24,8 +24,7 @@ public IReadOnlyList<SealSticker8b> ReadItems()
public void WriteItems(IReadOnlyList<SealSticker8b> items)
{
if (items.Count != SealSaveSize)
throw new ArgumentOutOfRangeException(nameof(items.Count));
ArgumentOutOfRangeException.ThrowIfNotEqual(items.Count, SealSaveSize);
foreach (var item in items)
item.Write(Data, Offset);
SAV.State.Edited = true;

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.ComponentModel;
using static System.Buffers.Binary.BinaryPrimitives;
@@ -97,8 +97,7 @@ public int GetSlotOffset(int slot)
public void SetTrainers(ReadOnlySpan<byte> data)
{
if (Data.Length > COUNT_TRAINERS)
throw new ArgumentOutOfRangeException(nameof(data.Length));
ArgumentOutOfRangeException.ThrowIfGreaterThan(data.Length, COUNT_TRAINERS);
data.CopyTo(GetTrainers());
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
namespace PKHeX.Core;
@@ -21,8 +21,7 @@ public IReadOnlyList<UndergroundItem8b> ReadItems()
public void WriteItems(IReadOnlyList<UndergroundItem8b> items)
{
if (items.Count != ItemSaveSize)
throw new ArgumentOutOfRangeException(nameof(items.Count));
ArgumentOutOfRangeException.ThrowIfNotEqual(items.Count, ItemSaveSize);
foreach (var item in items)
item.Write(Data, Offset);
SAV.State.Edited = true;

View File

@@ -19,8 +19,7 @@ public sealed class PokedexSaveData
public PokedexSaveData(byte[] data)
{
if (data.Length != POKEDEX_SAVE_DATA_SIZE)
throw new ArgumentException($"Unexpected {nameof(PokedexSaveData)} block size!");
ArgumentOutOfRangeException.ThrowIfNotEqual(data.Length, POKEDEX_SAVE_DATA_SIZE);
GlobalData = new PokedexSaveGlobalData(data, 0);

View File

@@ -27,8 +27,7 @@ public PK9[] Entities
get => GetAllEntities();
set
{
if (value.Length != CountAll)
throw new ArgumentException(nameof(value));
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, CountAll);
for (int i = 0; i < value.Length; i++)
GetSpawn(i).Entity = value[i];
}

View File

@@ -27,8 +27,7 @@ public override void GetPouch(ReadOnlySpan<byte> data)
public override void SetPouch(Span<byte> data)
{
if (Items.Length != PouchDataSize)
throw new ArgumentException("Item array length does not match original pouch size.");
ArgumentOutOfRangeException.ThrowIfNotEqual(Items.Length, PouchDataSize);
var span = data[Offset..];
for (int i = 0; i < Items.Length; i++)

View File

@@ -27,8 +27,7 @@ public override void GetPouch(ReadOnlySpan<byte> data)
public override void SetPouch(Span<byte> data)
{
if (Items.Length != PouchDataSize)
throw new ArgumentException("Item array length does not match original pouch size.");
ArgumentOutOfRangeException.ThrowIfNotEqual(Items.Length, PouchDataSize);
var span = data[Offset..];
for (int i = 0; i < Items.Length; i++)

View File

@@ -33,8 +33,7 @@ public override void GetPouch(ReadOnlySpan<byte> data)
public override void SetPouch(Span<byte> data)
{
if (Items.Length != PouchDataSize)
throw new ArgumentException("Item array length does not match original pouch size.");
ArgumentOutOfRangeException.ThrowIfNotEqual(Items.Length, PouchDataSize);
var span = data[Offset..];
for (int i = 0; i < Items.Length; i++)

View File

@@ -27,8 +27,7 @@ public override void GetPouch(ReadOnlySpan<byte> data)
public override void SetPouch(Span<byte> data)
{
if (Items.Length != PouchDataSize)
throw new ArgumentException("Item array length does not match original pouch size.");
ArgumentOutOfRangeException.ThrowIfNotEqual(Items.Length, PouchDataSize);
var span = data[Offset..];
var items = (InventoryItem7[])Items;

View File

@@ -31,8 +31,7 @@ public override void GetPouch(ReadOnlySpan<byte> data)
public override void SetPouch(Span<byte> data)
{
if (Items.Length != PouchDataSize)
throw new ArgumentException("Item array length does not match original pouch size.");
ArgumentOutOfRangeException.ThrowIfNotEqual(Items.Length, PouchDataSize);
var span = data[Offset..];
var items = (InventoryItem7b[])Items;

View File

@@ -31,8 +31,7 @@ public override void GetPouch(ReadOnlySpan<byte> data)
public override void SetPouch(Span<byte> data)
{
if (Items.Length != PouchDataSize)
throw new ArgumentException("Item array length does not match original pouch size.");
ArgumentOutOfRangeException.ThrowIfNotEqual(Items.Length, PouchDataSize);
var span = data[Offset..];
var items = (InventoryItem8[])Items;

View File

@@ -64,8 +64,7 @@ public override void GetPouch(ReadOnlySpan<byte> data)
public override void SetPouch(Span<byte> data)
{
if (Items.Length != PouchDataSize)
throw new ArgumentException("Item array length does not match original pouch size.");
ArgumentOutOfRangeException.ThrowIfNotEqual(Items.Length, PouchDataSize);
ClearCount0();

View File

@@ -62,7 +62,8 @@ private void SetSizeData(PB7 pk)
if (!TryGetSizeEntryIndex(species, form, out int index))
return;
if (Math.Round(pk.HeightAbsolute) < pk.PersonalInfo.Height) // possible minimum height
var pi = PersonalTable.GG[species, form];
if (pk.HeightAbsolute < pi.Height) // possible minimum height
{
int ofs = GetDexSizeOffset(DexSizeType.MinHeight, index);
var entry = SAV.Data.AsSpan(ofs, EntrySize);
@@ -70,7 +71,7 @@ private void SetSizeData(PB7 pk)
if (pk.HeightScalar < minHeight || IsUnset(entry))
SetSizeData(pk, DexSizeType.MinHeight);
}
else if (Math.Round(pk.HeightAbsolute) > pk.PersonalInfo.Height) // possible maximum height
else if (pk.HeightAbsolute > pi.Height) // possible maximum height
{
int ofs = GetDexSizeOffset(DexSizeType.MaxHeight, index);
var entry = SAV.Data.AsSpan(ofs, EntrySize);
@@ -79,8 +80,7 @@ private void SetSizeData(PB7 pk)
SetSizeData(pk, DexSizeType.MaxHeight);
}
var pi = PersonalTable.GG[species, form];
if (Math.Round(pk.WeightAbsolute) < pk.PersonalInfo.Weight) // possible minimum weight
if (pk.WeightAbsolute < pi.Weight) // possible minimum weight
{
int ofs = GetDexSizeOffset(DexSizeType.MinWeight, index);
var entry = SAV.Data.AsSpan(ofs, EntrySize);
@@ -90,7 +90,7 @@ private void SetSizeData(PB7 pk)
if (pk.WeightAbsolute < calcWeight || IsUnset(entry))
SetSizeData(pk, DexSizeType.MinWeight);
}
else if (Math.Round(pk.WeightAbsolute) > pk.PersonalInfo.Weight) // possible maximum weight
else if (pk.WeightAbsolute > pi.Weight) // possible maximum weight
{
int ofs = GetDexSizeOffset(DexSizeType.MaxWeight, index);
var entry = SAV.Data.AsSpan(ofs, EntrySize);

View File

@@ -38,13 +38,19 @@ private static Bitmap ExtendImage(Font font, Image qr, int width, int height, Im
g.FillRectangle(Brushes.White, 0, 0, newpic.Width, newpic.Height);
g.DrawImage(pic, 0, 0);
g.DrawString(GetLine(lines, 0), font, Brushes.Black, new PointF(18, qr.Height - 5));
g.DrawString(GetLine(lines, 1), font, Brushes.Black, new PointF(18, qr.Height + 8));
g.DrawString(GetLine(lines, 2).Replace(Environment.NewLine, "/").Replace("//", " ").Replace(":/", ": "), font,
Brushes.Black, new PointF(18, qr.Height + 20));
g.DrawString(GetLine(lines, 3) + extraText, font, Brushes.Black, new PointF(18, qr.Height + 32));
var black = Brushes.Black;
const int indent = 18;
g.DrawString(GetLine(lines, 0), font, black, new PointF(indent, qr.Height - 5));
g.DrawString(GetLine(lines, 1), font, black, new PointF(indent, qr.Height + 8));
g.DrawString(GetLine2(lines) , font, black, new PointF(indent, qr.Height + 20));
g.DrawString(GetLine(lines, 3) + extraText, font, black, new PointF(indent, qr.Height + 32));
return newpic;
}
private static string GetLine2(ReadOnlySpan<string> lines) => GetLine(lines, 2)
.Replace(Environment.NewLine, "/")
.Replace("//", " ")
.Replace(":/", ": ");
private static string GetLine(ReadOnlySpan<string> lines, int line) => lines.Length <= line ? string.Empty : lines[line];
}

View File

@@ -190,7 +190,7 @@ private static Bitmap ApplyColor(Bitmap img, SpriteBackgroundType type, Color co
return img;
}
private static Bitmap ApplyExperience(PKM pk, Image img, IEncounterTemplate? enc = null)
private static Bitmap ApplyExperience(PKM pk, Bitmap img, IEncounterTemplate? enc = null)
{
const int bpp = 4;
int start = bpp * SpriteWidth * (SpriteHeight - 1);
@@ -202,7 +202,7 @@ private static Bitmap ApplyExperience(PKM pk, Image img, IEncounterTemplate? enc
if (pct is not 0)
return ImageUtil.WritePixels(img, Color.DodgerBlue, start, start + (int)(SpriteWidth * pct * bpp));
var encLevel = enc is { EggEncounter: true } x ? x.LevelMin : pk.Met_Level;
var encLevel = enc is { EggEncounter: true } ? enc.LevelMin : pk.Met_Level;
var color = level != encLevel && pk.HasOriginalMetLocation ? Color.DarkOrange : Color.Yellow;
return ImageUtil.WritePixels(img, color, start, start + (SpriteWidth * bpp));
}

View File

@@ -1246,9 +1246,11 @@ private void ReloadMetLocations(GameVersion version, EntityContext context)
CB_EggLocation.DataSource = new BindingSource(eggList, null);
CB_EggLocation.DropDownWidth = GetWidth(eggList, CB_EggLocation.Font);
static int GetWidth(IReadOnlyList<ComboItem> items, Font f) => items.Count == 0 ? throw new ArgumentException("Expected items in array.", nameof(items)) :
items.Max(z => TextRenderer.MeasureText(z.Text, f).Width) +
SystemInformation.VerticalScrollBarWidth;
static int GetWidth(IReadOnlyCollection<ComboItem> items, Font f)
{
ArgumentOutOfRangeException.ThrowIfZero(items.Count);
return items.Max(z => TextRenderer.MeasureText(z.Text, f).Width) + SystemInformation.VerticalScrollBarWidth;
}
if (FieldsLoaded)
{

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Drawing;
using System.Windows.Forms;
using PKHeX.Core;
@@ -53,7 +53,7 @@ private void ResizeWindow()
splitContainer1.Width = img.Width;
}
private Image ReloadQRData(PK7 pk7)
private Bitmap ReloadQRData(PK7 pk7)
{
var box = (int)NUD_Box.Value - 1;
var slot = (int)NUD_Slot.Value - 1;

View File

@@ -30,12 +30,9 @@ public static Bitmap GetBitmap(CGearBackground bg)
/// <exception cref="ArgumentException"></exception>
public static CGearBackground GetCGearBackground(Bitmap img)
{
if (img.Width != Width)
throw new ArgumentException($"Invalid image width. Expected {Width} pixels wide.");
if (img.Height != Height)
throw new ArgumentException($"Invalid image height. Expected {Height} pixels high.");
if (img.PixelFormat is not PixelFormat.Format32bppArgb)
throw new ArgumentException($"Invalid image format. Expected {PixelFormat.Format32bppArgb}");
ArgumentOutOfRangeException.ThrowIfNotEqual(img.Width, Width);
ArgumentOutOfRangeException.ThrowIfNotEqual(img.Height, Height);
ArgumentOutOfRangeException.ThrowIfNotEqual((uint)img.PixelFormat, (uint)PixelFormat.Format32bppArgb);
// get raw bytes of image
byte[] data = ImageUtil.GetPixelData(img);

View File

@@ -95,7 +95,7 @@ public SAV_PokedexLA(SAV8LA sav)
CB_Species.DataSource = new BindingSource(species, null);
CB_DisplayForm.InitializeBinding();
DisplayedForms = new List<ComboItem> { new(GameInfo.Strings.types[0], 0) };
DisplayedForms = [new(GameInfo.Strings.types[0], 0)];
CB_DisplayForm.DataSource = new BindingSource(DisplayedForms, null);
for (var d = 1; d < DexToSpecies.Length; d++)

View File

@@ -26,13 +26,7 @@ public SAV_Wondercard(SaveFile sav, DataMysteryGift? g = null)
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
SAV = (Origin = sav).Clone();
mga = SAV.GiftAlbum;
pba = SAV.Generation switch
{
4 => PopulateViewGiftsG4(),
5 or 6 or 7 => PopulateViewGiftsG567(),
_ => throw new ArgumentOutOfRangeException(nameof(SAV.Generation), "Game not supported."),
};
pba = GetGiftPictureBoxes(SAV.Generation);
foreach (var pb in pba)
{
pb.AllowDrop = true;
@@ -70,11 +64,18 @@ public SAV_Wondercard(SaveFile sav, DataMysteryGift? g = null)
ViewGiftData(g);
}
private List<PictureBox> GetGiftPictureBoxes(int generation) => generation switch
{
4 => PopulateViewGiftsG4(),
5 or 6 or 7 => PopulateViewGiftsG567(),
_ => throw new ArgumentOutOfRangeException(nameof(generation), generation, "Game not supported."),
};
private readonly MysteryGiftAlbum mga;
private DataMysteryGift? mg;
private readonly List<PictureBox> pba; // don't mutate this list
// Repopulation Functions
// Re-population Functions
private void SetBackground(int index, Image bg)
{
for (int i = 0; i < mga.Gifts.Length; i++)