diff --git a/PKHeX.Core/Editing/Applicators/MoveApplicator.cs b/PKHeX.Core/Editing/Applicators/MoveApplicator.cs
index f9769af4d..d432a9530 100644
--- a/PKHeX.Core/Editing/Applicators/MoveApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/MoveApplicator.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
namespace PKHeX.Core
{
@@ -39,8 +38,8 @@ public static void SetMaximumPPUps(this PKM pk, int[] moves)
/// Option to maximize PP Ups
public static void SetMoves(this PKM pk, int[] moves, bool maxPP = false)
{
- if (moves.Any(z => z > pk.MaxMoveID))
- moves = moves.Where(z => z <= pk.MaxMoveID).ToArray();
+ if (Array.FindIndex(moves, z => z > pk.MaxMoveID) != -1)
+ moves = Array.FindAll(moves, z => z <= pk.MaxMoveID);
if (moves.Length != 4)
Array.Resize(ref moves, 4);
diff --git a/PKHeX.Core/Game/GameUtil.cs b/PKHeX.Core/Game/GameUtil.cs
index 561ae03e0..55e3ed092 100644
--- a/PKHeX.Core/Game/GameUtil.cs
+++ b/PKHeX.Core/Game/GameUtil.cs
@@ -11,10 +11,18 @@ namespace PKHeX.Core
public static class GameUtil
{
///
- /// List of possible values a can have.
+ /// All possible values a can have.
///
/// Ordered roughly by most recent games first.
- public static readonly IReadOnlyList GameVersions = ((GameVersion[])Enum.GetValues(typeof(GameVersion))).Where(IsValidSavedVersion).Reverse().ToArray();
+ public static readonly GameVersion[] GameVersions = GetValidGameVersions();
+
+ private static GameVersion[] GetValidGameVersions()
+ {
+ var all = (GameVersion[])Enum.GetValues(typeof(GameVersion));
+ var valid = Array.FindAll(all, IsValidSavedVersion);
+ Array.Reverse(valid);
+ return valid;
+ }
///
/// Indicates if the value is a value used by the games or is an aggregate indicator.
@@ -203,7 +211,7 @@ public static GameVersion[] GetVersionsInGeneration(int generation, int pkVersio
{
if (Gen7b.Contains(pkVersion))
return new[] {GO, GP, GE};
- return GameVersions.Where(z => z.GetGeneration() == generation).ToArray();
+ return Array.FindAll(GameVersions, z => z.GetGeneration() == generation);
}
///
diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs
index e97ce4289..9642c2ec4 100644
--- a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs
+++ b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs
@@ -85,7 +85,7 @@ private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, IReadOnlyLi
var Egg = MoveEgg.GetEggMoves(pkm.PersonalInfo, e.Species, e.Form, e.Version, e.Generation);
if (info.Generation < 3 && pkm.Format >= 7 && pkm.VC1)
- Egg = Egg.Where(m => m <= Legal.MaxMoveID_1).ToArray();
+ Egg = Array.FindAll(Egg, m => m <= Legal.MaxMoveID_1);
bool volt = (info.Generation > 3 || e.Version == GameVersion.E) && Legal.LightBall.Contains(pkm.Species);
var specialMoves = volt && notEvent ? new[] { (int)Move.VoltTackle } : Array.Empty(); // Volt Tackle for bred Pichu line
@@ -216,19 +216,21 @@ private static CheckMoveResult[] ParseMoves(PKM pkm, MoveParseSource source, Leg
var required = pkm is not PK1 pk1 ? 1 : GBRestrictions.GetRequiredMoveCount(pk1, source.CurrentMoves, info, source.Base);
// Special considerations!
- int reset = 0;
+ const int NoMinGeneration = 0;
+ int minGeneration = NoMinGeneration;
if (pkm is IBattleVersion {BattleVersion: not 0} v)
{
- reset = ((GameVersion) v.BattleVersion).GetGeneration();
+ minGeneration = ((GameVersion) v.BattleVersion).GetGeneration();
source.ResetSources();
}
// Check empty moves and relearn moves before generation specific moves
for (int m = 0; m < 4; m++)
{
- if (source.CurrentMoves[m] == 0)
+ var move = source.CurrentMoves[m];
+ if (move == 0)
res[m] = new CheckMoveResult(None, pkm.Format, m < required ? Fishy : Valid, LMoveSourceEmpty, CurrentMove);
- else if (reset == 0 && info.EncounterMoves.Relearn.Contains(source.CurrentMoves[m]))
+ else if (minGeneration == NoMinGeneration && info.EncounterMoves.Relearn.Contains(move))
res[m] = new CheckMoveResult(Relearn, info.Generation, Valid, LMoveSourceRelearn, CurrentMove);
}
@@ -240,16 +242,19 @@ private static CheckMoveResult[] ParseMoves(PKM pkm, MoveParseSource source, Leg
// Check moves going backwards, marking the move valid in the most current generation when it can be learned
int[] generations = GenerationTraversal.GetVisitedGenerationOrder(pkm, info.EncounterOriginal.Generation);
if (pkm.Format <= 2)
- generations = generations.Where(z => z < info.EncounterMoves.LevelUpMoves.Length).ToArray();
- if (reset != 0)
- generations = generations.Where(z => z >= reset).ToArray();
+ generations = Array.FindAll(generations, z => z < info.EncounterMoves.LevelUpMoves.Length);
+ if (minGeneration != NoMinGeneration)
+ generations = Array.FindAll(generations, z => z >= minGeneration);
- int lastgen = generations.Length == 0 ? 0 : generations[^1];
- foreach (var gen in generations)
+ if (generations.Length != 0)
{
- ParseMovesByGeneration(pkm, res, gen, info, moveInfo, lastgen);
- if (AllParsed())
- return res;
+ int lastgen = generations[^1];
+ foreach (var gen in generations)
+ {
+ ParseMovesByGeneration(pkm, res, gen, info, moveInfo, lastgen);
+ if (AllParsed())
+ return res;
+ }
}
if (pkm.Species == (int)Species.Shedinja && info.Generation <= 4)
@@ -459,7 +464,7 @@ private static void ParseEggMovesRemaining(PKM pkm, CheckMoveResult[] res, Learn
{
// A pokemon could have normal egg moves and regular egg moves
// Only if all regular egg moves are event egg moves or all event egg moves are regular egg moves
- var RegularEggMovesLearned = learnInfo.EggMovesLearned.Union(learnInfo.LevelUpEggMoves).ToList();
+ var RegularEggMovesLearned = learnInfo.EggMovesLearned.FindAll(learnInfo.LevelUpEggMoves.Contains);
if (RegularEggMovesLearned.Count != 0 && learnInfo.EventEggMoves.Count != 0)
{
// Moves that are egg moves or event egg moves but not both
diff --git a/PKHeX.Core/Legality/MoveList.cs b/PKHeX.Core/Legality/MoveList.cs
index 1c071ff9e..9b789bf78 100644
--- a/PKHeX.Core/Legality/MoveList.cs
+++ b/PKHeX.Core/Legality/MoveList.cs
@@ -60,7 +60,7 @@ internal static int[] GetBaseEggMoves(PKM pkm, int species, int form, GameVersio
{
case GSC or GS:
// If checking back-transfer specimen (GSC->RBY), remove moves that must be deleted prior to transfer
- static int[] getRBYCompatibleMoves(int format, int[] moves) => format == 1 ? moves.Where(m => m <= MaxMoveID_1).ToArray() : moves;
+ static int[] getRBYCompatibleMoves(int format, int[] moves) => format == 1 ? Array.FindAll(moves, m => m <= MaxMoveID_1) : moves;
if (pkm.InhabitedGeneration(2))
return getRBYCompatibleMoves(pkm.Format, LevelUpGS[species].GetMoves(lvl));
break;
diff --git a/PKHeX.Core/PKM/PK4.cs b/PKHeX.Core/PKM/PK4.cs
index 297fc9b70..6e93ce3b4 100644
--- a/PKHeX.Core/PKM/PK4.cs
+++ b/PKHeX.Core/PKM/PK4.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
namespace PKHeX.Core
{
@@ -384,7 +383,7 @@ public PK5 ConvertToPK5()
pk5.Form = 0;
pk5.HeldItem = 0;
}
- else if(!Legal.HeldItems_BW.Contains((ushort)HeldItem))
+ else if (Array.IndexOf(Legal.HeldItems_BW, (ushort)HeldItem) == -1)
{
pk5.HeldItem = 0; // if valid, it's already copied
}
@@ -419,10 +418,10 @@ public PK5 ConvertToPK5()
// if has defog, remove whirlpool.
bool hasDefog = HasMove((int) Move.Defog);
var banned = hasDefog ? Legal.HM_HGSS : Legal.HM_DPPt;
- if (banned.Contains(Move1)) Move1 = 0;
- if (banned.Contains(Move2)) Move2 = 0;
- if (banned.Contains(Move3)) Move3 = 0;
- if (banned.Contains(Move4)) Move4 = 0;
+ if (Array.IndexOf(banned, Move1) != -1) Move1 = 0;
+ if (Array.IndexOf(banned, Move2) != -1) Move2 = 0;
+ if (Array.IndexOf(banned, Move3) != -1) Move3 = 0;
+ if (Array.IndexOf(banned, Move4) != -1) Move4 = 0;
pk5.FixMoves();
pk5.RefreshChecksum();
diff --git a/PKHeX.Core/PKM/Util/PKX.cs b/PKHeX.Core/PKM/Util/PKX.cs
index 7734edf82..51f8f9fe3 100644
--- a/PKHeX.Core/PKM/Util/PKX.cs
+++ b/PKHeX.Core/PKM/Util/PKX.cs
@@ -198,6 +198,8 @@ public static int GetGenderFromPID(int species, uint pid)
_ => (pid & 0xFF) < gr ? 1 : 0
};
+ internal const string ExtensionPB7 = "pb7";
+
///
/// Gets an array of valid file extensions.
///
@@ -218,7 +220,7 @@ public static string[] GetPKMExtensions(int maxGeneration = Generation)
if (maxGeneration >= 4)
result.Add("bk4"); // battle revolution
if (maxGeneration >= 7)
- result.Add("pb7"); // let's go
+ result.Add(ExtensionPB7); // let's go
return result.ToArray();
}
diff --git a/PKHeX.Core/Saves/SAV1.cs b/PKHeX.Core/Saves/SAV1.cs
index 855c7f8df..e13e6140b 100644
--- a/PKHeX.Core/Saves/SAV1.cs
+++ b/PKHeX.Core/Saves/SAV1.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
namespace PKHeX.Core
{
@@ -20,11 +19,11 @@ public sealed class SAV1 : SaveFile, ILangDeviantSave
public override PersonalTable Personal { get; }
public override IReadOnlyList HeldItems => Array.Empty();
- public override IReadOnlyList PKMExtensions => PKM.Extensions.Where(f =>
+ public override IReadOnlyList PKMExtensions => Array.FindAll(PKM.Extensions, f =>
{
int gen = f[^1] - 0x30;
return gen is 1 or 2;
- }).ToArray();
+ });
public SAV1(GameVersion version = GameVersion.RBY, bool japanese = false) : base(SaveUtil.SIZE_G1RAW)
{
diff --git a/PKHeX.Core/Saves/SAV2.cs b/PKHeX.Core/Saves/SAV2.cs
index 2dbee89e8..83655a6ab 100644
--- a/PKHeX.Core/Saves/SAV2.cs
+++ b/PKHeX.Core/Saves/SAV2.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
namespace PKHeX.Core
{
@@ -20,13 +19,13 @@ public sealed class SAV2 : SaveFile, ILangDeviantSave
public override PersonalTable Personal { get; }
public override IReadOnlyList HeldItems => Legal.HeldItems_GSC;
- public override IReadOnlyList PKMExtensions => PKM.Extensions.Where(f =>
+ public override IReadOnlyList PKMExtensions => Array.FindAll(PKM.Extensions, f =>
{
int gen = f[^1] - 0x30;
if (Korean)
return gen == 2;
return gen is 1 or 2;
- }).ToArray();
+ });
public SAV2(GameVersion version = GameVersion.C, LanguageID lang = LanguageID.English) : base(SaveUtil.SIZE_G2RAW_J)
{
@@ -670,9 +669,15 @@ public override void SetEventConsts(ushort[] value)
private ushort GetResetKey()
{
var val = (TID >> 8) + (TID & 0xFF) + ((Money >> 16) & 0xFF) + ((Money >> 8) & 0xFF) + (Money & 0xFF);
- var ot = Data.Skip(Offsets.Trainer1 + 2).TakeWhile((z, i) => i < 5 && z != 0x50);
- var tr = ot.Sum(z => z);
- return (ushort)(val + tr);
+ var ot = Data.AsSpan(Offsets.Trainer1 + 2, 5);
+ var sum = 0;
+ foreach (var b in ot)
+ {
+ if (b == StringConverter12.G1TerminatorCode)
+ break;
+ sum += b;
+ }
+ return (ushort)(val + sum);
}
///
diff --git a/PKHeX.Core/Saves/SAV3Colosseum.cs b/PKHeX.Core/Saves/SAV3Colosseum.cs
index d8a47dec2..0935020e7 100644
--- a/PKHeX.Core/Saves/SAV3Colosseum.cs
+++ b/PKHeX.Core/Saves/SAV3Colosseum.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Security.Cryptography;
namespace PKHeX.Core
@@ -256,7 +255,7 @@ public override string ChecksumInfo
newHC -= BigEndian.ToInt32(D, 0);
newHC -= BigEndian.ToInt32(D, 4);
- byte[] chk = data.Slice(data.Length - 20, 20);
+ var chk = data.AsSpan(data.Length - 20, 20);
bool header = newHC == oldHC;
bool body = chk.SequenceEqual(checksum);
diff --git a/PKHeX.Core/Saves/SAV4BR.cs b/PKHeX.Core/Saves/SAV4BR.cs
index b05b78e44..0061e6f09 100644
--- a/PKHeX.Core/Saves/SAV4BR.cs
+++ b/PKHeX.Core/Saves/SAV4BR.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
namespace PKHeX.Core
{
@@ -299,12 +298,19 @@ public static bool VerifyChecksum(byte[] input, int offset, int len, int checksu
}
}
+ // Restore original checksums
for (int i = 0; i < storedChecksums.Length; i++)
{
BigEndian.GetBytes(storedChecksums[i]).CopyTo(input, checksum_offset + (i * 4));
}
- return checksums.SequenceEqual(storedChecksums);
+ // Check if they match
+ for (int i = 0; i < storedChecksums.Length; i++)
+ {
+ if (storedChecksums[i] != checksums[i])
+ return false;
+ }
+ return true;
}
private static void SetChecksum(byte[] input, int offset, int len, int checksum_offset)
diff --git a/PKHeX.Core/Saves/SAV7.cs b/PKHeX.Core/Saves/SAV7.cs
index 07edc792e..af0cc4ce9 100644
--- a/PKHeX.Core/Saves/SAV7.cs
+++ b/PKHeX.Core/Saves/SAV7.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Linq;
namespace PKHeX.Core
{
@@ -14,11 +13,11 @@ public abstract class SAV7 : SAV_BEEF, ITrainerStatRecord, ISaveBlock7Main, IReg
protected internal override string ShortSummary => $"{OT} ({Version}) - {Played.LastSavedTime}";
public override string Extension => string.Empty;
- public override IReadOnlyList PKMExtensions => PKM.Extensions.Where(f =>
+ public override IReadOnlyList PKMExtensions => Array.FindAll(PKM.Extensions, f =>
{
int gen = f[^1] - 0x30;
return gen <= 7 && f[1] != 'b'; // ignore PB7
- }).ToArray();
+ });
protected SAV7(byte[] data, int biOffset) : base(data, biOffset)
{
diff --git a/PKHeX.Core/Saves/SAV7b.cs b/PKHeX.Core/Saves/SAV7b.cs
index 3a5ccf92b..6e834c8eb 100644
--- a/PKHeX.Core/Saves/SAV7b.cs
+++ b/PKHeX.Core/Saves/SAV7b.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
namespace PKHeX.Core
{
@@ -11,7 +10,7 @@ public sealed class SAV7b : SAV_BEEF, IGameSync
{
protected internal override string ShortSummary => $"{OT} ({Version}) - {Blocks.Played.LastSavedTime}";
public override string Extension => ".bin";
- public override IReadOnlyList PKMExtensions => PKM.Extensions.Where(f => f[1] == 'b' && f[^1] == '7').ToArray();
+ public override IReadOnlyList PKMExtensions => new[] {PKX.ExtensionPB7};
public override Type PKMType => typeof(PB7);
public override PKM BlankPKM => new PB7();
diff --git a/PKHeX.Core/Saves/SAV8.cs b/PKHeX.Core/Saves/SAV8.cs
index 2759179c2..7287662e9 100644
--- a/PKHeX.Core/Saves/SAV8.cs
+++ b/PKHeX.Core/Saves/SAV8.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
namespace PKHeX.Core
{
@@ -13,11 +12,11 @@ public abstract class SAV8 : SaveFile, ISaveBlock8Main
protected internal override string ShortSummary => $"{OT} ({Version}) - {Played.LastSavedTime}";
public override string Extension => string.Empty;
- public override IReadOnlyList PKMExtensions => PKM.Extensions.Where(f =>
+ public override IReadOnlyList PKMExtensions => Array.FindAll(PKM.Extensions, f =>
{
int gen = f[^1] - 0x30;
return gen <= 8;
- }).ToArray();
+ });
protected SAV8(byte[] data) : base(data) { }
protected SAV8() { }
diff --git a/PKHeX.Core/Saves/SaveFile.cs b/PKHeX.Core/Saves/SaveFile.cs
index 93e93c9d8..0a2bff612 100644
--- a/PKHeX.Core/Saves/SaveFile.cs
+++ b/PKHeX.Core/Saves/SaveFile.cs
@@ -48,11 +48,11 @@ public SaveFile Clone()
public virtual string PlayTimeString => $"{PlayedHours}ː{PlayedMinutes:00}ː{PlayedSeconds:00}"; // not :
- public virtual IReadOnlyList PKMExtensions => PKM.Extensions.Where(f =>
+ public virtual IReadOnlyList PKMExtensions => Array.FindAll(PKM.Extensions, f =>
{
int gen = f[^1] - 0x30;
return 3 <= gen && gen <= Generation;
- }).ToArray();
+ });
// General SAV Properties
public byte[] Write(ExportFlags flags = ExportFlags.None)
diff --git a/PKHeX.Core/Saves/Substructures/Mail/Mail2.cs b/PKHeX.Core/Saves/Substructures/Mail/Mail2.cs
index b8efccffd..9b95b2681 100644
--- a/PKHeX.Core/Saves/Substructures/Mail/Mail2.cs
+++ b/PKHeX.Core/Saves/Substructures/Mail/Mail2.cs
@@ -1,5 +1,3 @@
-using System.Linq;
-
namespace PKHeX.Core
{
public sealed class Mail2 : Mail
@@ -22,8 +20,10 @@ public override void SetMessage(string line1, string line2)
{
if (US)
{
- StringConverter12.SetString1(line2, 0x10, false, 0x10, 0x50).CopyTo(Data, 0x11);
- StringConverter12.SetString1(line1, 0x10, false, 0x10, Data.Skip(0x11).Take(0x10).All(v => v == 0x50) ? (byte)0x50 : (byte)0x7F).CopyTo(Data, 0);
+ StringConverter12.SetString1(line2, 0x10, false, 0x10, StringConverter12.G1TerminatorCode).CopyTo(Data, 0x11);
+ bool hasLine2 = Data[0x11] != StringConverter12.G1TerminatorCode;
+ byte padChar = !hasLine2 ? StringConverter12.G1TerminatorCode : (byte)0x7F; // space
+ StringConverter12.SetString1(line1, 0x10, false, 0x10, padChar).CopyTo(Data, 0);
Data[0x10] = 0x4E;
}
}
diff --git a/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs b/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs
index 6d2647a10..523d8dda7 100644
--- a/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs
+++ b/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs
@@ -177,9 +177,9 @@ private void LoadAllBags()
var dgv = GetGrid(pouch.Type);
// Sanity Screen
- var invalid = pouch.Items.Where(item => item.Index != 0 && !pouch.LegalItems.Contains((ushort)item.Index)).ToArray();
- var outOfBounds = invalid.Where(item => item.Index >= itemlist.Length).ToArray();
- var incorrectPouch = invalid.Where(item => item.Index < itemlist.Length).ToArray();
+ var invalid = Array.FindAll(pouch.Items, item => item.Index != 0 && !pouch.LegalItems.Contains((ushort)item.Index));
+ var outOfBounds = Array.FindAll(invalid, item => item.Index >= itemlist.Length);
+ var incorrectPouch = Array.FindAll(invalid, item => item.Index < itemlist.Length);
if (outOfBounds.Length > 0)
WinFormsUtil.Error(MsgItemPouchUnknown, $"Item ID(s): {string.Join(", ", outOfBounds.Select(item => item.Index))}");