mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-05-09 04:24:36 -05:00
Add mysterygift region/language restriction code
Closes #1317 Needs the events crew to produce serialized binaries with hash-flag data for each generation before proceeding any further. I'm not really interested in doing all the work for events since it doesn't impact battle legality.
This commit is contained in:
parent
fffc943668
commit
e7fc30ac7a
13
PKHeX.Core/Game/RegionID.cs
Normal file
13
PKHeX.Core/Game/RegionID.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public enum RegionID
|
||||
{
|
||||
None = 0,
|
||||
RegJP = 1,
|
||||
RegNA = 2,
|
||||
RegEU = 3,
|
||||
RegZH = 4,
|
||||
RegKO = 5,
|
||||
RegTW = 6,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
[Flags]
|
||||
public enum MysteryGiftRestriction : ushort
|
||||
{
|
||||
None = 0,
|
||||
LangJapanese = 1 << LanguageID.Japanese,
|
||||
LangEnglish = 1 << LanguageID.English,
|
||||
LangFrench = 1 << LanguageID.French,
|
||||
LangItalian = 1 << LanguageID.Italian,
|
||||
LangGerman = 1 << LanguageID.German,
|
||||
LangSpanish = 1 << LanguageID.Spanish,
|
||||
LangKorean = 1 << LanguageID.Korean,
|
||||
|
||||
LangRestrict = LangJapanese | LangEnglish | LangFrench | LangItalian | LangGerman | LangSpanish | LangKorean,
|
||||
RegionBase = LangKorean,
|
||||
|
||||
RegJP = RegionBase << RegionID.Japan,
|
||||
RegNA = RegionBase << RegionID.NorthAmerica,
|
||||
RegEU = RegionBase << RegionID.Europe,
|
||||
RegZH = RegionBase << RegionID.China,
|
||||
RegKO = RegionBase << RegionID.Korea,
|
||||
RegTW = RegionBase << RegionID.Taiwan,
|
||||
|
||||
RegionRestrict = RegJP | RegNA | RegEU | RegZH | RegKO | RegTW,
|
||||
|
||||
OTReplacedOnTrade = RegTW << 1,
|
||||
}
|
||||
|
||||
public static class MysteryGiftRestrictionExtensions
|
||||
{
|
||||
public static bool HasFlagFast(this MysteryGiftRestriction value, MysteryGiftRestriction flag)
|
||||
{
|
||||
return (value & flag) != 0;
|
||||
}
|
||||
|
||||
public static int GetSuggestedLanguage(this MysteryGiftRestriction value)
|
||||
{
|
||||
for (int i = (int)LanguageID.Japanese; i <= (int)LanguageID.Korean; i++)
|
||||
if (value.HasFlagFast((MysteryGiftRestriction)(1 << i)))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
public static int GetSuggestedRegion(this MysteryGiftRestriction value)
|
||||
{
|
||||
for (int i = (int)RegionID.Japan; i <= (int)RegionID.Taiwan; i++)
|
||||
if (value.HasFlagFast((MysteryGiftRestriction)((int)MysteryGiftRestriction.RegionBase << i)))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
102
PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftVerifier.cs
Normal file
102
PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftVerifier.cs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static PKHeX.Core.LegalityCheckStrings;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public static class MysteryGiftVerifier
|
||||
{
|
||||
private static readonly Dictionary<int, MysteryGiftRestriction>[] RestrictionSet = Get();
|
||||
private static Dictionary<int, MysteryGiftRestriction>[] Get()
|
||||
{
|
||||
var s = new Dictionary<int, MysteryGiftRestriction>[PKX.Generation + 1];
|
||||
for (int i = 3; i < s.Length; i++)
|
||||
s[i] = GetRestriction(i);
|
||||
return s;
|
||||
}
|
||||
|
||||
private static string RestrictionSetName(int i) => $"mgrestrict{i}.pkl";
|
||||
private static Dictionary<int, MysteryGiftRestriction> GetRestriction(int generation)
|
||||
{
|
||||
var resource = RestrictionSetName(generation);
|
||||
var data = Util.GetBinaryResource(resource);
|
||||
var dict = new Dictionary<int, MysteryGiftRestriction>();
|
||||
for (int i = 0; i < data.Length; i += 4 + 2)
|
||||
{
|
||||
int hash = BitConverter.ToInt32(data, i + 0);
|
||||
var restrict = BitConverter.ToUInt16(data, i + 4);
|
||||
dict.Add(hash, (MysteryGiftRestriction)restrict);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static CheckResult VerifyGift(PKM pk, MysteryGift g)
|
||||
{
|
||||
bool restricted = TryGetRestriction(g, out var val);
|
||||
if (!restricted)
|
||||
return new CheckResult(CheckIdentifier.GameOrigin);
|
||||
|
||||
var lang = val & MysteryGiftRestriction.LangRestrict;
|
||||
if (lang != 0)
|
||||
{
|
||||
var current = 1 << pk.Language;
|
||||
if (!lang.HasFlagFast((MysteryGiftRestriction) current))
|
||||
{
|
||||
int suggest = lang.GetSuggestedLanguage();
|
||||
return new CheckResult(Severity.Invalid, string.Format(V5, suggest, pk.Language), CheckIdentifier.GameOrigin);
|
||||
}
|
||||
}
|
||||
var region = val & MysteryGiftRestriction.RegionRestrict;
|
||||
if (region != 0)
|
||||
{
|
||||
var current = (int)MysteryGiftRestriction.RegionBase << pk.ConsoleRegion;
|
||||
if (!region.HasFlagFast((MysteryGiftRestriction)current))
|
||||
return new CheckResult(Severity.Invalid, V301, CheckIdentifier.GameOrigin);
|
||||
}
|
||||
|
||||
return new CheckResult(CheckIdentifier.GameOrigin);
|
||||
}
|
||||
|
||||
private static bool TryGetRestriction(MysteryGift g, out MysteryGiftRestriction val)
|
||||
{
|
||||
var restrict = RestrictionSet[g.Generation];
|
||||
if (restrict != null)
|
||||
return restrict.TryGetValue(g.GetHashCode(), out val);
|
||||
val = MysteryGiftRestriction.None;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsValidChangedOTName(PKM pk, MysteryGift g)
|
||||
{
|
||||
bool restricted = TryGetRestriction(g, out var val);
|
||||
if (!restricted)
|
||||
return false; // no data
|
||||
if (!val.HasFlagFast(MysteryGiftRestriction.OTReplacedOnTrade))
|
||||
return false;
|
||||
return CurrentOTMatchesReplaced(g.Format, pk.OT_Name);
|
||||
}
|
||||
|
||||
private static bool CurrentOTMatchesReplaced(int format, string pkOtName)
|
||||
{
|
||||
if (format <= 4 && IsMatchName(pkOtName, 4))
|
||||
return true;
|
||||
if (format <= 5 && IsMatchName(pkOtName, 5))
|
||||
return true;
|
||||
if (format <= 6 && IsMatchName(pkOtName, 6))
|
||||
return true;
|
||||
if (format <= 7 && IsMatchName(pkOtName, 7))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsMatchName(string pkOtName, int generation)
|
||||
{
|
||||
switch (generation)
|
||||
{
|
||||
// todo
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user