diff --git a/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs b/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs
index cf73b9ffa..b0d52792a 100644
--- a/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs
@@ -1,9 +1,9 @@
-using System;
+using System;
namespace PKHeX.Core;
///
-/// Logic for modifying the .
+/// Logic for modifying the .
///
public static class MarkingApplicator
{
@@ -14,21 +14,40 @@ public static class MarkingApplicator
public static Func> MarkingMethod { get; set; } = FlagHighLow;
///
- /// Sets the to indicate flawless (or near-flawless) .
+ /// Sets the applied Markings to indicate flawless (or near-flawless) .
///
/// Pokémon to modify.
public static void SetMarkings(this PKM pk)
{
- if (pk.MarkingCount < 6)
+ if (pk is not IAppliedMarkings { MarkingCount: 6 })
return; // insufficient marking indexes
+ if (pk is IAppliedMarkings c)
+ SetMarkings(c, pk);
+ else if (pk is IAppliedMarkings b)
+ SetMarkings(b, pk);
+ }
+
+ private static void SetMarkings(this IAppliedMarkings mark, PKM pk)
+ {
var method = MarkingMethod(pk);
- pk.SetMarking(0, method(pk.IV_HP , 0));
- pk.SetMarking(1, method(pk.IV_ATK, 1));
- pk.SetMarking(2, method(pk.IV_DEF, 2));
- pk.SetMarking(3, method(pk.IV_SPA, 3));
- pk.SetMarking(4, method(pk.IV_SPD, 4));
- pk.SetMarking(5, method(pk.IV_SPE, 5));
+ mark.SetMarking(0, method(pk.IV_HP , 0) == 1);
+ mark.SetMarking(1, method(pk.IV_ATK, 1) == 1);
+ mark.SetMarking(2, method(pk.IV_DEF, 2) == 1);
+ mark.SetMarking(3, method(pk.IV_SPA, 3) == 1);
+ mark.SetMarking(4, method(pk.IV_SPD, 4) == 1);
+ mark.SetMarking(5, method(pk.IV_SPE, 5) == 1);
+ }
+
+ private static void SetMarkings(this IAppliedMarkings mark, PKM pk)
+ {
+ var method = MarkingMethod(pk);
+ mark.SetMarking(0, (MarkingColor)method(pk.IV_HP, 0));
+ mark.SetMarking(1, (MarkingColor)method(pk.IV_ATK, 1));
+ mark.SetMarking(2, (MarkingColor)method(pk.IV_DEF, 2));
+ mark.SetMarking(3, (MarkingColor)method(pk.IV_SPA, 3));
+ mark.SetMarking(4, (MarkingColor)method(pk.IV_SPD, 4));
+ mark.SetMarking(5, (MarkingColor)method(pk.IV_SPE, 5));
}
///
@@ -37,18 +56,19 @@ public static class MarkingApplicator
/// Pokémon to modify.
/// Marking index to toggle
/// Current marking value
- public static int ToggleMarking(this PKM pk, int index)
+ public static void ToggleMarking(this PKM pk, int index)
{
- var marking = pk.GetMarking(index);
- var revised = NextMarking(pk.Format, marking);
- pk.SetMarking(index, revised);
- return revised;
+ if (pk is IAppliedMarkings c)
+ c.SetMarking(index, c.GetMarking(index).Next());
+ else if (pk is IAppliedMarkings b)
+ b.SetMarking(index, !b.GetMarking(index));
}
- private static int NextMarking(int format, int marking) => format switch
+ private static MarkingColor Next(this MarkingColor value) => value switch
{
- <= 6 => marking ^ 1, // toggle : 0 (off) | 1 (on)
- _ => (marking + 1) % 3, // cycle 0->1->2->0... : 0 (none) | 1 (blue) | 2 (pink)
+ MarkingColor.Blue => MarkingColor.Pink,
+ MarkingColor.Pink => MarkingColor.None,
+ _ => MarkingColor.Blue,
};
private static Func FlagHighLow(PKM pk)
diff --git a/PKHeX.Core/Editing/PKM/EntitySummary.cs b/PKHeX.Core/Editing/PKM/EntitySummary.cs
index 37d0d2b19..a1f565716 100644
--- a/PKHeX.Core/Editing/PKM/EntitySummary.cs
+++ b/PKHeX.Core/Editing/PKM/EntitySummary.cs
@@ -66,7 +66,6 @@ public class EntitySummary : IFatefulEncounterReadOnly // do NOT seal, allow inh
public int Smart => pk is IContestStatsReadOnly s ? s.CNT_Smart : 0;
public int Tough => pk is IContestStatsReadOnly s ? s.CNT_Tough : 0;
public int Sheen => pk is IContestStatsReadOnly s ? s.CNT_Sheen : 0;
- public int Markings => pk.MarkValue;
public string NotOT => pk.Format > 5 ? pk.HT_Name : "N/A";
diff --git a/PKHeX.Core/Legality/Verifiers/MarkingVerifier.cs b/PKHeX.Core/Legality/Verifiers/MarkingVerifier.cs
index 0797d41be..18ad0e701 100644
--- a/PKHeX.Core/Legality/Verifiers/MarkingVerifier.cs
+++ b/PKHeX.Core/Legality/Verifiers/MarkingVerifier.cs
@@ -4,7 +4,7 @@ using static PKHeX.Core.CheckIdentifier;
namespace PKHeX.Core;
///
-/// Verifies the .
+/// Verifies the .
///
public sealed class MarkingVerifier : Verifier
{
@@ -26,26 +26,14 @@ public sealed class MarkingVerifier : Verifier
private void VerifyMarkValue(LegalityAnalysis data, PKM pk)
{
- var mv = pk.MarkValue;
- if (mv == 0)
- return;
-
// Eggs can have markings applied.
- //if (pk.IsEgg)
- //{
- // data.AddLine(GetInvalid(LMarkValueShouldBeZero));
- // return;
- //}
-
- switch (pk.Format)
+ switch (pk)
{
- case <= 2:
+ case IAppliedMarkings3 m4:
+ VerifyMarkValueSingle(data, m4, m4.MarkingValue);
return;
- case <= 6:
- VerifyMarkValueSingle(data, pk, mv);
- return;
- default:
- VerifyMarkValueDual(data, pk, mv);
+ case IAppliedMarkings7 m7:
+ VerifyMarkValueDual(data, m7, m7.MarkingValue);
return;
}
}
@@ -54,8 +42,10 @@ public sealed class MarkingVerifier : Verifier
private const int Single6 = 0b_111111;
private const int Dual6 = 0b_1111_1111_1111;
- private void VerifyMarkValueDual(LegalityAnalysis data, PKM pk, int mv)
+ private void VerifyMarkValueDual(LegalityAnalysis data, IAppliedMarkings7 pk, ushort mv)
{
+ if (mv == 0)
+ return;
if (mv > Dual6)
data.AddLine(GetInvalid(LMarkValueUnusedBitsPresent));
@@ -63,20 +53,22 @@ public sealed class MarkingVerifier : Verifier
for (int i = 0; i < count; i++)
{
var value = pk.GetMarking(i);
- if (value is not (0 or 1 or 2))
+ if (value is not (0 or MarkingColor.Blue or MarkingColor.Pink))
data.AddLine(GetInvalid(string.Format(LMarkValueOutOfRange_0, i)));
}
}
- private void VerifyMarkValueSingle(LegalityAnalysis data, PKM pk, int mv)
+ private void VerifyMarkValueSingle(LegalityAnalysis data, IAppliedMarkings3 pk, byte mv)
{
+ if (mv == 0)
+ return;
if (!IsMarkValueValid3456(pk, mv))
data.AddLine(GetInvalid(LMarkValueUnusedBitsPresent));
}
- private static bool IsMarkValueValid3456(PKM pk, int value)
+ private static bool IsMarkValueValid3456(IAppliedMarkings3 pk, int value)
{
- var max = pk.Format is 3 ? Single4 : Single6;
+ var max = pk is IAppliedMarkings4 ? Single6 : Single4;
return value <= max;
}
}
diff --git a/PKHeX.Core/PKM/BK4.cs b/PKHeX.Core/PKM/BK4.cs
index 3da2cbf81..2a7d06912 100644
--- a/PKHeX.Core/PKM/BK4.cs
+++ b/PKHeX.Core/PKM/BK4.cs
@@ -63,7 +63,7 @@ public sealed class BK4 : G4PKM
public override int OT_Friendship { get => Data[0x14]; set => Data[0x14] = (byte)value; }
public override int Ability { get => Data[0x15]; set => Data[0x15] = (byte)value; }
- public override int MarkValue { get => Data[0x16]; set => Data[0x16] = (byte)value; }
+ public override byte MarkingValue { get => Data[0x16]; set => Data[0x16] = value; }
public override int Language { get => Data[0x17]; set => Data[0x17] = (byte)value; }
public override int EV_HP { get => Data[0x18]; set => Data[0x18] = (byte)value; }
public override int EV_ATK { get => Data[0x19]; set => Data[0x19] = (byte)value; }
diff --git a/PKHeX.Core/PKM/CK3.cs b/PKHeX.Core/PKM/CK3.cs
index a3f14d054..00d51a401 100644
--- a/PKHeX.Core/PKM/CK3.cs
+++ b/PKHeX.Core/PKM/CK3.cs
@@ -174,7 +174,7 @@ public sealed class CK3(byte[] Data) : G3PKM(Data), IShadowCapture
public override bool AbilityBit { get => Data[0xCC] == 1; set => Data[0xCC] = value ? (byte)1 : (byte)0; }
public override bool Valid { get => Data[0xCD] == 0; set => Data[0xCD] = !value ? (byte)1 : (byte)0; }
- public override int MarkValue { get => SwapBits(Data[0xCF], 1, 2); set => Data[0xCF] = (byte)SwapBits(value, 1, 2); }
+ public override byte MarkingValue { get => (byte)SwapBits(Data[0xCF], 1, 2); set => Data[0xCF] = (byte)SwapBits(value, 1, 2); }
public override int PKRS_Days { get => Math.Max((sbyte)Data[0xD0], (sbyte)0); set => Data[0xD0] = (byte)(value == 0 ? 0xFF : value & 0xF); }
public int PartySlot { get => Data[0xD7]; set => Data[0xD7] = (byte)value; } // or not; only really used while in party?
diff --git a/PKHeX.Core/PKM/HOME/GameDataCore.cs b/PKHeX.Core/PKM/HOME/GameDataCore.cs
index 55f2a92b5..19362b89b 100644
--- a/PKHeX.Core/PKM/HOME/GameDataCore.cs
+++ b/PKHeX.Core/PKM/HOME/GameDataCore.cs
@@ -10,7 +10,8 @@ namespace PKHeX.Core;
public sealed class GameDataCore : IHomeTrack, ISpeciesForm, ITrainerID, INature, IFatefulEncounter, IContestStats, IScaledSize, ITrainerMemories, IHandlerLanguage, IBattleVersion, IHyperTrain, IFormArgument, IFavorite,
IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetMemory6, IRibbonSetCommon7,
IRibbonSetCommon8, IRibbonSetMark8,
- IRibbonSetCommon9, IRibbonSetMark9
+ IRibbonSetCommon9, IRibbonSetMark9,
+ IAppliedMarkings7
{
// Internal Attributes set on creation
private readonly Memory Buffer; // Raw Storage
@@ -39,7 +40,7 @@ public sealed class GameDataCore : IHomeTrack, ISpeciesForm, ITrainerID, INature
public ushort SID16 { get => ReadUInt16LittleEndian(Data[0x11..]); set => WriteUInt16LittleEndian(Data[0x11..], value); }
public uint EXP { get => ReadUInt32LittleEndian(Data[0x13..]); set => WriteUInt32LittleEndian(Data[0x13..], value); }
public bool IsFavorite { get => Data[0x17] != 0; set => Data[0x17] = (byte)(value ? 1 : 0); }
- public int MarkValue { get => ReadUInt16LittleEndian(Data[0x18..]); set => WriteUInt16LittleEndian(Data[0x18..], (ushort)value); }
+ public ushort MarkingValue { get => ReadUInt16LittleEndian(Data[0x18..]); set => WriteUInt16LittleEndian(Data[0x18..], value); }
public uint PID { get => ReadUInt32LittleEndian(Data[0x1A..]); set => WriteUInt32LittleEndian(Data[0x1A..], value); }
public int Nature { get => Data[0x1E]; set => Data[0x1E] = (byte)value; }
public int StatNature { get => Data[0x1F]; set => Data[0x1F] = (byte)value; }
@@ -296,25 +297,32 @@ public sealed class GameDataCore : IHomeTrack, ISpeciesForm, ITrainerID, INature
public int HeldItem { get => ReadUInt16LittleEndian(Data[0xC2..]); set => WriteUInt16LittleEndian(Data[0xC2..], (ushort)value); }
- public int MarkingCount => 6;
-
public TrainerIDFormat TrainerIDDisplayFormat => ((GameVersion)Version).GetGeneration() >= 7 ? TrainerIDFormat.SixDigit : TrainerIDFormat.SixteenBit;
- public int GetMarking(int index)
+ public int MarkingCount => 6;
+
+ public MarkingColor GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> (index * 2)) & 3;
+ return (MarkingColor)((MarkingValue >> (index * 2)) & 3);
}
- public void SetMarking(int index, int value)
+ public void SetMarking(int index, MarkingColor value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
var shift = index * 2;
- MarkValue = (MarkValue & ~(0b11 << shift)) | ((value & 3) << shift);
+ MarkingValue = (ushort)((MarkingValue & ~(0b11 << shift)) | (((byte)value & 3) << shift));
}
+ public MarkingColor MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public MarkingColor MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); }
+ public MarkingColor MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public MarkingColor MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+ public MarkingColor MarkingStar { get => GetMarking(4); set => SetMarking(4, value); }
+ public MarkingColor MarkingDiamond { get => GetMarking(5); set => SetMarking(5, value); }
+
public void CopyFrom(PKM pk)
{
EncryptionConstant = pk.EncryptionConstant;
@@ -325,7 +333,7 @@ public sealed class GameDataCore : IHomeTrack, ISpeciesForm, ITrainerID, INature
TID16 = pk.TID16;
SID16 = pk.SID16;
EXP = pk.EXP;
- MarkValue = pk.MarkValue;
+ MarkingValue = pk is IAppliedMarkings7 m7 ? m7.MarkingValue : (ushort)0;
Nature = pk.Nature;
StatNature = pk.StatNature;
FatefulEncounter = pk.FatefulEncounter;
@@ -382,7 +390,8 @@ public sealed class GameDataCore : IHomeTrack, ISpeciesForm, ITrainerID, INature
pk.TID16 = TID16;
pk.SID16 = SID16;
pk.EXP = EXP;
- pk.MarkValue = MarkValue;
+ if (pk is IAppliedMarkings7 m7)
+ m7.MarkingValue = MarkingValue;
pk.Nature = Nature;
pk.StatNature = StatNature;
pk.FatefulEncounter = FatefulEncounter;
diff --git a/PKHeX.Core/PKM/HOME/GameDataPK8.cs b/PKHeX.Core/PKM/HOME/GameDataPK8.cs
index 39ccb8241..6b6cf3602 100644
--- a/PKHeX.Core/PKM/HOME/GameDataPK8.cs
+++ b/PKHeX.Core/PKM/HOME/GameDataPK8.cs
@@ -112,7 +112,7 @@ public sealed class GameDataPK8 : HomeOptional1, IGameDataSide, IGigantamax
AbilityNumber = (byte)pk.AbilityNumber;
Ability = (ushort)pk.Ability;
- pkh.MarkValue &= 0b1111_1111_1111;
+ pkh.MarkingValue &= 0b1111_1111_1111;
if (!pk.IsNicknamed)
pkh.Nickname = SpeciesName.GetSpeciesNameGeneration(pk.Species, pk.Language, 8);
if (FormInfo.IsTotemForm(pk.Species, pk.Form))
diff --git a/PKHeX.Core/PKM/HOME/PKH.cs b/PKHeX.Core/PKM/HOME/PKH.cs
index e57404002..97756e61f 100644
--- a/PKHeX.Core/PKM/HOME/PKH.cs
+++ b/PKHeX.Core/PKM/HOME/PKH.cs
@@ -5,7 +5,8 @@ using static PKHeX.Core.GameVersion;
namespace PKHeX.Core;
/// Pokémon HOME format.
-public sealed class PKH : PKM, IHandlerLanguage, IFormArgument, IHomeTrack, IBattleVersion, ITrainerMemories, IRibbonSetAffixed, IContestStats, IScaledSize, IRibbonSetRibbons, IRibbonSetMarks
+public sealed class PKH : PKM, IHandlerLanguage, IFormArgument, IHomeTrack, IBattleVersion, ITrainerMemories, IRibbonSetAffixed, IContestStats, IScaledSize,
+ IRibbonSetRibbons, IRibbonSetMarks, IAppliedMarkings7
{
public readonly GameDataCore Core;
public GameDataPB7? DataPB7 { get; private set; }
@@ -93,7 +94,7 @@ public sealed class PKH : PKM, IHandlerLanguage, IFormArgument, IHomeTrack, IBat
public override ushort SID16 { get => Core.SID16; set => Core.SID16 = value; }
public override uint EXP { get => Core.EXP; set => Core.EXP = value; }
public bool Favorite { get => Core.IsFavorite; set => Core.IsFavorite = value; }
- public override int MarkValue { get => Core.MarkValue; set => Core.MarkValue = value; }
+ public ushort MarkingValue { get => Core.MarkingValue; set => Core.MarkingValue = value; }
public override uint PID { get => Core.PID; set => Core.PID = value; }
public override int Nature { get => Core.Nature; set => Core.Nature = value; }
public override int StatNature { get => Core.StatNature; set => Core.StatNature = value; }
@@ -167,12 +168,19 @@ public sealed class PKH : PKM, IHandlerLanguage, IFormArgument, IHomeTrack, IBat
public override string OT_Name { get => Core.OT_Name; set => Core.OT_Name = value; }
public override string HT_Name { get => Core.HT_Name; set => Core.HT_Name = value; }
- public override int MarkingCount => Core.MarkingCount;
+ public int MarkingCount => Core.MarkingCount;
public int RibbonCount => Core.RibbonCount;
public int MarkCount => Core.MarkCount;
public int RibbonMarkCount => Core.RibbonMarkCount;
- public override int GetMarking(int index) => Core.GetMarking(index);
- public override void SetMarking(int index, int value) => Core.SetMarking(index, value);
+ public MarkingColor GetMarking(int index) => Core.GetMarking(index);
+ public void SetMarking(int index, MarkingColor value) => Core.SetMarking(index, value);
+
+ public MarkingColor MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public MarkingColor MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); }
+ public MarkingColor MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public MarkingColor MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+ public MarkingColor MarkingStar { get => GetMarking(4); set => SetMarking(4, value); }
+ public MarkingColor MarkingDiamond { get => GetMarking(5); set => SetMarking(5, value); }
#endregion
diff --git a/PKHeX.Core/PKM/Interfaces/IAppliedMarkings.cs b/PKHeX.Core/PKM/Interfaces/IAppliedMarkings.cs
new file mode 100644
index 000000000..994c65c38
--- /dev/null
+++ b/PKHeX.Core/PKM/Interfaces/IAppliedMarkings.cs
@@ -0,0 +1,90 @@
+namespace PKHeX.Core;
+
+///
+/// Indicates if the object is capable of being marked by the player with simple shapes.
+///
+public interface IAppliedMarkings
+{
+ ///
+ /// Count of unique markings that can be applied to the object.
+ ///
+ int MarkingCount { get; }
+}
+
+public interface IAppliedMarkings : IAppliedMarkings where T : unmanaged
+{
+ ///
+ /// Gets the marking value at the given index.
+ ///
+ /// Index of the marking to get.
+ /// Marking value at the given index.
+ T GetMarking(int index);
+
+ ///
+ /// Sets the marking value at the given index.
+ ///
+ /// Index of the marking to set.
+ /// Value to set the marking to.
+ void SetMarking(int index, T value);
+}
+
+///
+/// Generation 3 Markings
+///
+public interface IAppliedMarkings3 : IAppliedMarkings
+{
+ ///
+ /// Backing value for the packed bits.
+ ///
+ byte MarkingValue { get; set; }
+
+ bool MarkingCircle { get; set; }
+ bool MarkingTriangle { get; set; } // In generation 3, this is marking index 2
+ bool MarkingSquare { get; set; } // In generation 3, this is marking index 1
+ bool MarkingHeart { get; set; }
+}
+
+///
+/// Generation 4-6 Markings
+///
+public interface IAppliedMarkings4 : IAppliedMarkings3
+{
+ bool MarkingStar { get; set; }
+ bool MarkingDiamond { get; set; }
+}
+
+///
+/// Generation 7+ Markings
+///
+public interface IAppliedMarkings7 : IAppliedMarkings
+{
+ ///
+ /// Backing value for the packed bits.
+ ///
+ ushort MarkingValue { get; set; }
+
+ MarkingColor MarkingCircle { get; set; }
+ MarkingColor MarkingTriangle { get; set; }
+ MarkingColor MarkingSquare { get; set; }
+ MarkingColor MarkingHeart { get; set; }
+ MarkingColor MarkingStar { get; set; }
+ MarkingColor MarkingDiamond { get; set; }
+}
+
+public enum MarkingColor : byte
+{
+ ///
+ /// Not marked.
+ ///
+ None = 0,
+
+ ///
+ /// Blue marking.
+ ///
+ Blue = 1,
+
+ ///
+ /// Pink marking.
+ ///
+ Pink = 2,
+}
diff --git a/PKHeX.Core/PKM/PA8.cs b/PKHeX.Core/PKM/PA8.cs
index 09a6c1fd3..c9f9462a4 100644
--- a/PKHeX.Core/PKM/PA8.cs
+++ b/PKHeX.Core/PKM/PA8.cs
@@ -130,7 +130,7 @@ public sealed class PA8 : PKM, ISanityChecksum,
public bool IsAlpha { get => (Data[0x16] & 32) != 0; set => Data[0x16] = (byte)((Data[0x16] & ~32) | ((value ? 1 : 0) << 5)); }
public bool IsNoble { get => (Data[0x16] & 64) != 0; set => Data[0x16] = (byte)((Data[0x16] & ~64) | ((value ? 1 : 0) << 6)); }
// 0x17 alignment unused
- public override int MarkValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x18)); set => WriteUInt16LittleEndian(Data.AsSpan(0x18), (ushort)value); }
+ public ushort MarkValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x18)); set => WriteUInt16LittleEndian(Data.AsSpan(0x18), value); }
// 0x1A alignment unused
// 0x1B alignment unused
public override uint PID { get => ReadUInt32LittleEndian(Data.AsSpan(0x1C)); set => WriteUInt32LittleEndian(Data.AsSpan(0x1C), value); }
@@ -540,21 +540,21 @@ public sealed class PA8 : PKM, ISanityChecksum,
return NatureAmp.AmplifyStat(nature, statIndex, initial);
}
- public override int MarkingCount => 6;
+ public int MarkingCount => 6;
- public override int GetMarking(int index)
+ public MarkingColor GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> (index * 2)) & 3;
+ return (MarkingColor)((MarkValue >> (index * 2)) & 3);
}
- public override void SetMarking(int index, int value)
+ public void SetMarking(int index, MarkingColor value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
var shift = index * 2;
- MarkValue = (MarkValue & ~(0b11 << shift)) | ((value & 3) << shift);
+ MarkValue = (ushort)((MarkValue & ~(0b11 << shift)) | (((byte)value & 3) << shift));
}
public bool GetRibbon(int index) => FlagUtil.GetFlag(Data, GetRibbonByte(index), index & 7);
diff --git a/PKHeX.Core/PKM/PB7.cs b/PKHeX.Core/PKM/PB7.cs
index 9c245471c..44ecec93d 100644
--- a/PKHeX.Core/PKM/PB7.cs
+++ b/PKHeX.Core/PKM/PB7.cs
@@ -5,7 +5,7 @@ using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
/// Generation 7 format used for .
-public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, ICombatPower, IFavorite, IFormArgument
+public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, ICombatPower, IFavorite, IFormArgument, IAppliedMarkings7
{
public override ReadOnlySpan ExtraBytes =>
[
@@ -98,7 +98,7 @@ public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, IComb
public override int Ability { get => Data[0x14]; set => Data[0x14] = (byte)value; }
public override int AbilityNumber { get => Data[0x15] & 7; set => Data[0x15] = (byte)((Data[0x15] & ~7) | (value & 7)); }
public bool IsFavorite { get => (Data[0x15] & 8) != 0; set => Data[0x15] = (byte)((Data[0x15] & ~8) | ((value ? 1 : 0) << 3)); }
- public override int MarkValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x16)); set => WriteUInt16LittleEndian(Data.AsSpan(0x16), (ushort)value); }
+ public ushort MarkingValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x16)); set => WriteUInt16LittleEndian(Data.AsSpan(0x16), value); }
public override uint PID
{
@@ -309,23 +309,30 @@ public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, IComb
// 102/103 unused
#endregion
- public override int MarkingCount => 6;
+ public int MarkingCount => 6;
- public override int GetMarking(int index)
+ public MarkingColor GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> (index * 2)) & 3;
+ return (MarkingColor)((MarkingValue >> (index * 2)) & 3);
}
- public override void SetMarking(int index, int value)
+ public void SetMarking(int index, MarkingColor value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
var shift = index * 2;
- MarkValue = (MarkValue & ~(0b11 << shift)) | ((value & 3) << shift);
+ MarkingValue = (ushort)((MarkingValue & ~(0b11 << shift)) | (((byte)value & 3) << shift));
}
+ public MarkingColor MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public MarkingColor MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); }
+ public MarkingColor MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public MarkingColor MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+ public MarkingColor MarkingStar { get => GetMarking(4); set => SetMarking(4, value); }
+ public MarkingColor MarkingDiamond { get => GetMarking(5); set => SetMarking(5, value); }
+
protected override bool TradeOT(ITrainerInfo tr)
{
// Check to see if the OT matches the SAV's OT info.
diff --git a/PKHeX.Core/PKM/PK3.cs b/PKHeX.Core/PKM/PK3.cs
index 1ac02b9b1..6edcf4244 100644
--- a/PKHeX.Core/PKM/PK3.cs
+++ b/PKHeX.Core/PKM/PK3.cs
@@ -60,7 +60,7 @@ public sealed class PK3 : G3PKM, ISanityChecksum
get => StringConverter3.GetString(OT_Trash, Japanese);
set => StringConverter3.SetString(OT_Trash, value, 7, Japanese, StringConverterOption.None);
}
- public override int MarkValue { get => SwapBits(Data[0x1B], 1, 2); set => Data[0x1B] = (byte)SwapBits(value, 1, 2); }
+ public override byte MarkingValue { get => (byte)SwapBits(Data[0x1B], 1, 2); set => Data[0x1B] = (byte)SwapBits(value, 1, 2); }
public ushort Checksum { get => ReadUInt16LittleEndian(Data.AsSpan(0x1C)); set => WriteUInt16LittleEndian(Data.AsSpan(0x1C), value); }
public ushort Sanity { get => ReadUInt16LittleEndian(Data.AsSpan(0x1E)); set => WriteUInt16LittleEndian(Data.AsSpan(0x1E), value); }
@@ -222,7 +222,7 @@ public sealed class PK3 : G3PKM, ISanityChecksum
Form = Form,
// IsEgg = false, -- already false
OT_Friendship = 70,
- MarkValue = MarkValue & 0b1111,
+ MarkingValue = (byte)(MarkingValue & 0b1111),
Language = Language,
EV_HP = EV_HP,
EV_ATK = EV_ATK,
diff --git a/PKHeX.Core/PKM/PK4.cs b/PKHeX.Core/PKM/PK4.cs
index a04730d70..292b21921 100644
--- a/PKHeX.Core/PKM/PK4.cs
+++ b/PKHeX.Core/PKM/PK4.cs
@@ -43,7 +43,7 @@ public sealed class PK4 : G4PKM
public override uint EXP { get => ReadUInt32LittleEndian(Data.AsSpan(0x10)); set => WriteUInt32LittleEndian(Data.AsSpan(0x10), value); }
public override int OT_Friendship { get => Data[0x14]; set => Data[0x14] = (byte)value; }
public override int Ability { get => Data[0x15]; set => Data[0x15] = (byte)value; }
- public override int MarkValue { get => Data[0x16]; set => Data[0x16] = (byte)value; }
+ public override byte MarkingValue { get => Data[0x16]; set => Data[0x16] = value; }
public override int Language { get => Data[0x17]; set => Data[0x17] = (byte)value; }
public override int EV_HP { get => Data[0x18]; set => Data[0x18] = (byte)value; }
public override int EV_ATK { get => Data[0x19]; set => Data[0x19] = (byte)value; }
diff --git a/PKHeX.Core/PKM/PK5.cs b/PKHeX.Core/PKM/PK5.cs
index 83cbd14cc..a203ae1b3 100644
--- a/PKHeX.Core/PKM/PK5.cs
+++ b/PKHeX.Core/PKM/PK5.cs
@@ -7,7 +7,7 @@ namespace PKHeX.Core;
/// Generation 5 format.
public sealed class PK5 : PKM, ISanityChecksum,
IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetUnique3, IRibbonSetUnique4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetRibbons,
- IContestStats, IGroundTile
+ IContestStats, IGroundTile, IAppliedMarkings4
{
public override ReadOnlySpan ExtraBytes =>
[
@@ -64,7 +64,7 @@ public sealed class PK5 : PKM, ISanityChecksum,
public override uint EXP { get => ReadUInt32LittleEndian(Data.AsSpan(0x10)); set => WriteUInt32LittleEndian(Data.AsSpan(0x10), value); }
public override int OT_Friendship { get => Data[0x14]; set => Data[0x14] = (byte)value; }
public override int Ability { get => Data[0x15]; set => Data[0x15] = (byte)value; }
- public override int MarkValue { get => Data[0x16]; set => Data[0x16] = (byte)value; }
+ public byte MarkingValue { get => Data[0x16]; set => Data[0x16] = value; }
public override int Language { get => Data[0x17]; set => Data[0x17] = (byte)value; }
public override int EV_HP { get => Data[0x18]; set => Data[0x18] = (byte)value; }
public override int EV_ATK { get => Data[0x19]; set => Data[0x19] = (byte)value; }
@@ -307,22 +307,29 @@ public sealed class PK5 : PKM, ISanityChecksum,
return false;
}
- public override int MarkingCount => 6;
+ public int MarkingCount => 6;
- public override int GetMarking(int index)
+ public bool GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> index) & 1;
+ return ((MarkingValue >> index) & 1) != 0;
}
- public override void SetMarking(int index, int value)
+ public void SetMarking(int index, bool value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- MarkValue = (MarkValue & ~(1 << index)) | ((value & 1) << index);
+ MarkingValue = (byte)((MarkingValue & ~(1 << index)) | ((value ? 1 : 0) << index));
}
+ public bool MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public bool MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); }
+ public bool MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public bool MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+ public bool MarkingStar { get => GetMarking(4); set => SetMarking(4, value); }
+ public bool MarkingDiamond { get => GetMarking(5); set => SetMarking(5, value); }
+
public override void RefreshAbility(int n)
{
base.RefreshAbility(n);
@@ -341,7 +348,7 @@ public sealed class PK5 : PKM, ISanityChecksum,
PID = PID,
Ability = Ability,
AbilityNumber = 1 << CalculateAbilityIndex(),
- MarkValue = MarkValue & 0b_11_1111,
+ MarkingValue = MarkingValue,
Language = Math.Max((int)LanguageID.Japanese, Language), // Hacked or Bad IngameTrade (Japanese B/W)
CNT_Cool = CNT_Cool,
diff --git a/PKHeX.Core/PKM/PK6.cs b/PKHeX.Core/PKM/PK6.cs
index 7212a36bf..0d30c3d3e 100644
--- a/PKHeX.Core/PKM/PK6.cs
+++ b/PKHeX.Core/PKM/PK6.cs
@@ -6,7 +6,7 @@ namespace PKHeX.Core;
/// Generation 6 format.
public sealed class PK6 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetMemory6, IRibbonSetRibbons,
- IContestStats, IGeoTrack, ISuperTrain, IFormArgument, ITrainerMemories, IAffection, IGroundTile
+ IContestStats, IGeoTrack, ISuperTrain, IFormArgument, ITrainerMemories, IAffection, IGroundTile, IAppliedMarkings4
{
public override ReadOnlySpan ExtraBytes =>
[
@@ -112,7 +112,7 @@ public sealed class PK6 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetC
public byte CNT_Smart { get => Data[0x27]; set => Data[0x27] = value; }
public byte CNT_Tough { get => Data[0x28]; set => Data[0x28] = value; }
public byte CNT_Sheen { get => Data[0x29]; set => Data[0x29] = value; }
- public override int MarkValue { get => Data[0x2A]; set => Data[0x2A] = (byte)value; }
+ public byte MarkingValue { get => Data[0x2A]; set => Data[0x2A] = value; }
private byte PKRS { get => Data[0x2B]; set => Data[0x2B] = value; }
public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)((PKRS & ~0xF) | value); }
public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)((PKRS & 0xF) | (value << 4)); }
@@ -455,28 +455,35 @@ public sealed class PK6 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetC
public override int MaxItemID => Legal.MaxItemID_6_AO;
public override int MaxBallID => Legal.MaxBallID_6;
public override int MaxGameID => Legal.MaxGameID_6; // OR
- public override int MarkingCount => 6;
+ public int MarkingCount => 6;
- public override int GetMarking(int index)
+ public bool GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> index) & 1;
+ return ((MarkingValue >> index) & 1) != 0;
}
- public override void SetMarking(int index, int value)
+ public void SetMarking(int index, bool value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- MarkValue = (MarkValue & ~(1 << index)) | ((value & 1) << index);
+ MarkingValue = (byte)((MarkingValue & ~(1 << index)) | ((value ? 1 : 0) << index));
}
+ public bool MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public bool MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); }
+ public bool MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public bool MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+ public bool MarkingStar { get => GetMarking(4); set => SetMarking(4, value); }
+ public bool MarkingDiamond { get => GetMarking(5); set => SetMarking(5, value); }
+
public PK7 ConvertToPK7()
{
PK7 pk7 = new((byte[])Data.Clone())
{
ResortEventStatus = 0, // Clears old Marking Value
- MarkValue = 0, // Clears old Super Training Bag & Hits Remaining
+ MarkingValue = 0, // Clears old Super Training Bag & Hits Remaining
FormArgument = 0, // Clears old style Form Argument
DirtType = 0, // Clears old Form Argument byte
DirtLocation = 0, // Clears old Form Argument byte
@@ -484,7 +491,7 @@ public sealed class PK6 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetC
// Remap boolean markings to the dual-bit format -- set 1 if marked.
for (int i = 0; i < 6; i++)
- pk7.SetMarking(i, GetMarking(i));
+ pk7.SetMarking(i, GetMarking(i) ? MarkingColor.Blue : MarkingColor.None);
var an = AbilityNumber;
if (an is 1 or 2 or 4) // Valid Ability Numbers
diff --git a/PKHeX.Core/PKM/PK7.cs b/PKHeX.Core/PKM/PK7.cs
index 2415fe9d1..ca34176fb 100644
--- a/PKHeX.Core/PKM/PK7.cs
+++ b/PKHeX.Core/PKM/PK7.cs
@@ -6,7 +6,7 @@ namespace PKHeX.Core;
/// Generation 7 format.
public sealed class PK7 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetMemory6, IRibbonSetCommon7, IRibbonSetRibbons,
- IContestStats, IHyperTrain, IGeoTrack, ISuperTrain, IFormArgument, ITrainerMemories, IAffection, IPokerusStatus
+ IContestStats, IHyperTrain, IGeoTrack, ISuperTrain, IFormArgument, ITrainerMemories, IAffection, IPokerusStatus, IAppliedMarkings7
{
public override ReadOnlySpan ExtraBytes =>
[
@@ -88,7 +88,7 @@ public sealed class PK7 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetC
public override int Ability { get => Data[0x14]; set => Data[0x14] = (byte)value; }
public override int AbilityNumber { get => Data[0x15] & 7; set => Data[0x15] = (byte)((Data[0x15] & ~7) | (value & 7)); }
- public override int MarkValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x16)); set => WriteUInt16LittleEndian(Data.AsSpan(0x16), (ushort)value); }
+ public ushort MarkingValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x16)); set => WriteUInt16LittleEndian(Data.AsSpan(0x16), value); }
public override uint PID
{
@@ -423,23 +423,30 @@ public sealed class PK7 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetC
public bool IsUntradedEvent6 => Geo1_Country == 0 && Geo1_Region == 0 && Met_Location / 10000 == 4 && Gen6;
- public override int MarkingCount => 6;
+ public int MarkingCount => 6;
- public override int GetMarking(int index)
+ public MarkingColor GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> (index * 2)) & 3;
+ return (MarkingColor)((MarkingValue >> (index * 2)) & 3);
}
- public override void SetMarking(int index, int value)
+ public void SetMarking(int index, MarkingColor value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
var shift = index * 2;
- MarkValue = (MarkValue & ~(0b11 << shift)) | ((value & 3) << shift);
+ MarkingValue = (ushort)((MarkingValue & ~(0b11 << shift)) | (((byte)value & 3) << shift));
}
+ public MarkingColor MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public MarkingColor MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); }
+ public MarkingColor MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public MarkingColor MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+ public MarkingColor MarkingStar { get => GetMarking(4); set => SetMarking(4, value); }
+ public MarkingColor MarkingDiamond { get => GetMarking(5); set => SetMarking(5, value); }
+
public void FixMemories()
{
if (IsEgg) // No memories if is egg.
diff --git a/PKHeX.Core/PKM/PK9.cs b/PKHeX.Core/PKM/PK9.cs
index 0b908d3d4..78794be86 100644
--- a/PKHeX.Core/PKM/PK9.cs
+++ b/PKHeX.Core/PKM/PK9.cs
@@ -6,7 +6,7 @@ namespace PKHeX.Core;
/// Generation 9 format.
public sealed class PK9 : PKM, ISanityChecksum, ITeraType, ITechRecord, IObedienceLevel,
- IContestStats, IHyperTrain, IScaledSize, IScaledSize3, IFavorite, IHandlerLanguage, IFormArgument, IHomeTrack, IBattleVersion, ITrainerMemories,
+ IContestStats, IHyperTrain, IScaledSize, IScaledSize3, IFavorite, IHandlerLanguage, IFormArgument, IHomeTrack, IBattleVersion, ITrainerMemories, IAppliedMarkings7,
IRibbonIndex, IRibbonSetAffixed, IRibbonSetRibbons, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetMemory6, IRibbonSetCommon7, IRibbonSetCommon8, IRibbonSetCommon9, IRibbonSetMarks, IRibbonSetMark8, IRibbonSetMark9
{
public override ReadOnlySpan ExtraBytes =>
@@ -130,7 +130,7 @@ public sealed class PK9 : PKM, ISanityChecksum, ITeraType, ITechRecord, IObedien
public override int AbilityNumber { get => Data[0x16] & 7; set => Data[0x16] = (byte)((Data[0x16] & ~7) | (value & 7)); }
public bool IsFavorite { get => (Data[0x16] & 8) != 0; set => Data[0x16] = (byte)((Data[0x16] & ~8) | ((value ? 1 : 0) << 3)); } // unused, was in LGPE but not in SWSH
// 0x17 alignment unused
- public override int MarkValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x18)); set => WriteUInt16LittleEndian(Data.AsSpan(0x18), (ushort)value); }
+ public ushort MarkingValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x18)); set => WriteUInt16LittleEndian(Data.AsSpan(0x18), value); }
// 0x1A alignment unused
// 0x1B alignment unused
public override uint PID { get => ReadUInt32LittleEndian(Data.AsSpan(0x1C)); set => WriteUInt32LittleEndian(Data.AsSpan(0x1C), value); }
@@ -512,23 +512,30 @@ public sealed class PK9 : PKM, ISanityChecksum, ITeraType, ITechRecord, IObedien
public override int Stat_SPD { get => ReadUInt16LittleEndian(Data.AsSpan(0x154)); set => WriteUInt16LittleEndian(Data.AsSpan(0x154), (ushort)value); }
#endregion
- public override int MarkingCount => 6;
+ public int MarkingCount => 6;
- public override int GetMarking(int index)
+ public MarkingColor GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> (index * 2)) & 3;
+ return (MarkingColor)((MarkingValue >> (index * 2)) & 3);
}
- public override void SetMarking(int index, int value)
+ public void SetMarking(int index, MarkingColor value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
var shift = index * 2;
- MarkValue = (MarkValue & ~(0b11 << shift)) | ((value & 3) << shift);
+ MarkingValue = (ushort)((MarkingValue & ~(0b11 << shift)) | (((byte)value & 3) << shift));
}
+ public MarkingColor MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public MarkingColor MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); }
+ public MarkingColor MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public MarkingColor MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+ public MarkingColor MarkingStar { get => GetMarking(4); set => SetMarking(4, value); }
+ public MarkingColor MarkingDiamond { get => GetMarking(5); set => SetMarking(5, value); }
+
public bool GetRibbon(int index) => FlagUtil.GetFlag(Data, GetRibbonByte(index), index & 7);
public void SetRibbon(int index, bool value = true) => FlagUtil.SetFlag(Data, GetRibbonByte(index), index & 7, value);
diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs
index 9c0a2359a..094120932 100644
--- a/PKHeX.Core/PKM/PKM.cs
+++ b/PKHeX.Core/PKM/PKM.cs
@@ -131,7 +131,6 @@ public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILa
public abstract uint TSV { get; }
public abstract uint PSV { get; }
public abstract int Characteristic { get; }
- public abstract int MarkValue { get; set; }
public abstract int Met_Location { get; set; }
public abstract int Egg_Location { get; set; }
public abstract int OT_Friendship { get; set; }
@@ -523,10 +522,6 @@ public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILa
}
}
- public abstract int MarkingCount { get; }
- public abstract int GetMarking(int index);
- public abstract void SetMarking(int index, int value);
-
private int HPBitValPower => ((IV_HP & 2) >> 1) | ((IV_ATK & 2) >> 0) | ((IV_DEF & 2) << 1) | ((IV_SPE & 2) << 2) | ((IV_SPA & 2) << 3) | ((IV_SPD & 2) << 4);
public virtual int HPPower => Format < 6 ? ((40 * HPBitValPower) / 63) + 30 : 60;
diff --git a/PKHeX.Core/PKM/RK4.cs b/PKHeX.Core/PKM/RK4.cs
index 3d53b8dfc..af156ecd3 100644
--- a/PKHeX.Core/PKM/RK4.cs
+++ b/PKHeX.Core/PKM/RK4.cs
@@ -46,7 +46,7 @@ public sealed class RK4 : G4PKM
public override uint EXP { get => ReadUInt32LittleEndian(Data.AsSpan(0x10)); set => WriteUInt32LittleEndian(Data.AsSpan(0x10), value); }
public override int OT_Friendship { get => Data[0x14]; set => Data[0x14] = (byte)value; }
public override int Ability { get => Data[0x15]; set => Data[0x15] = (byte)value; }
- public override int MarkValue { get => Data[0x16]; set => Data[0x16] = (byte)value; }
+ public override byte MarkingValue { get => Data[0x16]; set => Data[0x16] = value; }
public override int Language { get => Data[0x17]; set => Data[0x17] = (byte)value; }
public override int EV_HP { get => Data[0x18]; set => Data[0x18] = (byte)value; }
public override int EV_ATK { get => Data[0x19]; set => Data[0x19] = (byte)value; }
diff --git a/PKHeX.Core/PKM/Shared/G3PKM.cs b/PKHeX.Core/PKM/Shared/G3PKM.cs
index b932c58e0..17b12194b 100644
--- a/PKHeX.Core/PKM/Shared/G3PKM.cs
+++ b/PKHeX.Core/PKM/Shared/G3PKM.cs
@@ -6,7 +6,7 @@ namespace PKHeX.Core;
///
/// Generation 3 Base Class
///
-public abstract class G3PKM : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSetUnique3, IRibbonSetOnly3, IRibbonSetRibbons, IContestStats
+public abstract class G3PKM : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSetUnique3, IRibbonSetOnly3, IRibbonSetRibbons, IContestStats, IAppliedMarkings3
{
protected G3PKM(byte[] data) : base(data) { }
protected G3PKM([ConstantExpected] int size) : base(size) { }
@@ -39,22 +39,28 @@ public abstract class G3PKM : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonS
public sealed override int CurrentFriendship { get => OT_Friendship; set => OT_Friendship = value; }
public sealed override int CurrentHandler { get => 0; set { } }
public sealed override int Egg_Location { get => 0; set { } }
- public override int MarkingCount => 4;
+ public int MarkingCount => 4;
+ public abstract byte MarkingValue { get; set; }
- public override int GetMarking(int index)
+ public bool GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> index) & 1;
+ return ((MarkingValue >> index) & 1) != 0;
}
- public override void SetMarking(int index, int value)
+ public void SetMarking(int index, bool value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- MarkValue = (MarkValue & ~(1 << index)) | ((value & 1) << index);
+ MarkingValue = (byte)((MarkingValue & ~(1 << index)) | ((value ? 1 : 0) << index));
}
+ public bool MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public bool MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); } // Purposefully reverse because we swap bits already and want to match Gen4+
+ public bool MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public bool MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+
public abstract ushort SpeciesInternal { get; set; } // raw access
public sealed override byte Form
diff --git a/PKHeX.Core/PKM/Shared/G4PKM.cs b/PKHeX.Core/PKM/Shared/G4PKM.cs
index 0fe354a08..e9ebc7ff5 100644
--- a/PKHeX.Core/PKM/Shared/G4PKM.cs
+++ b/PKHeX.Core/PKM/Shared/G4PKM.cs
@@ -5,7 +5,7 @@ namespace PKHeX.Core;
/// Generation 4 format.
public abstract class G4PKM : PKM,
- IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetUnique3, IRibbonSetUnique4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetRibbons, IContestStats, IGroundTile
+ IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetUnique3, IRibbonSetUnique4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetRibbons, IContestStats, IGroundTile, IAppliedMarkings4
{
protected G4PKM(byte[] data) : base(data) { }
protected G4PKM([ConstantExpected] int size) : base(size) { }
@@ -162,22 +162,30 @@ public abstract class G4PKM : PKM,
public abstract byte BallDPPt { get; set; }
public abstract byte BallHGSS { get; set; }
public abstract byte PokeathlonStat { get; set; }
- public override int MarkingCount => 6;
+ public int MarkingCount => 6;
+ public abstract byte MarkingValue { get; set; }
- public override int GetMarking(int index)
+ public bool GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> index) & 1;
+ return ((MarkingValue >> index) & 1) != 0;
}
- public override void SetMarking(int index, int value)
+ public void SetMarking(int index, bool value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- MarkValue = (MarkValue & ~(1 << index)) | ((value & 1) << index);
+ MarkingValue = (byte)((MarkingValue & ~(1 << index)) | ((value ? 1 : 0) << index));
}
+ public bool MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public bool MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); }
+ public bool MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public bool MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+ public bool MarkingStar { get => GetMarking(4); set => SetMarking(4, value); }
+ public bool MarkingDiamond { get => GetMarking(5); set => SetMarking(5, value); }
+
public abstract ushort Egg_LocationDP { get; set; }
public abstract ushort Egg_LocationExtended { get; set; }
public abstract ushort Met_LocationDP { get; set; }
diff --git a/PKHeX.Core/PKM/Shared/G8PKM.cs b/PKHeX.Core/PKM/Shared/G8PKM.cs
index 429e9c72c..774ee2b09 100644
--- a/PKHeX.Core/PKM/Shared/G8PKM.cs
+++ b/PKHeX.Core/PKM/Shared/G8PKM.cs
@@ -6,7 +6,7 @@ namespace PKHeX.Core;
/// Generation 8 format.
public abstract class G8PKM : PKM, ISanityChecksum,
- ITechRecord, ISociability, IContestStats, IHyperTrain, IScaledSize, IGigantamax, IFavorite, IDynamaxLevel, IHandlerLanguage, IFormArgument, IHomeTrack, IBattleVersion, ITrainerMemories, IPokerusStatus,
+ ITechRecord, ISociability, IContestStats, IHyperTrain, IScaledSize, IGigantamax, IFavorite, IDynamaxLevel, IHandlerLanguage, IFormArgument, IHomeTrack, IBattleVersion, ITrainerMemories, IPokerusStatus, IAppliedMarkings7,
IRibbonIndex, IRibbonSetAffixed, IRibbonSetRibbons, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetMemory6, IRibbonSetCommon7, IRibbonSetCommon8, IRibbonSetCommon9, IRibbonSetMarks, IRibbonSetMark8, IRibbonSetMark9
{
protected G8PKM() : base(PokeCrypto.SIZE_8PARTY) { }
@@ -104,7 +104,7 @@ public abstract class G8PKM : PKM, ISanityChecksum,
public bool IsFavorite { get => (Data[0x16] & 8) != 0; set => Data[0x16] = (byte)((Data[0x16] & ~8) | ((value ? 1 : 0) << 3)); } // unused, was in LGP/E but not in SW/SH
public bool CanGigantamax { get => (Data[0x16] & 16) != 0; set => Data[0x16] = (byte)((Data[0x16] & ~16) | (value ? 16 : 0)); }
// 0x17 alignment unused
- public override int MarkValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x18)); set => WriteUInt16LittleEndian(Data.AsSpan(0x18), (ushort)value); }
+ public ushort MarkingValue { get => ReadUInt16LittleEndian(Data.AsSpan(0x18)); set => WriteUInt16LittleEndian(Data.AsSpan(0x18), value); }
// 0x1A alignment unused
// 0x1B alignment unused
public override uint PID { get => ReadUInt32LittleEndian(Data.AsSpan(0x1C)); set => WriteUInt32LittleEndian(Data.AsSpan(0x1C), value); }
@@ -454,23 +454,30 @@ public abstract class G8PKM : PKM, ISanityChecksum,
public override int Stat_SPD { get => ReadUInt16LittleEndian(Data.AsSpan(0x154)); set => WriteUInt16LittleEndian(Data.AsSpan(0x154), (ushort)value); }
#endregion
- public override int MarkingCount => 6;
+ public int MarkingCount => 6;
- public override int GetMarking(int index)
+ public MarkingColor GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
- return (MarkValue >> (index * 2)) & 3;
+ return (MarkingColor)((MarkingValue >> (index * 2)) & 3);
}
- public override void SetMarking(int index, int value)
+ public void SetMarking(int index, MarkingColor value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
var shift = index * 2;
- MarkValue = (MarkValue & ~(0b11 << shift)) | ((value & 3) << shift);
+ MarkingValue = (ushort)((MarkingValue & ~(0b11 << shift)) | (((byte)value & 3) << shift));
}
+ public MarkingColor MarkingCircle { get => GetMarking(0); set => SetMarking(0, value); }
+ public MarkingColor MarkingTriangle { get => GetMarking(1); set => SetMarking(1, value); }
+ public MarkingColor MarkingSquare { get => GetMarking(2); set => SetMarking(2, value); }
+ public MarkingColor MarkingHeart { get => GetMarking(3); set => SetMarking(3, value); }
+ public MarkingColor MarkingStar { get => GetMarking(4); set => SetMarking(4, value); }
+ public MarkingColor MarkingDiamond { get => GetMarking(5); set => SetMarking(5, value); }
+
public bool GetRibbon(int index) => FlagUtil.GetFlag(Data, GetRibbonByte(index), index & 7);
public void SetRibbon(int index, bool value = true) => FlagUtil.SetFlag(Data, GetRibbonByte(index), index & 7, value);
diff --git a/PKHeX.Core/PKM/Shared/GBPKM.cs b/PKHeX.Core/PKM/Shared/GBPKM.cs
index 0744392f0..c14f77b0c 100644
--- a/PKHeX.Core/PKM/Shared/GBPKM.cs
+++ b/PKHeX.Core/PKM/Shared/GBPKM.cs
@@ -120,7 +120,6 @@ public abstract class GBPKM : PKM
public sealed override uint TSV => 0x0000;
public sealed override uint PSV => 0xFFFF;
public sealed override int Characteristic => -1;
- public sealed override int MarkValue { get => 0; set { } }
public sealed override int Ability { get => -1; set { } }
public sealed override int CurrentHandler { get => 0; set { } }
public sealed override int Egg_Location { get => 0; set { } }
@@ -181,9 +180,6 @@ public abstract class GBPKM : PKM
public int IV_SPC { get => (DV16 >> 0) & 0xF; set => DV16 = (ushort)((DV16 & ~(0xF << 0)) | (ushort)((value > 0xF ? 0xF : value) << 0)); }
public sealed override int IV_SPA { get => IV_SPC; set => IV_SPC = value; }
public sealed override int IV_SPD { get => IV_SPC; set { } }
- public override int MarkingCount => 0;
- public override int GetMarking(int index) => 0;
- public override void SetMarking(int index, int value) { }
public void SetNotNicknamed() => SetNotNicknamed(GuessedLanguage());
public abstract void SetNotNicknamed(int language);
diff --git a/PKHeX.Core/PKM/XK3.cs b/PKHeX.Core/PKM/XK3.cs
index 2884b6adb..e4251ace6 100644
--- a/PKHeX.Core/PKM/XK3.cs
+++ b/PKHeX.Core/PKM/XK3.cs
@@ -44,7 +44,7 @@ public sealed class XK3 : G3PKM, IShadowCapture
public override int Stat_Level { get => Data[0x11]; set => Data[0x11] = (byte)value; }
public override byte CNT_Sheen { get => Data[0x12]; set => Data[0x12] = value; }
public override int PKRS_Strain { get => Data[0x13] & 0xF; set => Data[0x13] = (byte)(value & 0xF); }
- public override int MarkValue { get => SwapBits(Data[0x14], 1, 2); set => Data[0x14] = (byte)SwapBits(value, 1, 2); }
+ public override byte MarkingValue { get => (byte)SwapBits(Data[0x14], 1, 2); set => Data[0x14] = (byte)SwapBits(value, 1, 2); }
public override int PKRS_Days { get => Math.Max((sbyte)Data[0x15], (sbyte)0); set => Data[0x15] = (byte)(value == 0 ? 0xFF : value & 0xF); }
// 0x16-0x1C Battle Related
private int XDPKMFLAGS { get => Data[0x1D]; set => Data[0x1D] = (byte)value; }
diff --git a/PKHeX.WinForms/Controls/PKM Editor/DrawConfig.cs b/PKHeX.WinForms/Controls/PKM Editor/DrawConfig.cs
index 21a8422bf..a92c28dd6 100644
--- a/PKHeX.WinForms/Controls/PKM Editor/DrawConfig.cs
+++ b/PKHeX.WinForms/Controls/PKM Editor/DrawConfig.cs
@@ -80,12 +80,12 @@ public sealed class DrawConfig : IDisposable
_ => TextColor,
};
- public bool GetMarkingColor(int markval, out Color c)
+ public bool GetMarkingColor(MarkingColor markval, out Color c)
{
switch (markval)
{
- case 1: c = MarkBlue; return true;
- case 2: c = MarkPink; return true;
+ case MarkingColor.Blue: c = MarkBlue; return true;
+ case MarkingColor.Pink: c = MarkPink; return true;
default: c = MarkDefault; return false; // recolor not required
}
}
diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
index 8121178b2..516545ae9 100644
--- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
+++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
@@ -496,27 +496,30 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
private void SetMarkings()
{
- var pba = Markings;
- var count = Entity.MarkingCount;
- for (int i = 0; i < pba.Length; i++)
- pba[i].Image = GetMarkSprite(pba[i], i < count && Entity.GetMarking(i) != 0);
-
PB_MarkShiny.Image = GetMarkSprite(PB_MarkShiny, !BTN_Shinytize.Enabled);
PB_MarkCured.Image = GetMarkSprite(PB_MarkCured, CHK_Cured.Checked);
PB_Favorite.Image = GetMarkSprite(PB_Favorite, Entity is IFavorite { IsFavorite: true });
PB_Origin.Image = GetOriginSprite(Entity);
- // Colored Markings
- if (Entity.Format < 7)
- return;
-
- for (int i = 0; i < count; i++)
+ var pba = Markings;
+ if (Entity is IAppliedMarkings b)
{
- if (!Draw.GetMarkingColor(Entity.GetMarking(i), out Color c))
- continue;
- var pb = pba[i];
- pb.Image = ImageUtil.ChangeAllColorTo(pb.Image, c);
+ for (int i = 0; i < b.MarkingCount; i++)
+ pba[i].Image = GetMarkSprite(pba[i], b.GetMarking(i));
+ }
+ else if (Entity is IAppliedMarkings c)
+ {
+ for (int i = 0; i < pba.Length; i++)
+ {
+ var pb = pba[i];
+ var state = c.GetMarking(i);
+ var opaque = Draw.GetMarkingColor(state, out var color);
+ var img = GetMarkSprite(pb, opaque);
+ if (opaque)
+ img = ImageUtil.ChangeAllColorTo(img, color);
+ pb.Image = img;
+ }
}
}