Add server date checks for WA8 gifts

This commit is contained in:
Kurt 2022-05-02 18:52:43 -07:00
parent 41578132cf
commit 5132f961cc
6 changed files with 95 additions and 42 deletions

View file

@ -7,6 +7,9 @@ namespace PKHeX.Core;
public sealed class LegalMoveInfo
{
private int LearnCount;
// Use a bool array instead of a HashSet; we have a limited range of moves.
// This implementation is faster (no hashcode or bucket search) with lower memory overhead (1 byte per move ID).
private readonly bool[] AllowedMoves = new bool[(int)Move.MAX_COUNT];
/// <summary>

View file

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using static PKHeX.Core.EncounterServerDateCheck;
namespace PKHeX.Core;
public interface IEncounterServerDate
{
bool IsDateRestricted { get; }
}
public enum EncounterServerDateCheck
{
None,
Valid,
Invalid,
}
public static class EncounterServerDate
{
private static bool IsValidDate(DateTime obtained, DateTime start) => obtained >= start && obtained <= DateTime.UtcNow;
private static bool IsValidDate(DateTime obtained, DateTime start, DateTime end) => obtained >= start && obtained <= end;
//private static bool IsValidDate(DateTime obtained, (DateTime Start, DateTime? End) value)
//{
// var (start, end) = value;
// if (end is not { } x)
// return IsValidDate(obtained, start);
// return IsValidDate(obtained, start, x);
//}
private static bool IsValidDate(DateTime obtained, (DateTime Start, DateTime End) value)
{
var (start, end) = value;
return IsValidDate(obtained, start, end);
}
private static EncounterServerDateCheck Result(bool result) => result ? Valid : Invalid;
public static EncounterServerDateCheck IsValidDate(this IEncounterServerDate enc, DateTime obtained) => enc switch
{
WC8 wc8 => Result(IsValidDateWC8(wc8.CardID, obtained)),
WA8 wa8 => Result(IsValidDateWA8(wa8.CardID, obtained)),
_ => throw new ArgumentOutOfRangeException(nameof(enc)),
};
public static bool IsValidDateWC8(int cardID, DateTime obtained) => WC8Gifts.TryGetValue(cardID, out var time) && IsValidDate(obtained, time);
public static bool IsValidDateWA8(int cardID, DateTime obtained) => WA8Gifts.TryGetValue(cardID, out var time) && IsValidDate(obtained, time);
/// <summary>
/// Minimum date the gift can be received.
/// </summary>
public static readonly Dictionary<int, DateTime> WC8Gifts = new()
{
{9000, new DateTime(2020, 02, 12)}, // Bulbasaur
{9001, new DateTime(2020, 02, 12)}, // Charmander
{9002, new DateTime(2020, 02, 12)}, // Squirtle
{9003, new DateTime(2020, 02, 12)}, // Pikachu
{9004, new DateTime(2020, 02, 15)}, // Original Color Magearna
{9005, new DateTime(2020, 02, 12)}, // Eevee
{9006, new DateTime(2020, 02, 12)}, // Rotom
{9007, new DateTime(2020, 02, 12)}, // Pichu
{9008, new DateTime(2020, 06, 02)}, // Hidden Ability Grookey
{9009, new DateTime(2020, 06, 02)}, // Hidden Ability Scorbunny
{9010, new DateTime(2020, 06, 02)}, // Hidden Ability Sobble
{9011, new DateTime(2020, 06, 30)}, // Shiny Zeraora
{9012, new DateTime(2020, 11, 10)}, // Gigantamax Melmetal
{9013, new DateTime(2021, 06, 17)}, // Gigantamax Bulbasaur
{9014, new DateTime(2021, 06, 17)}, // Gigantamax Squirtle
};
/// <summary>
/// Minimum date the gift can be received.
/// </summary>
public static readonly Dictionary<int, (DateTime Start, DateTime End)> WA8Gifts = new()
{
{0138, (new(2022, 01, 27), new(2022, 11, 01))}, // Poké Center Happiny
{0301, (new(2022, 02, 12), new(2022, 02, 24))}, // プロポチャ Piplup
{0801, (new(2022, 02, 25), new(2022, 06, 01))}, // Teresa Roca Hisuian Growlithe
};
}

View file

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
namespace PKHeX.Core
{
public static class EncountersHOME
{
public static bool IsValidDateWC8(int cardID, DateTime obtained) => WC8Gifts.TryGetValue(cardID, out var time) && obtained >= time && obtained <= DateTime.UtcNow;
/// <summary>
/// Minimum date the gift can be received.
/// </summary>
public static readonly Dictionary<int, DateTime> WC8Gifts = new()
{
{9000, new DateTime(2020, 02, 12)}, // Bulbasaur
{9001, new DateTime(2020, 02, 12)}, // Charmander
{9002, new DateTime(2020, 02, 12)}, // Squirtle
{9003, new DateTime(2020, 02, 12)}, // Pikachu
{9004, new DateTime(2020, 02, 15)}, // Original Color Magearna
{9005, new DateTime(2020, 02, 12)}, // Eevee
{9006, new DateTime(2020, 02, 12)}, // Rotom
{9007, new DateTime(2020, 02, 12)}, // Pichu
{9008, new DateTime(2020, 06, 02)}, // Hidden Ability Grookey
{9009, new DateTime(2020, 06, 02)}, // Hidden Ability Scorbunny
{9010, new DateTime(2020, 06, 02)}, // Hidden Ability Sobble
{9011, new DateTime(2020, 06, 30)}, // Shiny Zeraora
{9012, new DateTime(2020, 11, 10)}, // Gigantamax Melmetal
{9013, new DateTime(2021, 06, 17)}, // Gigantamax Bulbasaur
{9014, new DateTime(2021, 06, 17)}, // Gigantamax Squirtle
};
}
}

View file

@ -70,10 +70,11 @@ namespace PKHeX.Core
VerifyFullness(data, pkm);
var enc = data.EncounterMatch;
if (enc is WC8 { IsHOMEGift: true } w)
if (enc is IEncounterServerDate { IsDateRestricted: true } serverGift)
{
var date = new DateTime(pkm.Met_Year + 2000, pkm.Met_Month, pkm.Met_Day);
if (!EncountersHOME.IsValidDateWC8(w.CardID, date))
var result = serverGift.IsValidDate(date);
if (result == EncounterServerDateCheck.Invalid)
data.AddLine(GetInvalid(LDateOutsideDistributionWindow));
}
else if (enc is IOverworldCorrelation8 z)

View file

@ -8,7 +8,8 @@ namespace PKHeX.Core
/// <summary>
/// Generation 8 Mystery Gift Template File, same as <see cref="WC8"/> with <see cref="IGanbaru"/> fields at the end.
/// </summary>
public sealed class WA8 : DataMysteryGift, ILangNick, INature, IGigantamax, IDynamaxLevel, IRibbonIndex, IMemoryOT, ILangNicknamedTemplate, IGanbaru, IAlpha,
public sealed class WA8 : DataMysteryGift, ILangNick, INature, IGigantamax, IDynamaxLevel, IRibbonIndex, IMemoryOT, IEncounterServerDate,
ILangNicknamedTemplate, IGanbaru, IAlpha,
IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetCommon7, IRibbonSetCommon8, IRibbonSetMark8
{
public const int Size = 0x2C8;
@ -26,6 +27,7 @@ namespace PKHeX.Core
public WA8(byte[] data) : base(data) { }
public bool CanBeReceivedByVersion(int v) => v is (int) GameVersion.PLA;
public bool IsDateRestricted => true;
// General Card Properties
public override int CardID
@ -456,11 +458,7 @@ namespace PKHeX.Core
pk.SID = sav.SID;
}
// Official code explicitly corrects for Meowstic
if (pk.Species == (int)Core.Species.Meowstic)
pk.Form = pk.Gender;
pk.MetDate = DateTime.Now;
pk.MetDate = IsDateRestricted && EncounterServerDate.WA8Gifts.TryGetValue(CardID, out var dt) ? dt.Start : DateTime.Now;
var nickname_language = GetLanguage(language);
pk.Language = nickname_language != 0 ? nickname_language : sav.Language;

View file

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// <summary>
/// Generation 8 Mystery Gift Template File
/// </summary>
public sealed class WC8 : DataMysteryGift, ILangNick, INature, IGigantamax, IDynamaxLevel, IRibbonIndex, IMemoryOT, ILangNicknamedTemplate,
public sealed class WC8 : DataMysteryGift, ILangNick, INature, IGigantamax, IDynamaxLevel, IRibbonIndex, IMemoryOT, ILangNicknamedTemplate, IEncounterServerDate,
IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetCommon7, IRibbonSetCommon8, IRibbonSetMark8
{
public const int Size = 0x2D0;
@ -461,7 +461,7 @@ namespace PKHeX.Core
if (pk.Species == (int)Core.Species.Meowstic)
pk.Form = pk.Gender;
pk.MetDate = IsHOMEGift && EncountersHOME.WC8Gifts.TryGetValue(CardID, out var dt) ? dt : DateTime.Now;
pk.MetDate = IsDateRestricted && EncounterServerDate.WC8Gifts.TryGetValue(CardID, out var dt) ? dt : DateTime.Now;
var nickname_language = GetLanguage(language);
pk.Language = nickname_language != 0 ? nickname_language : sav.Language;
@ -692,6 +692,8 @@ namespace PKHeX.Core
return TID == 0 && SID == 0 && PID != 0;
}
public bool IsDateRestricted => IsHOMEGift;
protected override bool IsMatchDeferred(PKM pkm) => Species != pkm.Species;
protected override bool IsMatchPartial(PKM pkm) => false; // no version compatibility checks yet.