Initial ribbon refactor

remove legality check's use of reflection which checked individual
properties; add interfaces to interact with the ribbons of each PKM
type. With this, every ribbon attribute is accessible via its
corresponding interface (cast)

will have to add checks for individual interfaces as per #1250

I didn't feel like adding much documentation, is pretty straightforward.
Cast a pkm object to the desired ribbon set; if not null, can access
ribbons regardless of pkm format.
This commit is contained in:
Kurt 2017-06-19 21:43:44 -07:00
parent b4222c756a
commit 6921a2ebee
25 changed files with 668 additions and 190 deletions

View file

@ -723,80 +723,138 @@ namespace PKHeX.Core
if (!Encounter.Valid)
return;
// Check Unobtainable Ribbons
var encounterContent = (EncounterMatch as MysteryGift)?.Content ?? EncounterMatch;
List<string> missingRibbons = new List<string>();
List<string> invalidRibbons = new List<string>();
// Check Event Ribbons
var encounterContent = (EncounterMatch as MysteryGift)?.Content ?? EncounterMatch;
var set1 = pkm as IRibbonSet1;
var set2 = pkm as IRibbonSet2;
if (set1 != null)
VerifyRibbonSet1(set1, encounterContent, missingRibbons, invalidRibbons);
if (set2 != null)
VerifyRibbonSet2(set2, encounterContent, missingRibbons, invalidRibbons);
// Check Unobtainable Ribbons
if (pkm.IsEgg)
{
var RibbonNames = ReflectUtil.GetPropertiesStartWithPrefix(pkm.GetType(), "Ribbon");
if (set1 != null)
RibbonNames = RibbonNames.Except(RibbonSetHelper.GetRibbonNames(set1));
if (set2 != null)
RibbonNames = RibbonNames.Except(RibbonSetHelper.GetRibbonNames(set2));
foreach (object RibbonValue in RibbonNames.Select(RibbonName => ReflectUtil.GetValue(pkm, RibbonName)))
{
if (RibbonValue as bool? == true) // Boolean
{ AddLine(Severity.Invalid, V95, CheckIdentifier.Ribbon); return; }
if ((RibbonValue as int?) > 0) // Count
{ AddLine(Severity.Invalid, V95, CheckIdentifier.Ribbon); return; }
}
VerifyRibbonsEgg(encounterContent);
return;
}
// Unobtainable ribbons for Gen Origin
if (pkm.GenNumber > 3)
{
if (ReflectUtil.GetBooleanState(pkm, nameof(PK3.RibbonChampionG3Hoenn)) == true)
invalidRibbons.Add(V96); // RSE HoF
if (ReflectUtil.GetBooleanState(pkm, nameof(PK3.RibbonArtist)) == true)
invalidRibbons.Add(V97); // RSE Master Rank Portrait
}
if (pkm.Format >= 4 && pkm.GenNumber > 4)
{
if (ReflectUtil.GetBooleanState(pkm, nameof(PK4.RibbonChampionSinnoh)) == true)
invalidRibbons.Add(V99); // DPPt HoF
if (ReflectUtil.GetBooleanState(pkm, nameof(PK4.RibbonLegend)) == true)
invalidRibbons.Add(V100); // HGSS Defeat Red @ Mt.Silver
}
if (pkm.Format >= 6 && pkm.GenNumber >= 6)
{
if (ReflectUtil.GetBooleanState(pkm, nameof(PK6.RibbonCountMemoryContest)) == true)
invalidRibbons.Add(V106); // Gen3/4 Contest
if (ReflectUtil.GetBooleanState(pkm, nameof(PK6.RibbonCountMemoryBattle)) == true)
invalidRibbons.Add(V105); // Gen3/4 Battle
}
if (ReflectUtil.GetBooleanState(pkm, nameof(PK6.RibbonRecord)) == true)
invalidRibbons.Add(V104); // Unobtainable
VerifyRibbonSet1(pkm as IRibbonSetEvent3, encounterContent, missingRibbons, invalidRibbons);
VerifyRibbonSet2(pkm as IRibbonSetEvent4, encounterContent, missingRibbons, invalidRibbons);
invalidRibbons.AddRange(GetRibbonResults(pkm));
if (missingRibbons.Count + invalidRibbons.Count == 0)
var result = GetRibbonMessage(missingRibbons, invalidRibbons);
if (result.Count == 0)
{
AddLine(Severity.Valid, V103, CheckIdentifier.Ribbon);
AddLine(Severity.Valid, V602, CheckIdentifier.Ribbon);
return;
}
string[] result = new string[2];
if (missingRibbons.Count > 0)
result[0] = string.Format(V101, string.Join(", ", missingRibbons.Select(z => z.Replace("Ribbon", ""))));
if (invalidRibbons.Count > 0)
result[1] = string.Format(V102, string.Join(", ", invalidRibbons.Select(z => z.Replace("Ribbon", ""))));
AddLine(Severity.Invalid, string.Join(Environment.NewLine, result.Where(s => !string.IsNullOrEmpty(s))), CheckIdentifier.Ribbon);
}
private void VerifyRibbonSet1(IRibbonSet1 set1, object encounterContent, List<string> missingRibbons, List<string> invalidRibbons)
private static List<string> GetRibbonMessage(IReadOnlyCollection<string> missingRibbons, IReadOnlyCollection<string> invalidRibbons)
{
var names = RibbonSetHelper.GetRibbonNames(set1);
var sb = RibbonSetHelper.GetRibbonBits(set1);
var eb = RibbonSetHelper.GetRibbonBits(encounterContent as IRibbonSet1);
var result = new List<string>();
if (missingRibbons.Count > 0)
result.Add(string.Format(V601, string.Join(", ", missingRibbons.Select(z => z.Replace("Ribbon", "")))));
if (invalidRibbons.Count > 0)
result.Add(string.Format(V600, string.Join(", ", invalidRibbons.Select(z => z.Replace("Ribbon", "")))));
return result;
}
private static IEnumerable<string> GetRibbonResults(PKM pkm)
{
int gen = pkm.GenNumber;
if (pkm is IRibbonSetOnly3 o3)
{
}
if (pkm is IRibbonSetUnique3 u3)
{
}
if (pkm is IRibbonSetUnique4 u5)
{
}
if (pkm is IRibbonSetCommon3 s3)
{
if (gen != 3)
{
if (s3.RibbonChampionG3Hoenn && gen != 3)
yield return V610; // RSE HoF
if (s3.RibbonArtist && gen != 3)
yield return V611; // RSE Master Rank Portrait
}
}
if (pkm is IRibbonSetCommon4 s4)
{
if (s4.RibbonRecord)
yield return V614; // Unobtainable
if (gen != 3 && gen != 4)
{
if (s4.RibbonChampionSinnoh)
yield return V612; // DPPt HoF
if (s4.RibbonLegend)
yield return V613; // HGSS Defeat Red @ Mt.Silver
}
}
if (pkm is IRibbonSetCommon6 s6)
{
int contest = 0;
int battle = 0;
switch (gen)
{
case 3:
contest = 40;
battle = 8;
break;
case 4:
contest = 20;
battle = 8;
break;
}
if (s6.RibbonCountMemoryContest > contest)
yield return V616;
if (s6.RibbonCountMemoryBattle > battle)
yield return V615;
bool inhabited6 = 3 <= gen && gen <= 6;
if (!inhabited6 && s6.RibbonChampionKalos)
yield return V615;
}
if (pkm is IRibbonSetCommon7 s7)
{
}
}
private void VerifyRibbonsEgg(object encounter)
{
var event3 = encounter as IRibbonSetEvent3;
var event4 = encounter as IRibbonSetEvent4;
var RibbonNames = ReflectUtil.GetPropertiesStartWithPrefix(pkm.GetType(), "Ribbon");
if (event3 != null)
RibbonNames = RibbonNames.Except(event3.RibbonNames());
if (event4 != null)
RibbonNames = RibbonNames.Except(event4.RibbonNames());
foreach (object RibbonValue in RibbonNames.Select(RibbonName => ReflectUtil.GetValue(pkm, RibbonName)))
{
if (!HasFlag(RibbonValue) && !HasCount(RibbonValue))
continue;
AddLine(Severity.Invalid, V603, CheckIdentifier.Ribbon);
return;
bool HasFlag(object o) => o is bool z && z;
bool HasCount(object o) => o is int z && z > 0;
}
}
private void VerifyRibbonSet1(IRibbonSetEvent3 set1, object encounterContent, List<string> missingRibbons, List<string> invalidRibbons)
{
if (set1 == null)
return;
var names = set1.RibbonNames();
var sb = set1.RibbonBits();
var eb = (encounterContent as IRibbonSetEvent3).RibbonBits();
if (pkm.Gen3)
{
@ -813,11 +871,13 @@ namespace PKHeX.Core
if (sb[i] != eb[i])
(eb[i] ? missingRibbons : invalidRibbons).Add(names[i]);
}
private void VerifyRibbonSet2(IRibbonSet2 set2, object encounterContent, List<string> missingRibbons, List<string> invalidRibbons)
private void VerifyRibbonSet2(IRibbonSetEvent4 set2, object encounterContent, List<string> missingRibbons, List<string> invalidRibbons)
{
var names = RibbonSetHelper.GetRibbonNames(set2);
var sb = RibbonSetHelper.GetRibbonBits(set2);
var eb = RibbonSetHelper.GetRibbonBits(encounterContent as IRibbonSet2);
if (set2 == null)
return;
var names = set2.RibbonNames();
var sb = set2.RibbonBits();
var eb = (encounterContent as IRibbonSetEvent4).RibbonBits();
if (EncounterMatch is EncounterLink)
eb[0] = true; // require Classic Ribbon

View file

@ -215,18 +215,6 @@ namespace PKHeX.Core
public static string V94 {get; set;} = "Distribution Super Training missions are not released."; // Fishy
public static string V98 {get; set;} = "Unused Super Training Flag is flagged.";
public static string V95 {get; set;} = "Can't receive Ribbon(s) as an Egg.";
public static string V96 {get; set;} = "GBA Champion Ribbon";
public static string V97 {get; set;} = "Artist Ribbon";
public static string V99 {get; set;} = "Sinnoh Champion Ribbon";
public static string V100 {get; set;} = "Legend Ribbon";
public static string V104 {get; set;} = "Record Ribbon";
public static string V101 {get; set;} = "Missing Ribbons: {0}";
public static string V102 {get; set;} = "Invalid Ribbons: {0}";
public static string V103 {get; set;} = "All ribbons accounted for.";
public static string V105 {get; set;} = "Battle Memory Ribbon";
public static string V106 {get; set;} = "Contest Memory Ribbon";
public static string V107 {get; set;} = "Ability is not valid for species/form.";
public static string V108 {get; set;} = "Hidden Ability mismatch for encounter type.";
public static string V223 {get; set;} = "Ability mismatch for encounter.";
@ -412,6 +400,19 @@ namespace PKHeX.Core
public static string V416 {get; set;} = "Mystery Gift cannot be received by this version."; // Invalid
public static string V417 {get; set;} = "Suspicious Original Trainer details.";
public static string V418 {get; set;} = "Individual EV without changing EXP cannot be greater than {0}.";
public static string V600 { get; set; } = "Invalid Ribbons: {0}";
public static string V601 { get; set; } = "Missing Ribbons: {0}";
public static string V602 { get; set; } = "All ribbons accounted for.";
public static string V603 { get; set; } = "Can't receive Ribbon(s) as an Egg.";
public static string V610 { get; set; } = "GBA Champion Ribbon";
public static string V611 { get; set; } = "Artist Ribbon";
public static string V612 { get; set; } = "Sinnoh Champion Ribbon";
public static string V613 { get; set; } = "Legend Ribbon";
public static string V614 { get; set; } = "Record Ribbon";
public static string V615 { get; set; } = "Battle Memory Ribbon";
public static string V616 { get; set; } = "Contest Memory Ribbon";
#endregion
}

View file

@ -1,72 +0,0 @@
namespace PKHeX.Core
{
internal interface IRibbonSet1 // Gen3+
{
bool RibbonEarth { get; set; }
bool RibbonNational { get; set; }
bool RibbonCountry { get; set; }
bool RibbonChampionBattle { get; set; }
bool RibbonChampionRegional { get; set; }
bool RibbonChampionNational { get; set; }
}
internal interface IRibbonSet2 // Gen4+
{
bool RibbonClassic { get; set; }
bool RibbonWishing { get; set; }
bool RibbonPremier { get; set; }
bool RibbonEvent { get; set; }
bool RibbonBirthday { get; set; }
bool RibbonSpecial { get; set; }
bool RibbonWorld { get; set; }
bool RibbonChampionWorld { get; set; }
bool RibbonSouvenir { get; set; }
}
internal static class RibbonSetHelper
{
private static readonly string[] RibbonNames1 =
{
nameof(IRibbonSet1.RibbonEarth), nameof(IRibbonSet1.RibbonNational), nameof(IRibbonSet1.RibbonCountry),
nameof(IRibbonSet1.RibbonChampionBattle), nameof(IRibbonSet1.RibbonChampionRegional), nameof(IRibbonSet1.RibbonChampionNational)
};
internal static bool[] GetRibbonBits(IRibbonSet1 set)
{
if (set == null)
return new bool[6];
return new[]
{
set.RibbonEarth,
set.RibbonNational,
set.RibbonCountry,
set.RibbonChampionBattle,
set.RibbonChampionRegional,
set.RibbonChampionNational,
};
}
private static readonly string[] RibbonNames2 =
{
nameof(IRibbonSet2.RibbonClassic), nameof(IRibbonSet2.RibbonWishing), nameof(IRibbonSet2.RibbonPremier),
nameof(IRibbonSet2.RibbonEvent), nameof(IRibbonSet2.RibbonBirthday), nameof(IRibbonSet2.RibbonSpecial),
nameof(IRibbonSet2.RibbonWorld), nameof(IRibbonSet2.RibbonChampionWorld), nameof(IRibbonSet2.RibbonSouvenir)
};
internal static bool[] GetRibbonBits(IRibbonSet2 set)
{
if (set == null)
return new bool[9];
return new[]
{
set.RibbonClassic,
set.RibbonWishing,
set.RibbonPremier,
set.RibbonEvent,
set.RibbonBirthday,
set.RibbonSpecial,
set.RibbonWorld,
set.RibbonChampionWorld,
set.RibbonSouvenir,
};
}
internal static string[] GetRibbonNames(IRibbonSet1 set) => RibbonNames1;
internal static string[] GetRibbonNames(IRibbonSet2 set) => RibbonNames2;
}
}

View file

@ -3,7 +3,7 @@ using System.Text;
namespace PKHeX.Core
{
public sealed class PGF : MysteryGift, IRibbonSet1, IRibbonSet2
public sealed class PGF : MysteryGift, IRibbonSetEvent3, IRibbonSetEvent4
{
public const int Size = 0xCC;
public override int Format => 5;

View file

@ -4,7 +4,7 @@ using System.Text;
namespace PKHeX.Core
{
public sealed class WC6 : MysteryGift, IRibbonSet1, IRibbonSet2
public sealed class WC6 : MysteryGift, IRibbonSetEvent3, IRibbonSetEvent4
{
public const int Size = 0x108;
public const int SizeFull = 0x310;

View file

@ -4,7 +4,7 @@ using System.Text;
namespace PKHeX.Core
{
public sealed class WC7 : MysteryGift, IRibbonSet1, IRibbonSet2
public sealed class WC7 : MysteryGift, IRibbonSetEvent3, IRibbonSetEvent4
{
public const int Size = 0x108;
public const int SizeFull = 0x310;

View file

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public class CK3 : PKM, IRibbonSet1
public class CK3 : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSetUnique3, IRibbonSetOnly3
{
public static readonly byte[] ExtraBytes =
{

View file

@ -3,7 +3,7 @@ using System.Linq;
namespace PKHeX.Core
{
public class PK3 : PKM, IRibbonSet1
public class PK3 : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSetUnique3, IRibbonSetOnly3
{
public static readonly byte[] ExtraBytes =
{

View file

@ -3,7 +3,7 @@ using System.Linq;
namespace PKHeX.Core
{
public class PK4 : PKM, IRibbonSet1, IRibbonSet2
public class PK4 : PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetUnique3, IRibbonSetUnique4
{
public static readonly byte[] ExtraBytes =
{

View file

@ -3,7 +3,7 @@ using System.Linq;
namespace PKHeX.Core
{
public class PK5 : PKM, IRibbonSet1, IRibbonSet2
public class PK5 : PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetUnique4
{
public static readonly byte[] ExtraBytes =
{

View file

@ -3,7 +3,7 @@ using System.Linq;
namespace PKHeX.Core
{
public class PK6 : PKM, IRibbonSet1, IRibbonSet2
public class PK6 : PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6
{
public static readonly byte[] ExtraBytes =
{

View file

@ -3,7 +3,7 @@ using System.Linq;
namespace PKHeX.Core
{
public class PK7 : PKM, IRibbonSet1, IRibbonSet2
public class PK7 : PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetCommon7
{
public static readonly byte[] ExtraBytes =
{

View file

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public class XK3 : PKM, IRibbonSet1
public class XK3 : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSetUnique3, IRibbonSetOnly3
{
public static readonly byte[] ExtraBytes =
{

View file

@ -162,17 +162,6 @@ V92 = Can't have active Super Training complete flag for origins.
V93 = Super Training complete flag mismatch.
V94 = Distribution Super Training missions are not released.
V98 = Unused Super Training Flag is flagged.
V95 = Can't receive Ribbon(s) as an Egg.
V96 = GBA Champion Ribbon
V97 = Artist Ribbon
V99 = Sinnoh Champion Ribbon
V100 = Legend Ribbon
V104 = Record Ribbon
V101 = Missing Ribbons: {0}
V102 = Invalid Ribbons: {0}
V103 = All ribbons accounted for.
V105 = Battle Memory Ribbon
V106 = Contest Memory Ribbon
V107 = Ability is not valid for species/form.
V108 = Hidden Ability mismatch for encounter type.
V223 = Ability mismatch for encounter.
@ -349,3 +338,14 @@ V415 = Eggs cannot have Pokéathlon stats.
V416 = Mystery Gift cannot be received by this version.
V417 = Suspicious Original Trainer details.
V418 = Individual EV without changing EXP cannot be greater than {0}.
V600 = All ribbons accounted for.
V601 = Missing Ribbons: {0}
V602 = Invalid Ribbons: {0}
V603 = Can't receive Ribbon(s) as an Egg.
V610 = GBA Champion Ribbon
V611 = Artist Ribbon
V612 = Sinnoh Champion Ribbon
V613 = Legend Ribbon
V614 = Record Ribbon
V615 = Battle Memory Ribbon
V616 = Contest Memory Ribbon

View file

@ -162,17 +162,6 @@ V92 = 만난 게임에서 대단한 특훈 완료 플래그를 켤 수 없습니
V93 = 대단한 특훈 완료 플래그가 일치하지 않습니다.
V94 = 배분한 대단한 특훈 미션이 배포되지 않은 미션입니다.
V98 = 사용되지 않는 대단한 특훈 플래그가 켜져 있습니다.
V95 = 알은 리본을 얻을 수 없습니다.
V96 = GBA챔피언리본
V97 = 브로마이드리본
V99 = 신오챔피언리본
V100 = 레전드리본
V104 = 레코드리본
V101 = 없는 리본: {0}
V102 = 사용할 수 없는 리본: {0}
V103 = 모든 리본이 채워졌습니다.
V105 = 추억배틀리본
V106 = 추억콘테스트리본
V107 = 포켓몬 종류/폼에서 사용할 수 없는 특성입니다.
V108 = 숨겨진 특성이 인카운터 유형과 일치하지 않습니다.
V223 = 특성이 인카운터와 일치하지 않습니다.
@ -349,3 +338,14 @@ V415 = Eggs cannot have Pokéathlon stats.
V416 = Mystery Gift cannot be received by this version.
V417 = Suspicious Original Trainer details.
V418 = Individual EV without changing EXP cannot be greater than {0}.
V600 = 모든 리본이 채워졌습니다.
V601 = 없는 리본: {0}
V602 = 사용할 수 없는 리본: {0}
V603 = 알은 리본을 얻을 수 없습니다.
V610 = GBA챔피언리본
V611 = 브로마이드리본
V612 = 신오챔피언리본
V613 = 레전드리본
V614 = 레코드리본
V615 = 추억배틀리본
V616 = 추억콘테스트리본

View file

@ -162,17 +162,6 @@ V92 = 当前来源版本不能有超级训练完成的标记。
V93 = 超级训练完成标记不匹配。
V94 = 配信超级训练任务未发布。
V98 = 未使用的超级训练旗标被标记。
V95 = 蛋不能接受奖章。
V96 = GBA冠军奖章
V97 = 肖像奖章
V99 = 神奥冠军奖章
V100 = 传说奖章
V104 = 记录奖章
V101 = 缺失奖章: {0}
V102 = 不合法奖章: {0}
V103 = 所有奖章合法。
V105 = 对战回忆奖章
V106 = 华丽大赛回忆奖章
V107 = 特性对于该种类/形态不合法。
V108 = 隐藏特性与相遇方式不一致。
V223 = 特性与相遇方式不一致。
@ -349,3 +338,14 @@ V415 = Eggs cannot have Pokéathlon stats.
V416 = Mystery Gift cannot be received by this version.
V417 = Suspicious Original Trainer details.
V418 = Individual EV without changing EXP cannot be greater than {0}.
V600 = 所有奖章合法。
V601 = 缺失奖章: {0}
V602 = 不合法奖章: {0}
V603 = 蛋不能接受奖章。
V610 = GBA冠军奖章
V611 = 肖像奖章
V612 = 神奥冠军奖章
V613 = 传说奖章
V614 = 记录奖章
V615 = 对战回忆奖章
V616 = 华丽大赛回忆奖章

View file

@ -0,0 +1,30 @@
namespace PKHeX.Core
{
/// <summary> Common Ribbons introduced in Generation 3 </summary>
internal interface IRibbonSetCommon3
{
bool RibbonChampionG3Hoenn { get; set; }
bool RibbonArtist { get; set; }
bool RibbonEffort { get; set; }
}
internal static partial class RibbonExtensions
{
private static readonly string[] RibbonSetNamesCommon3 =
{
nameof(IRibbonSetCommon3.RibbonChampionG3Hoenn), nameof(IRibbonSetCommon3.RibbonArtist), nameof(IRibbonSetCommon3.RibbonEffort)
};
internal static bool[] RibbonBits(this IRibbonSetCommon3 set)
{
if (set == null)
return new bool[3];
return new[]
{
set.RibbonChampionG3Hoenn,
set.RibbonArtist,
set.RibbonEffort,
};
}
internal static string[] RibbonNames(this IRibbonSetCommon3 set) => RibbonSetNamesCommon3;
}
}

View file

@ -0,0 +1,56 @@
namespace PKHeX.Core
{
/// <summary> Common Ribbons introduced in Generation 4 </summary>
internal interface IRibbonSetCommon4
{
bool RibbonChampionSinnoh { get; set; }
bool RibbonAlert { get; set; }
bool RibbonShock { get; set; }
bool RibbonDowncast { get; set; }
bool RibbonCareless { get; set; }
bool RibbonRelax { get; set; }
bool RibbonSnooze { get; set; }
bool RibbonSmile { get; set; }
bool RibbonGorgeous { get; set; }
bool RibbonRoyal { get; set; }
bool RibbonGorgeousRoyal { get; set; }
bool RibbonFootprint { get; set; }
bool RibbonRecord { get; set; }
bool RibbonLegend { get; set; }
}
internal static partial class RibbonExtensions
{
private static readonly string[] RibbonSetNamesCommon4 =
{
nameof(IRibbonSetCommon4.RibbonChampionSinnoh), nameof(IRibbonSetCommon4.RibbonAlert), nameof(IRibbonSetCommon4.RibbonShock),
nameof(IRibbonSetCommon4.RibbonDowncast), nameof(IRibbonSetCommon4.RibbonCareless), nameof(IRibbonSetCommon4.RibbonRelax),
nameof(IRibbonSetCommon4.RibbonSnooze), nameof(IRibbonSetCommon4.RibbonSmile), nameof(IRibbonSetCommon4.RibbonGorgeous),
nameof(IRibbonSetCommon4.RibbonRoyal), nameof(IRibbonSetCommon4.RibbonGorgeousRoyal), nameof(IRibbonSetCommon4.RibbonFootprint),
nameof(IRibbonSetCommon4.RibbonRecord), nameof(IRibbonSetCommon4.RibbonLegend),
};
internal static bool[] RibbonBits(this IRibbonSetCommon4 set)
{
if (set == null)
return new bool[15];
return new[]
{
set.RibbonChampionSinnoh,
set.RibbonAlert,
set.RibbonShock,
set.RibbonDowncast,
set.RibbonCareless,
set.RibbonRelax,
set.RibbonSnooze,
set.RibbonSmile,
set.RibbonGorgeous,
set.RibbonRoyal,
set.RibbonGorgeousRoyal,
set.RibbonFootprint,
set.RibbonRecord,
set.RibbonLegend,
};
}
internal static string[] RibbonNames(this IRibbonSetCommon4 set) => RibbonSetNamesCommon4;
}
}

View file

@ -0,0 +1,57 @@
namespace PKHeX.Core
{
/// <summary> Common Ribbons introduced in Generation 6 </summary>
internal interface IRibbonSetCommon6
{
bool RibbonChampionKalos { get; set; }
bool RibbonChampionG6Hoenn { get; set; }
bool RibbonBestFriends { get; set; }
bool RibbonTraining { get; set; }
bool RibbonBattlerSkillful { get; set; }
bool RibbonBattlerExpert { get; set; }
bool RibbonContestStar { get; set; }
bool RibbonMasterCoolness { get; set; }
bool RibbonMasterBeauty { get; set; }
bool RibbonMasterCuteness { get; set; }
bool RibbonMasterCleverness { get; set; }
bool RibbonMasterToughness { get; set; }
int RibbonCountMemoryContest { get; set; }
int RibbonCountMemoryBattle { get; set; }
}
internal static partial class RibbonExtensions
{
private static readonly string[] RibbonSetNamesCommon6Bool =
{
nameof(IRibbonSetCommon6.RibbonChampionKalos), nameof(IRibbonSetCommon6.RibbonChampionG6Hoenn), nameof(IRibbonSetCommon6.RibbonBestFriends),
nameof(IRibbonSetCommon6.RibbonTraining), nameof(IRibbonSetCommon6.RibbonBattlerSkillful), nameof(IRibbonSetCommon6.RibbonBattlerExpert),
nameof(IRibbonSetCommon6.RibbonContestStar), nameof(IRibbonSetCommon6.RibbonMasterCoolness), nameof(IRibbonSetCommon6.RibbonMasterBeauty),
nameof(IRibbonSetCommon6.RibbonMasterCuteness), nameof(IRibbonSetCommon6.RibbonMasterCleverness), nameof(IRibbonSetCommon6.RibbonMasterToughness),
};
internal static bool[] RibbonBits(this IRibbonSetCommon6 set)
{
if (set == null)
return new bool[12];
return new[]
{
set.RibbonChampionKalos,
set.RibbonChampionG6Hoenn,
set.RibbonBestFriends,
set.RibbonTraining,
set.RibbonBattlerSkillful,
set.RibbonBattlerExpert,
set.RibbonContestStar,
set.RibbonMasterCoolness,
set.RibbonMasterBeauty,
set.RibbonMasterCuteness,
set.RibbonMasterCleverness,
set.RibbonMasterToughness,
};
}
internal static string[] RibbonNamesBool(this IRibbonSetCommon6 set) => RibbonSetNamesCommon6Bool;
}
}

View file

@ -0,0 +1,33 @@
namespace PKHeX.Core
{
/// <summary> Common Ribbons introduced in Generation 7 </summary>
internal interface IRibbonSetCommon7
{
bool RibbonChampionAlola { get; set; }
bool RibbonBattleRoyale { get; set; }
bool RibbonBattleTreeGreat { get; set; }
bool RibbonBattleTreeMaster { get; set; }
}
internal static partial class RibbonExtensions
{
private static readonly string[] RibbonSetNamesCommon7 =
{
nameof(IRibbonSetCommon7.RibbonChampionAlola), nameof(IRibbonSetCommon7.RibbonBattleRoyale),
nameof(IRibbonSetCommon7.RibbonBattleTreeGreat), nameof(IRibbonSetCommon7.RibbonBattleTreeMaster)
};
internal static bool[] RibbonBits(this IRibbonSetCommon7 set)
{
if (set == null)
return new bool[4];
return new[]
{
set.RibbonChampionAlola,
set.RibbonBattleRoyale,
set.RibbonBattleTreeGreat,
set.RibbonBattleTreeMaster,
};
}
internal static string[] RibbonNames(this IRibbonSetCommon7 set) => RibbonSetNamesCommon7;
}
}

View file

@ -0,0 +1,37 @@
namespace PKHeX.Core
{
/// <summary> Ribbons introduced in Generation 3 for Special Events </summary>
internal interface IRibbonSetEvent3
{
bool RibbonEarth { get; set; }
bool RibbonNational { get; set; }
bool RibbonCountry { get; set; }
bool RibbonChampionBattle { get; set; }
bool RibbonChampionRegional { get; set; }
bool RibbonChampionNational { get; set; }
}
internal static partial class RibbonExtensions
{
private static readonly string[] RibbonSetNamesEvent3 =
{
nameof(IRibbonSetEvent3.RibbonEarth), nameof(IRibbonSetEvent3.RibbonNational), nameof(IRibbonSetEvent3.RibbonCountry),
nameof(IRibbonSetEvent3.RibbonChampionBattle), nameof(IRibbonSetEvent3.RibbonChampionRegional), nameof(IRibbonSetEvent3.RibbonChampionNational)
};
internal static bool[] RibbonBits(this IRibbonSetEvent3 set)
{
if (set == null)
return new bool[6];
return new[]
{
set.RibbonEarth,
set.RibbonNational,
set.RibbonCountry,
set.RibbonChampionBattle,
set.RibbonChampionRegional,
set.RibbonChampionNational,
};
}
internal static string[] RibbonNames(this IRibbonSetEvent3 set) => RibbonSetNamesEvent3;
}
}

View file

@ -0,0 +1,35 @@
namespace PKHeX.Core
{
/// <summary> Ribbons that originated in Generation 3 and were only present within that Generation. </summary>
internal interface IRibbonSetOnly3
{
int RibbonCountG3Cool { get; set; }
int RibbonCountG3Beauty { get; set; }
int RibbonCountG3Cute { get; set; }
int RibbonCountG3Smart { get; set; }
int RibbonCountG3Tough { get; set; }
}
internal static partial class RibbonExtensions
{
private static readonly string[] RibbonSetNamesOnly3 =
{
nameof(IRibbonSetOnly3.RibbonCountG3Cool), nameof(IRibbonSetOnly3.RibbonCountG3Beauty), nameof(IRibbonSetOnly3.RibbonCountG3Cute),
nameof(IRibbonSetOnly3.RibbonCountG3Smart), nameof(IRibbonSetOnly3.RibbonCountG3Tough),
};
internal static int[] RibbonCounts(this IRibbonSetOnly3 set)
{
if (set == null)
return new int[5];
return new[]
{
set.RibbonCountG3Cool,
set.RibbonCountG3Beauty,
set.RibbonCountG3Cute,
set.RibbonCountG3Smart,
set.RibbonCountG3Tough,
};
}
internal static string[] RibbonNames(this IRibbonSetOnly3 set) => RibbonSetNamesOnly3;
}
}

View file

@ -0,0 +1,30 @@
namespace PKHeX.Core
{
/// <summary> Ribbons introduced in Generation 3 and were transferred to future Generations (4 and 5 only). </summary>
internal interface IRibbonSetUnique3
{
/// <summary> Ribbon awarded for clearing Hoenn's Battle Tower's Lv. 50 challenge. </summary>
bool RibbonWinning { get; set; }
/// <summary> Ribbon awarded for clearing Hoenn's Battle Tower's Lv. 100 challenge. </summary>
bool RibbonVictory { get; set; }
}
internal static partial class RibbonExtensions
{
private static readonly string[] RibbonSetNamesUnique3 =
{
nameof(IRibbonSetUnique3.RibbonWinning), nameof(IRibbonSetUnique3.RibbonVictory),
};
internal static bool[] RibbonBits(this IRibbonSetUnique3 set)
{
if (set == null)
return new bool[2];
return new[]
{
set.RibbonWinning,
set.RibbonVictory,
};
}
internal static string[] RibbonNames(this IRibbonSetUnique3 set) => RibbonSetNamesUnique3;
}
}

View file

@ -0,0 +1,167 @@
namespace PKHeX.Core
{
/// <summary> Ribbons introduced in Generation 4 and were transferred to future Generations (4 and 5 only). </summary>
internal interface IRibbonSetUnique4
{
bool RibbonAbility { get; set; }
bool RibbonAbilityGreat { get; set; }
bool RibbonAbilityDouble { get; set; }
bool RibbonAbilityMulti { get; set; }
bool RibbonAbilityPair { get; set; }
bool RibbonAbilityWorld { get; set; }
bool RibbonG3Cool { get; set; }
bool RibbonG3CoolSuper { get; set; }
bool RibbonG3CoolHyper { get; set; }
bool RibbonG3CoolMaster { get; set; }
bool RibbonG3Beauty { get; set; }
bool RibbonG3BeautySuper { get; set; }
bool RibbonG3BeautyHyper { get; set; }
bool RibbonG3BeautyMaster { get; set; }
bool RibbonG3Cute { get; set; }
bool RibbonG3CuteSuper { get; set; }
bool RibbonG3CuteHyper { get; set; }
bool RibbonG3CuteMaster { get; set; }
bool RibbonG3Smart { get; set; }
bool RibbonG3SmartSuper { get; set; }
bool RibbonG3SmartHyper { get; set; }
bool RibbonG3SmartMaster { get; set; }
bool RibbonG3Tough { get; set; }
bool RibbonG3ToughSuper { get; set; }
bool RibbonG3ToughHyper { get; set; }
bool RibbonG3ToughMaster { get; set; }
bool RibbonG4Cool { get; set; }
bool RibbonG4CoolGreat { get; set; }
bool RibbonG4CoolUltra { get; set; }
bool RibbonG4CoolMaster { get; set; }
bool RibbonG4Beauty { get; set; }
bool RibbonG4BeautyGreat { get; set; }
bool RibbonG4BeautyUltra { get; set; }
bool RibbonG4BeautyMaster { get; set; }
bool RibbonG4Cute { get; set; }
bool RibbonG4CuteGreat { get; set; }
bool RibbonG4CuteUltra { get; set; }
bool RibbonG4CuteMaster { get; set; }
bool RibbonG4Smart { get; set; }
bool RibbonG4SmartGreat { get; set; }
bool RibbonG4SmartUltra { get; set; }
bool RibbonG4SmartMaster { get; set; }
bool RibbonG4Tough { get; set; }
bool RibbonG4ToughGreat { get; set; }
bool RibbonG4ToughUltra { get; set; }
bool RibbonG4ToughMaster { get; set; }
}
internal static partial class RibbonExtensions
{
private static readonly string[] RibbonSetNamesUnique4 =
{
nameof(IRibbonSetUnique4.RibbonAbility),
nameof(IRibbonSetUnique4.RibbonAbilityGreat),
nameof(IRibbonSetUnique4.RibbonAbilityDouble),
nameof(IRibbonSetUnique4.RibbonAbilityMulti),
nameof(IRibbonSetUnique4.RibbonAbilityPair),
nameof(IRibbonSetUnique4.RibbonAbilityWorld),
nameof(IRibbonSetUnique4.RibbonG3Cool),
nameof(IRibbonSetUnique4.RibbonG3CoolSuper),
nameof(IRibbonSetUnique4.RibbonG3CoolHyper),
nameof(IRibbonSetUnique4.RibbonG3CoolMaster),
nameof(IRibbonSetUnique4.RibbonG3Beauty),
nameof(IRibbonSetUnique4.RibbonG3BeautySuper),
nameof(IRibbonSetUnique4.RibbonG3BeautyHyper),
nameof(IRibbonSetUnique4.RibbonG3BeautyMaster),
nameof(IRibbonSetUnique4.RibbonG3Cute),
nameof(IRibbonSetUnique4.RibbonG3CuteSuper),
nameof(IRibbonSetUnique4.RibbonG3CuteHyper),
nameof(IRibbonSetUnique4.RibbonG3CuteMaster),
nameof(IRibbonSetUnique4.RibbonG3Smart),
nameof(IRibbonSetUnique4.RibbonG3SmartSuper),
nameof(IRibbonSetUnique4.RibbonG3SmartHyper),
nameof(IRibbonSetUnique4.RibbonG3SmartMaster),
nameof(IRibbonSetUnique4.RibbonG3Tough),
nameof(IRibbonSetUnique4.RibbonG3ToughSuper),
nameof(IRibbonSetUnique4.RibbonG3ToughHyper),
nameof(IRibbonSetUnique4.RibbonG3ToughMaster),
nameof(IRibbonSetUnique4.RibbonG4Cool),
nameof(IRibbonSetUnique4.RibbonG4CoolGreat),
nameof(IRibbonSetUnique4.RibbonG4CoolUltra),
nameof(IRibbonSetUnique4.RibbonG4CoolMaster),
nameof(IRibbonSetUnique4.RibbonG4Beauty),
nameof(IRibbonSetUnique4.RibbonG4BeautyGreat),
nameof(IRibbonSetUnique4.RibbonG4BeautyUltra),
nameof(IRibbonSetUnique4.RibbonG4BeautyMaster),
nameof(IRibbonSetUnique4.RibbonG4Cute),
nameof(IRibbonSetUnique4.RibbonG4CuteGreat),
nameof(IRibbonSetUnique4.RibbonG4CuteUltra),
nameof(IRibbonSetUnique4.RibbonG4CuteMaster),
nameof(IRibbonSetUnique4.RibbonG4Smart),
nameof(IRibbonSetUnique4.RibbonG4SmartGreat),
nameof(IRibbonSetUnique4.RibbonG4SmartUltra),
nameof(IRibbonSetUnique4.RibbonG4SmartMaster),
nameof(IRibbonSetUnique4.RibbonG4Tough),
nameof(IRibbonSetUnique4.RibbonG4ToughGreat),
nameof(IRibbonSetUnique4.RibbonG4ToughUltra),
nameof(IRibbonSetUnique4.RibbonG4ToughMaster),
};
internal static bool[] RibbonBits(this IRibbonSetUnique4 set)
{
if (set == null)
return new bool[3];
return new[]
{
set.RibbonAbility,
set.RibbonAbilityGreat,
set.RibbonAbilityDouble,
set.RibbonAbilityMulti,
set.RibbonAbilityPair,
set.RibbonAbilityWorld,
set.RibbonG3Cool,
set.RibbonG3CoolSuper,
set.RibbonG3CoolHyper,
set.RibbonG3CoolMaster,
set.RibbonG3Beauty,
set.RibbonG3BeautySuper,
set.RibbonG3BeautyHyper,
set.RibbonG3BeautyMaster,
set.RibbonG3Cute,
set.RibbonG3CuteSuper,
set.RibbonG3CuteHyper,
set.RibbonG3CuteMaster,
set.RibbonG3Smart,
set.RibbonG3SmartSuper,
set.RibbonG3SmartHyper,
set.RibbonG3SmartMaster,
set.RibbonG3Tough,
set.RibbonG3ToughSuper,
set.RibbonG3ToughHyper,
set.RibbonG3ToughMaster,
set.RibbonG4Cool,
set.RibbonG4CoolGreat,
set.RibbonG4CoolUltra,
set.RibbonG4CoolMaster,
set.RibbonG4Beauty,
set.RibbonG4BeautyGreat,
set.RibbonG4BeautyUltra,
set.RibbonG4BeautyMaster,
set.RibbonG4Cute,
set.RibbonG4CuteGreat,
set.RibbonG4CuteUltra,
set.RibbonG4CuteMaster,
set.RibbonG4Smart,
set.RibbonG4SmartGreat,
set.RibbonG4SmartUltra,
set.RibbonG4SmartMaster,
set.RibbonG4Tough,
set.RibbonG4ToughGreat,
set.RibbonG4ToughUltra,
set.RibbonG4ToughMaster,
};
}
internal static string[] RibbonNames(this IRibbonSetUnique4 set) => RibbonSetNamesUnique4;
}
}

View file

@ -0,0 +1,44 @@
namespace PKHeX.Core
{
/// <summary> Ribbons introduced in Generation 4 for Special Events </summary>
internal interface IRibbonSetEvent4
{
bool RibbonClassic { get; set; }
bool RibbonWishing { get; set; }
bool RibbonPremier { get; set; }
bool RibbonEvent { get; set; }
bool RibbonBirthday { get; set; }
bool RibbonSpecial { get; set; }
bool RibbonWorld { get; set; }
bool RibbonChampionWorld { get; set; }
bool RibbonSouvenir { get; set; }
}
internal static partial class RibbonExtensions
{
private static readonly string[] RibbonSetNamesEvent4 =
{
nameof(IRibbonSetEvent4.RibbonClassic), nameof(IRibbonSetEvent4.RibbonWishing), nameof(IRibbonSetEvent4.RibbonPremier),
nameof(IRibbonSetEvent4.RibbonEvent), nameof(IRibbonSetEvent4.RibbonBirthday), nameof(IRibbonSetEvent4.RibbonSpecial),
nameof(IRibbonSetEvent4.RibbonWorld), nameof(IRibbonSetEvent4.RibbonChampionWorld), nameof(IRibbonSetEvent4.RibbonSouvenir)
};
internal static bool[] RibbonBits(this IRibbonSetEvent4 set)
{
if (set == null)
return new bool[9];
return new[]
{
set.RibbonClassic,
set.RibbonWishing,
set.RibbonPremier,
set.RibbonEvent,
set.RibbonBirthday,
set.RibbonSpecial,
set.RibbonWorld,
set.RibbonChampionWorld,
set.RibbonSouvenir,
};
}
internal static string[] RibbonNames(this IRibbonSetEvent4 set) => RibbonSetNamesEvent4;
}
}