From e0cf4447ffbef41c30a7cdda79631b7d8040b5ca Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 1 Nov 2023 19:19:50 -0700 Subject: [PATCH] Explicitly handle mark8 presence (wc9/static9) Move some files around WC9 fidough gift sets Classic AND Uncommon, and it doesn't set the lowest ribbon indexes. Nice GUI. --- .../Templates/Gen9/EncounterStatic9.cs | 15 +++++- PKHeX.Core/Legality/Verifiers/MarkVerifier.cs | 8 ++-- .../Legality/Verifiers/Ribbons/MarkRules.cs | 21 +++++++++ PKHeX.Core/MysteryGifts/WC9.cs | 20 ++++++-- PKHeX.Core/Ribbons/IRibbonSetMark8.cs | 46 +++++++++++++++++++ .../Ribbons/{ => Past}/IRibbonSetOnly3.cs | 0 .../Ribbons/{ => Past}/IRibbonSetUnique3.cs | 0 .../Ribbons/{ => Past}/IRibbonSetUnique4.cs | 0 .../Ribbons => Ribbons/Past}/RibbonIndex3.cs | 0 .../Ribbons => Ribbons/Past}/RibbonIndex4.cs | 0 PKHeX.Core/Ribbons/RibbonInfo.cs | 2 +- 11 files changed, 100 insertions(+), 12 deletions(-) rename PKHeX.Core/Ribbons/{ => Past}/IRibbonSetOnly3.cs (100%) rename PKHeX.Core/Ribbons/{ => Past}/IRibbonSetUnique3.cs (100%) rename PKHeX.Core/Ribbons/{ => Past}/IRibbonSetUnique4.cs (100%) rename PKHeX.Core/{Legality/Verifiers/Ribbons => Ribbons/Past}/RibbonIndex3.cs (100%) rename PKHeX.Core/{Legality/Verifiers/Ribbons => Ribbons/Past}/RibbonIndex4.cs (100%) diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen9/EncounterStatic9.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen9/EncounterStatic9.cs index 22baae1e2..c860fe98c 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen9/EncounterStatic9.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen9/EncounterStatic9.cs @@ -6,7 +6,7 @@ namespace PKHeX.Core; /// Generation 9 Static Encounter /// public sealed record EncounterStatic9(GameVersion Version) - : IEncounterable, IEncounterMatch, IEncounterConvertible, IMoveset, IFlawlessIVCount, IFixedIVSet, IGemType, IFixedGender, IFixedNature + : IEncounterable, IEncounterMatch, IEncounterConvertible, IMoveset, IFlawlessIVCount, IFixedIVSet, IGemType, IFixedGender, IFixedNature, IEncounterMarkExtra { public int Generation => 9; public EntityContext Context => EntityContext.Gen9; @@ -32,6 +32,19 @@ public sealed record EncounterStatic9(GameVersion Version) public byte Size { get; init; } public bool IsTitan { get; init; } public bool RibbonMarkCrafty => Species == (int)Core.Species.Munchlax; // Shiny etc + public bool IsMissingExtraMark(PKM pk, out RibbonIndex index) + { + if (RibbonMarkCrafty) + { + if (pk is IRibbonSetMark8 m8 && !m8.HasMark8(RibbonIndex.MarkCrafty)) + { + index = RibbonIndex.MarkCrafty; + return true; + } + } + index = default; + return false; + } private bool Gift => FixedBall != Ball.None; diff --git a/PKHeX.Core/Legality/Verifiers/MarkVerifier.cs b/PKHeX.Core/Legality/Verifiers/MarkVerifier.cs index fba0d6709..eb62c85af 100644 --- a/PKHeX.Core/Legality/Verifiers/MarkVerifier.cs +++ b/PKHeX.Core/Legality/Verifiers/MarkVerifier.cs @@ -23,11 +23,9 @@ public override void Verify(LegalityAnalysis data) VerifyAffixedRibbonMark(data, m); - // temp logic to catch this case; in the future we will need more robust checks for encounters - if (data.EncounterMatch is WC9 { RibbonMarkCharismatic: true } && pk is IRibbonSetMark8 { RibbonMarkCharismatic: false }) - data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(MarkCharismatic)))); - else if (data.EncounterMatch is EncounterStatic9 { RibbonMarkCrafty: true } && pk is IRibbonSetMark8 { RibbonMarkCrafty: false }) - data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(MarkCrafty)))); + // Some encounters come with a fixed Mark, and we've not yet checked if it's missing. + if (data.EncounterMatch is IEncounterMarkExtra extra && extra.IsMissingExtraMark(pk, out var missing)) + data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(missing)))); } private void VerifyNoMarksPresent(LegalityAnalysis data, IRibbonIndex m) diff --git a/PKHeX.Core/Legality/Verifiers/Ribbons/MarkRules.cs b/PKHeX.Core/Legality/Verifiers/Ribbons/MarkRules.cs index c1b119160..983dbbded 100644 --- a/PKHeX.Core/Legality/Verifiers/Ribbons/MarkRules.cs +++ b/PKHeX.Core/Legality/Verifiers/Ribbons/MarkRules.cs @@ -255,3 +255,24 @@ public static RibbonIndex GetMaxAffixValue(EvolutionHistory evos) return unchecked((RibbonIndex)(-1)); } } + +/// +/// Indicates if the encounter is lacking a specific mark. +/// +/// +/// Some encounters are made available with a specific mark, and the mark is required to be present. +/// +public interface IEncounterMarkExtra +{ + /// + /// Checks if the encounter is missing a specific mark. + /// + /// The encounter to check. + /// The missing mark. + /// True if the encounter is missing the mark. + /// + /// If the encounter is missing the mark, the value will be set to the missing mark. + /// + bool IsMissingExtraMark(PKM pk, out RibbonIndex missing); +} + diff --git a/PKHeX.Core/MysteryGifts/WC9.cs b/PKHeX.Core/MysteryGifts/WC9.cs index e3bed2391..75507f250 100644 --- a/PKHeX.Core/MysteryGifts/WC9.cs +++ b/PKHeX.Core/MysteryGifts/WC9.cs @@ -8,7 +8,7 @@ namespace PKHeX.Core; /// Generation 9 Mystery Gift Template File /// public sealed class WC9 : DataMysteryGift, ILangNick, INature, ITeraType, IRibbonIndex, IMemoryOT, ILangNicknamedTemplate, IEncounterServerDate, - IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetCommon7, IRibbonSetCommon8, IRibbonSetMark8, IRibbonSetCommon9, IRibbonSetMark9 + IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetCommon7, IRibbonSetCommon8, IRibbonSetMark8, IRibbonSetCommon9, IRibbonSetMark9, IEncounterMarkExtra { public const int Size = 0x2C8; public const int CardStart = 0x0; @@ -227,8 +227,6 @@ public bool HasMarkEncounter8 { foreach (var value in RibbonSpan) { - if (value == RibbonByteNone) - return false; // end if (((RibbonIndex)value).IsEncounterMark8()) return true; } @@ -242,8 +240,6 @@ public bool HasMarkEncounter9 { foreach (var value in RibbonSpan) { - if (value == RibbonByteNone) - return false; // end if (((RibbonIndex)value).IsEncounterMark9()) return true; } @@ -933,4 +929,18 @@ public void SetRibbon(int index, bool value = true) } } #endregion + + public bool IsMissingExtraMark(PKM pk, out RibbonIndex missing) + { + foreach (var value in RibbonSpan) + { + missing = (RibbonIndex)value; + if (!missing.IsEncounterMark8()) + continue; + if (pk is IRibbonSetMark8 m8 && !m8.HasMark8(missing)) + return true; + } + missing = default; + return false; + } } diff --git a/PKHeX.Core/Ribbons/IRibbonSetMark8.cs b/PKHeX.Core/Ribbons/IRibbonSetMark8.cs index 151f5918d..42fb57368 100644 --- a/PKHeX.Core/Ribbons/IRibbonSetMark8.cs +++ b/PKHeX.Core/Ribbons/IRibbonSetMark8.cs @@ -1,3 +1,5 @@ +using System; + namespace PKHeX.Core; /// Marks introduced in Generation 8 @@ -119,4 +121,48 @@ public static void CopyRibbonSetMark8(this IRibbonSetMark8 set, IRibbonSetMark8 dest.RibbonMarkVigor = set.RibbonMarkVigor; dest.RibbonMarkSlump = set.RibbonMarkSlump; } + + public static bool HasMark8(this IRibbonSetMark8 set, RibbonIndex index) => index switch + { + RibbonIndex.MarkLunchtime => set.RibbonMarkLunchtime, + RibbonIndex.MarkSleepyTime => set.RibbonMarkSleepyTime, + RibbonIndex.MarkDusk => set.RibbonMarkDusk, + RibbonIndex.MarkDawn => set.RibbonMarkDawn, + RibbonIndex.MarkCloudy => set.RibbonMarkCloudy, + RibbonIndex.MarkRainy => set.RibbonMarkRainy, + RibbonIndex.MarkStormy => set.RibbonMarkStormy, + RibbonIndex.MarkSnowy => set.RibbonMarkSnowy, + RibbonIndex.MarkBlizzard => set.RibbonMarkBlizzard, + RibbonIndex.MarkDry => set.RibbonMarkDry, + RibbonIndex.MarkSandstorm => set.RibbonMarkSandstorm, + RibbonIndex.MarkMisty => set.RibbonMarkMisty, + RibbonIndex.MarkDestiny => set.RibbonMarkDestiny, + RibbonIndex.MarkFishing => set.RibbonMarkFishing, + RibbonIndex.MarkCurry => set.RibbonMarkCurry, + RibbonIndex.MarkUncommon => set.RibbonMarkUncommon, + RibbonIndex.MarkRare => set.RibbonMarkRare, + RibbonIndex.MarkRowdy => set.RibbonMarkRowdy, + RibbonIndex.MarkAbsentMinded => set.RibbonMarkAbsentMinded, + RibbonIndex.MarkJittery => set.RibbonMarkJittery, + RibbonIndex.MarkExcited => set.RibbonMarkExcited, + RibbonIndex.MarkCharismatic => set.RibbonMarkCharismatic, + RibbonIndex.MarkCalmness => set.RibbonMarkCalmness, + RibbonIndex.MarkIntense => set.RibbonMarkIntense, + RibbonIndex.MarkZonedOut => set.RibbonMarkZonedOut, + RibbonIndex.MarkJoyful => set.RibbonMarkJoyful, + RibbonIndex.MarkAngry => set.RibbonMarkAngry, + RibbonIndex.MarkSmiley => set.RibbonMarkSmiley, + RibbonIndex.MarkTeary => set.RibbonMarkTeary, + RibbonIndex.MarkUpbeat => set.RibbonMarkUpbeat, + RibbonIndex.MarkPeeved => set.RibbonMarkPeeved, + RibbonIndex.MarkIntellectual => set.RibbonMarkIntellectual, + RibbonIndex.MarkFerocious => set.RibbonMarkFerocious, + RibbonIndex.MarkCrafty => set.RibbonMarkCrafty, + RibbonIndex.MarkScowling => set.RibbonMarkScowling, + RibbonIndex.MarkKindly => set.RibbonMarkKindly, + RibbonIndex.MarkFlustered => set.RibbonMarkFlustered, + RibbonIndex.MarkPumpedUp => set.RibbonMarkPumpedUp, + RibbonIndex.MarkZeroEnergy => set.RibbonMarkZeroEnergy, + _ => throw new ArgumentOutOfRangeException(nameof(index), index, null) + }; } diff --git a/PKHeX.Core/Ribbons/IRibbonSetOnly3.cs b/PKHeX.Core/Ribbons/Past/IRibbonSetOnly3.cs similarity index 100% rename from PKHeX.Core/Ribbons/IRibbonSetOnly3.cs rename to PKHeX.Core/Ribbons/Past/IRibbonSetOnly3.cs diff --git a/PKHeX.Core/Ribbons/IRibbonSetUnique3.cs b/PKHeX.Core/Ribbons/Past/IRibbonSetUnique3.cs similarity index 100% rename from PKHeX.Core/Ribbons/IRibbonSetUnique3.cs rename to PKHeX.Core/Ribbons/Past/IRibbonSetUnique3.cs diff --git a/PKHeX.Core/Ribbons/IRibbonSetUnique4.cs b/PKHeX.Core/Ribbons/Past/IRibbonSetUnique4.cs similarity index 100% rename from PKHeX.Core/Ribbons/IRibbonSetUnique4.cs rename to PKHeX.Core/Ribbons/Past/IRibbonSetUnique4.cs diff --git a/PKHeX.Core/Legality/Verifiers/Ribbons/RibbonIndex3.cs b/PKHeX.Core/Ribbons/Past/RibbonIndex3.cs similarity index 100% rename from PKHeX.Core/Legality/Verifiers/Ribbons/RibbonIndex3.cs rename to PKHeX.Core/Ribbons/Past/RibbonIndex3.cs diff --git a/PKHeX.Core/Legality/Verifiers/Ribbons/RibbonIndex4.cs b/PKHeX.Core/Ribbons/Past/RibbonIndex4.cs similarity index 100% rename from PKHeX.Core/Legality/Verifiers/Ribbons/RibbonIndex4.cs rename to PKHeX.Core/Ribbons/Past/RibbonIndex4.cs diff --git a/PKHeX.Core/Ribbons/RibbonInfo.cs b/PKHeX.Core/Ribbons/RibbonInfo.cs index c06b98b33..6a727fb8c 100644 --- a/PKHeX.Core/Ribbons/RibbonInfo.cs +++ b/PKHeX.Core/Ribbons/RibbonInfo.cs @@ -4,7 +4,7 @@ namespace PKHeX.Core; /// -/// Provides ribbon information about the state of a given ribbon. +/// Provides information about the state of a given ribbon. /// public sealed class RibbonInfo {