2024-05-13 04:40:50 +00:00
|
|
|
using System;
|
2023-02-09 01:24:47 +00:00
|
|
|
using static PKHeX.Core.CheckIdentifier;
|
2024-05-13 23:16:26 +00:00
|
|
|
using static PKHeX.Core.LegalityCheckStrings;
|
2023-02-09 01:24:47 +00:00
|
|
|
|
|
|
|
namespace PKHeX.Core.Bulk;
|
|
|
|
|
|
|
|
public sealed class HandlerChecker : IBulkAnalyzer
|
|
|
|
{
|
|
|
|
public void Analyze(BulkAnalysis input)
|
|
|
|
{
|
|
|
|
if (input.Trainer.Generation < 6 || !input.Settings.CheckActiveHandler)
|
|
|
|
return; // no HT yet
|
|
|
|
CheckHandlerFlag(input);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void CheckHandlerFlag(BulkAnalysis input)
|
|
|
|
{
|
|
|
|
for (var i = 0; i < input.AllData.Count; i++)
|
|
|
|
{
|
2024-05-13 23:16:26 +00:00
|
|
|
var la = input.AllAnalysis[i];
|
|
|
|
if (!la.Valid)
|
2023-02-09 01:24:47 +00:00
|
|
|
continue;
|
|
|
|
var cs = input.AllData[i];
|
2024-05-13 23:16:26 +00:00
|
|
|
Verify(input, cs, la);
|
2023-02-09 01:24:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-13 23:16:26 +00:00
|
|
|
private static void Verify(BulkAnalysis input, SlotCache cs, LegalityAnalysis la)
|
2023-02-09 01:24:47 +00:00
|
|
|
{
|
|
|
|
var pk = cs.Entity;
|
|
|
|
var tr = cs.SAV;
|
2024-05-13 23:16:26 +00:00
|
|
|
var current = pk.CurrentHandler;
|
2023-02-09 01:24:47 +00:00
|
|
|
|
2024-05-13 23:16:26 +00:00
|
|
|
var shouldBe0 = tr.IsFromTrainer(pk);
|
|
|
|
byte expect = shouldBe0 ? (byte)0 : (byte)1;
|
|
|
|
if (!HistoryVerifier.IsHandlerStateCorrect(la.EncounterOriginal, pk, current, expect))
|
|
|
|
input.AddLine(cs, LTransferCurrentHandlerInvalid, Trainer);
|
2023-02-09 01:24:47 +00:00
|
|
|
|
2024-05-13 23:16:26 +00:00
|
|
|
if (current == 1)
|
|
|
|
CheckHandlingTrainerEquals(input, pk, tr, cs);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary> <see cref="HistoryVerifier.CheckHandlingTrainerEquals"/> </summary>
|
|
|
|
private static void CheckHandlingTrainerEquals(BulkAnalysis data, PKM pk, SaveFile tr, SlotCache cs)
|
|
|
|
{
|
2024-05-13 04:40:50 +00:00
|
|
|
Span<char> ht = stackalloc char[pk.TrashCharCountTrainer];
|
|
|
|
var len = pk.LoadString(pk.HandlingTrainerTrash, ht);
|
|
|
|
ht = ht[..len];
|
|
|
|
|
|
|
|
if (!ht.SequenceEqual(tr.OT))
|
2024-05-13 23:16:26 +00:00
|
|
|
data.AddLine(cs, LTransferHTMismatchName, Trainer);
|
|
|
|
if (pk.HandlingTrainerGender != tr.Gender)
|
|
|
|
data.AddLine(cs, LTransferHTMismatchGender, Trainer);
|
|
|
|
|
|
|
|
// If the format exposes a language, check if it matches.
|
|
|
|
// Can be mismatched as the game only checks OT/Gender equivalence -- if it matches, don't update everything else.
|
|
|
|
// Statistically unlikely that players will play in different languages, but it's technically possible.
|
2024-02-23 03:20:54 +00:00
|
|
|
if (pk is IHandlerLanguage h && h.HandlingTrainerLanguage != tr.Language)
|
2024-05-13 23:16:26 +00:00
|
|
|
data.AddLine(cs, LTransferHTMismatchLanguage, Trainer, Severity.Fishy);
|
2023-02-09 01:24:47 +00:00
|
|
|
}
|
|
|
|
}
|