Batch editing: accurately track untouched results

still feels goofy
This commit is contained in:
Kurt
2025-04-20 11:23:59 -05:00
parent 972c432205
commit d6a18ddc10
5 changed files with 65 additions and 28 deletions

View File

@@ -350,7 +350,7 @@ public static bool TryModify(PKM pk, IEnumerable<StringInstruction> filters, IEn
internal static ModifyResult TryModifyPKM(PKM pk, IEnumerable<StringInstruction> filters, IEnumerable<StringInstruction> modifications)
{
if (!pk.ChecksumValid || pk.Species == 0)
return ModifyResult.Invalid;
return ModifyResult.Skipped;
var info = new BatchInfo(pk);
var props = GetProps(pk);
@@ -369,22 +369,27 @@ internal static ModifyResult TryModifyPKM(PKM pk, IEnumerable<StringInstruction>
}
}
ModifyResult result = ModifyResult.Modified;
var error = false;
var result = ModifyResult.Skipped;
foreach (var cmd in modifications)
{
try
{
var tmp = SetPKMProperty(cmd, info, props);
if (tmp != ModifyResult.Modified)
if (tmp == ModifyResult.Error)
error = true;
else if (tmp != ModifyResult.Skipped)
result = tmp;
}
// Swallow any error because this can be malformed user input.
catch (Exception ex)
{
Debug.WriteLine(MsgBEModifyFail + " " + ex.Message, cmd.PropertyName, cmd.PropertyValue);
result = ModifyResult.Error;
error = true;
}
}
if (error)
result |= ModifyResult.Error;
return result;
}

View File

@@ -34,10 +34,14 @@ public bool Process(PKM pk, IEnumerable<StringInstruction> filters, IEnumerable<
}
var result = BatchEditing.TryModifyPKM(pk, filters, modifications);
if (result != ModifyResult.Invalid)
if (result != ModifyResult.Skipped)
Iterated++;
if (result == ModifyResult.Error)
if (result.HasFlag(ModifyResult.Error))
{
Failed++;
// Still need to fix checksum if another modification was successful.
result &= ~ModifyResult.Error;
}
if (result != ModifyResult.Modified)
return false;

View File

@@ -1,27 +1,30 @@
namespace PKHeX.Core;
using System;
namespace PKHeX.Core;
/// <summary>
/// Batch Editor Modification result for an individual <see cref="PKM"/>.
/// Batch Editor Modification result for an individual processing operation.
/// </summary>
[Flags]
public enum ModifyResult
{
/// <summary>
/// The <see cref="PKM"/> has invalid data and is not a suitable candidate for modification.
/// </summary>
Invalid,
/// <summary>
/// An error was occurred while iterating modifications for this <see cref="PKM"/>.
/// </summary>
Error,
/// <summary>
/// The <see cref="PKM"/> was skipped due to a matching Filter.
/// No modifications were performed as a filter excluded it.
/// </summary>
Filtered,
/// <summary>
/// The <see cref="PKM"/> was modified.
/// Not a suitable candidate for modification.
/// </summary>
Skipped,
/// <summary>
/// One or more modifications was successfully applied.
/// </summary>
Modified,
/// <summary>
/// An error was occurred while attempting modifications.
/// </summary>
Error = 0x80,
}

View File

