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.
This commit is contained in:
Kurt 2023-11-01 19:19:50 -07:00
parent be574948db
commit e0cf4447ff
11 changed files with 100 additions and 12 deletions

View file

@ -6,7 +6,7 @@ namespace PKHeX.Core;
/// Generation 9 Static Encounter /// Generation 9 Static Encounter
/// </summary> /// </summary>
public sealed record EncounterStatic9(GameVersion Version) public sealed record EncounterStatic9(GameVersion Version)
: IEncounterable, IEncounterMatch, IEncounterConvertible<PK9>, IMoveset, IFlawlessIVCount, IFixedIVSet, IGemType, IFixedGender, IFixedNature : IEncounterable, IEncounterMatch, IEncounterConvertible<PK9>, IMoveset, IFlawlessIVCount, IFixedIVSet, IGemType, IFixedGender, IFixedNature, IEncounterMarkExtra
{ {
public int Generation => 9; public int Generation => 9;
public EntityContext Context => EntityContext.Gen9; public EntityContext Context => EntityContext.Gen9;
@ -32,6 +32,19 @@ public sealed record EncounterStatic9(GameVersion Version)
public byte Size { get; init; } public byte Size { get; init; }
public bool IsTitan { get; init; } public bool IsTitan { get; init; }
public bool RibbonMarkCrafty => Species == (int)Core.Species.Munchlax; // Shiny etc 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; private bool Gift => FixedBall != Ball.None;

View file

@ -23,11 +23,9 @@ public sealed class MarkVerifier : Verifier
VerifyAffixedRibbonMark(data, m); VerifyAffixedRibbonMark(data, m);
// temp logic to catch this case; in the future we will need more robust checks for encounters // Some encounters come with a fixed Mark, and we've not yet checked if it's missing.
if (data.EncounterMatch is WC9 { RibbonMarkCharismatic: true } && pk is IRibbonSetMark8 { RibbonMarkCharismatic: false }) if (data.EncounterMatch is IEncounterMarkExtra extra && extra.IsMissingExtraMark(pk, out var missing))
data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(MarkCharismatic)))); data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(missing))));
else if (data.EncounterMatch is EncounterStatic9 { RibbonMarkCrafty: true } && pk is IRibbonSetMark8 { RibbonMarkCrafty: false })
data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(MarkCrafty))));
} }
private void VerifyNoMarksPresent(LegalityAnalysis data, IRibbonIndex m) private void VerifyNoMarksPresent(LegalityAnalysis data, IRibbonIndex m)

View file

@ -255,3 +255,24 @@ public static class MarkRules
return unchecked((RibbonIndex)(-1)); return unchecked((RibbonIndex)(-1));
} }
} }
/// <summary>
/// Indicates if the encounter is lacking a specific mark.
/// </summary>
/// <remarks>
/// Some encounters are made available with a specific mark, and the mark is required to be present.
/// </remarks>
public interface IEncounterMarkExtra
{
/// <summary>
/// Checks if the encounter is missing a specific mark.
/// </summary>
/// <param name="pk">The encounter to check.</param>
/// <param name="missing">The missing mark.</param>
/// <returns>True if the encounter is missing the mark.</returns>
/// <remarks>
/// If the encounter is missing the mark, the <paramref name="missing"/> value will be set to the missing mark.
/// </remarks>
bool IsMissingExtraMark(PKM pk, out RibbonIndex missing);
}

View file

@ -8,7 +8,7 @@ namespace PKHeX.Core;
/// Generation 9 Mystery Gift Template File /// Generation 9 Mystery Gift Template File
/// </summary> /// </summary>
public sealed class WC9 : DataMysteryGift, ILangNick, INature, ITeraType, IRibbonIndex, IMemoryOT, ILangNicknamedTemplate, IEncounterServerDate, 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 Size = 0x2C8;
public const int CardStart = 0x0; public const int CardStart = 0x0;
@ -227,8 +227,6 @@ public sealed class WC9 : DataMysteryGift, ILangNick, INature, ITeraType, IRibbo
{ {
foreach (var value in RibbonSpan) foreach (var value in RibbonSpan)
{ {
if (value == RibbonByteNone)
return false; // end
if (((RibbonIndex)value).IsEncounterMark8()) if (((RibbonIndex)value).IsEncounterMark8())
return true; return true;
} }
@ -242,8 +240,6 @@ public sealed class WC9 : DataMysteryGift, ILangNick, INature, ITeraType, IRibbo
{ {
foreach (var value in RibbonSpan) foreach (var value in RibbonSpan)
{ {
if (value == RibbonByteNone)
return false; // end
if (((RibbonIndex)value).IsEncounterMark9()) if (((RibbonIndex)value).IsEncounterMark9())
return true; return true;
} }
@ -933,4 +929,18 @@ public sealed class WC9 : DataMysteryGift, ILangNick, INature, ITeraType, IRibbo
} }
} }
#endregion #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;
}
} }

View file

@ -1,3 +1,5 @@
using System;
namespace PKHeX.Core; namespace PKHeX.Core;
/// <summary> Marks introduced in Generation 8 </summary> /// <summary> Marks introduced in Generation 8 </summary>
@ -119,4 +121,48 @@ public static partial class RibbonExtensions
dest.RibbonMarkVigor = set.RibbonMarkVigor; dest.RibbonMarkVigor = set.RibbonMarkVigor;
dest.RibbonMarkSlump = set.RibbonMarkSlump; 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)
};
} }

View file

@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace PKHeX.Core; namespace PKHeX.Core;
/// <summary> /// <summary>
/// Provides ribbon information about the state of a given ribbon. /// Provides information about the state of a given ribbon.
/// </summary> /// </summary>
public sealed class RibbonInfo public sealed class RibbonInfo
{ {