diff --git a/src/HexManiac.Core/Models/Runs/ArrayRun.cs b/src/HexManiac.Core/Models/Runs/ArrayRun.cs index fff27908..901745e7 100644 --- a/src/HexManiac.Core/Models/Runs/ArrayRun.cs +++ b/src/HexManiac.Core/Models/Runs/ArrayRun.cs @@ -257,22 +257,32 @@ namespace HavenSoft.HexManiac.Core.Models.Runs { // some searches allow special conditions on the run. For example, we could only be intersted in runs with >100 pointers leading to it. if (runFilter != null && !runFilter(targetRun)) continue; + // tolerate a few errors in the data. We know what length we're looking for, so if most of the elements match, then + // most likely we're just looking at the right collection but with some user-created bugs. + int errorsToTolerate = bestLength / 80; + int encounterErrors = 0; + int lastGoodLength = 0; int currentLength = 0; int currentAddress = targetRun.Start; bool earlyExit = false; for (int i = 0; i < bestLength; i++) { var nextArray = data.GetNextAnchor(currentAddress + 1); - if (DataMatchesElementFormat(data, currentAddress, elementContent, flags, nextArray)) { - currentLength++; - currentAddress += elementLength; + bool match = DataMatchesElementFormat(data, currentAddress, elementContent, flags, nextArray); + currentLength++; + currentAddress += elementLength; + if (match) { + lastGoodLength = currentLength; } else { - // as long as this array is at least 80% of the passed in array, we're fine and can say that these are matched. - // (the other one might have bad data at the end that needs to be removed) (example: see Gaia) - earlyExit = bestLength * .8 > currentLength; - break; + encounterErrors++; + if (encounterErrors > errorsToTolerate) { + // as long as this array is at least 80% of the passed in array, we're fine and can say that these are matched. + // (the other one might have bad data at the end that needs to be removed) (example: see Gaia) + earlyExit = bestLength * .8 > lastGoodLength; + break; + } } } - + currentLength = lastGoodLength; if (!earlyExit) { var dataEmpty = Enumerable.Range(targetRun.Start, currentLength * elementLength).Select(i => data[i]).All(d => d == 0xFF || d == 0x00); diff --git a/src/HexManiac.Core/Models/Runs/PLMRun.cs b/src/HexManiac.Core/Models/Runs/PLMRun.cs index b765e42b..a1fda647 100644 --- a/src/HexManiac.Core/Models/Runs/PLMRun.cs +++ b/src/HexManiac.Core/Models/Runs/PLMRun.cs @@ -39,7 +39,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs { } // validate value var (level, move) = SplitToken(value); - if (level > 100 || level < 1) break; + if (level > 101 || level < 1) break; if (move > this.cachedMovenames.Count) break; } } diff --git a/src/HexManiac.Tests/AutoSearchTests.cs b/src/HexManiac.Tests/AutoSearchTests.cs index af4e99e1..f947f6d5 100644 --- a/src/HexManiac.Tests/AutoSearchTests.cs +++ b/src/HexManiac.Tests/AutoSearchTests.cs @@ -36,7 +36,7 @@ namespace HavenSoft.HexManiac.Tests { var address = model.GetAddressFromAnchor(noChange, -1, EggMoveRun.PokemonNameTable); var run = (ArrayRun)model.GetNextAnchor(address); - if (game.Contains("Gaia")) Assert.Equal(914, run.ElementCount); + if (game.Contains("Gaia")) Assert.Equal(925, run.ElementCount); else Assert.Equal(412, run.ElementCount); }