@@ -48,7 +48,7 @@ public static ModifyResult SetSuggestedMasteryData(BatchInfo info, ReadOnlySpan<
{
var pk = info.Entity;
if (pk is not IMoveShop8Mastery t)
return ModifyResult.Invalid;
return ModifyResult.Skipped;
t.ClearMoveShopFlags();
if (IsNone(propValue))
@@ -95,10 +95,14 @@ public static ModifyResult SetSuggestedMetData(BatchInfo info)
var location = encounter.Location;
var level = encounter.LevelMin;
var minimumLevel = EncounterSuggestion.GetLowestLevel(pk, level);
var current = Math.Max(minimumLevel, level);
if (pk.MetLevel == level && pk.MetLocation == location && pk.CurrentLevel == current)
return ModifyResult.Skipped;
pk.MetLevel = level;
pk.MetLocation = location;
pk.CurrentLevel = Math.Max(minimumLevel, level);
pk.CurrentLevel = current;
return ModifyResult.Modified;
}
@@ -109,7 +113,7 @@ public static ModifyResult SetSuggestedMetData(BatchInfo info)
public static ModifyResult SetMinimumCurrentLevel(BatchInfo info)
{
var result = EncounterSuggestion.IterateMinimumCurrentLevel(info.Entity, info.Legal);
return result ? ModifyResult.Modified : ModifyResult.Filtered;
return result ? ModifyResult.Modified : ModifyResult.Skipped;
}
/// <summary>
@@ -119,6 +123,10 @@ public static ModifyResult SetMinimumCurrentLevel(BatchInfo info)
/// <param name="moves">Moves to apply.</param>
public static ModifyResult SetMoves(PKM pk, ReadOnlySpan<ushort> moves)
{
Span<ushort> current = stackalloc ushort[4];
pk.GetMoves(current);
if (current.SequenceEqual(moves))
return ModifyResult.Skipped;
pk.SetMoves(moves);
return ModifyResult.Modified;
}
@@ -127,6 +135,11 @@ public static ModifyResult SetEVs(PKM pk)
{
Span<int> evs = stackalloc int[6];
EffortValues.SetMax(evs, pk);
Span<int> current = stackalloc int[6];
pk.GetEVs(current);
if (current.SequenceEqual(evs))
return ModifyResult.Skipped;
pk.SetEVs(evs);
return ModifyResult.Modified;
}
@@ -149,21 +162,33 @@ public static ModifyResult SetContestStats(PKM pk, LegalityAnalysis la, ReadOnly
public static ModifyResult SetSuggestedCurrentFriendship(BatchInfo info)
{
var pk = info.Entity;
pk.CurrentFriendship = HistoryVerifier.GetSuggestedFriendshipCurrent(pk, info.Legality.EncounterMatch);
var value = HistoryVerifier.GetSuggestedFriendshipCurrent(pk, info.Legality.EncounterMatch);
if (pk.CurrentFriendship == value)
return ModifyResult.Skipped;
pk.CurrentFriendship = value;
return ModifyResult.Modified;
}
public static ModifyResult SetSuggestedOriginalTrainerFriendship(BatchInfo info)
{
var pk = info.Entity;
pk.OriginalTrainerFriendship = HistoryVerifier.GetSuggestedFriendshipOT(pk, info.Legality.EncounterMatch);
var value = HistoryVerifier.GetSuggestedFriendshipOT(pk, info.Legality.EncounterMatch);
if (pk.OriginalTrainerFriendship == value)
return ModifyResult.Skipped;
pk.OriginalTrainerFriendship = value;
return ModifyResult.Modified;
}
public static ModifyResult SetSuggestedHandlingTrainerFriendship(BatchInfo info)
{
var pk = info.Entity;
pk.HandlingTrainerFriendship = HistoryVerifier.GetSuggestedFriendshipHT(pk);
var value = HistoryVerifier.GetSuggestedFriendshipHT(pk);
if (pk.HandlingTrainerFriendship == value)
return ModifyResult.Skipped;
pk.HandlingTrainerFriendship = value;
return ModifyResult.Modified;
}
}

View File

@@ -25,9 +25,9 @@ public ModifyResult Modify(ReadOnlySpan<char> name, ReadOnlySpan<char> value, Ba
{
var pk = info.Entity;
if (pk is not T x)
return ModifyResult.Invalid;
return ModifyResult.Skipped;
if (!Criteria(x))
return ModifyResult.Invalid;
return ModifyResult.Skipped;
Action(x, value);
return ModifyResult.Modified;
}