using System;
namespace PKHeX.Core
{
///
/// Logic for modifying the .
///
public static class MarkingApplicator
{
///
/// Default when applying markings.
///
// ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global
public static Func> MarkingMethod { get; set; } = FlagHighLow;
///
/// Sets the to indicate flawless (or near-flawless) .
///
/// Pokémon to modify.
/// to use (if already known). Will fetch the current if not provided.
public static void SetMarkings(this PKM pk, int[] ivs)
{
if (pk.Format <= 3)
return; // no markings (gen3 only has 4; can't mark stats intelligently
Span markings = stackalloc int[ivs.Length];
var method = MarkingMethod(pk);
for (int i = 0; i < markings.Length; i++)
markings[i] = method(ivs[i], i);
PKX.ReorderSpeedLast(markings);
pk.SetMarkings(markings);
}
///
/// Sets the to indicate flawless (or near-flawless) .
///
/// Pokémon to modify.
public static void SetMarkings(this PKM pk)
{
if (pk.Format <= 3)
return; // no markings (gen3 only has 4; can't mark stats intelligently
Span IVs = stackalloc int[6];
pk.GetIVs(IVs);
pk.SetMarkings(IVs);
}
///
/// Toggles the marking at a given index.
///
/// Pokémon to modify.
/// Marking index to toggle
/// Current marking values
public static int[] ToggleMarking(this PKM pk, int index) => pk.ToggleMarking(index, pk.Markings);
///
/// Toggles the marking at a given index.
///
/// Pokémon to modify.
/// Marking index to toggle
/// Current marking values (optional)
/// Current marking values
public static int[] ToggleMarking(this PKM pk, int index, int[] markings)
{
switch (pk.Format)
{
case 3 or 4 or 5 or 6: // on/off
markings[index] ^= 1; // toggle
pk.Markings = markings;
break;
case 7 or 8: // 0 (none) | 1 (blue) | 2 (pink)
markings[index] = (markings[index] + 1) % 3; // cycle 0->1->2->0...
pk.Markings = markings;
break;
}
return markings;
}
private static Func FlagHighLow(PKM pk)
{
if (pk.Format < 7)
return GetSimpleMarking;
return GetComplexMarking;
static int GetSimpleMarking(int val, int _) => val == 31 ? 1 : 0;
static int GetComplexMarking(int val, int _) => val switch
{
31 or 1 => 1,
30 or 0 => 2,
_ => 0,
};
}
}
}