diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 372d84da8..abaa71c07 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -1849,6 +1849,10 @@ private void verifyForm() AddLine(Severity.Invalid, V311, CheckIdentifier.Form); return; } + else if (!Legal.CheckVivillonPattern(pkm.AltForm,pkm.Country,pkm.Region)) + { + AddLine(Severity.Invalid, V312, CheckIdentifier.Form); + } break; case 666: // Vivillon if (pkm.AltForm > 17) // Fancy & Pokéball @@ -1860,6 +1864,10 @@ private void verifyForm() return; } + else if (!Legal.CheckVivillonPattern(pkm.AltForm, pkm.Country, pkm.Region)) + { + AddLine(Severity.Invalid, V312, CheckIdentifier.Form); + } break; case 670: // Floette if (pkm.AltForm == 5) // Eternal Flower -- Never Released diff --git a/PKHeX/Legality/VivillonTables.cs b/PKHeX/Legality/VivillonTables.cs new file mode 100644 index 000000000..72737fa31 --- /dev/null +++ b/PKHeX/Legality/VivillonTables.cs @@ -0,0 +1,282 @@ +using System.Linq; + +namespace PKHeX.Core +{ + public static partial class Legal + { + private class CountryTable + { + public byte countryID; + public byte mainform; + public FormSubregionTable[] otherforms; + } + private class FormSubregionTable + { + public byte form; + public int[] region; + } + private static readonly int[][] VivillonCountryTable = + { + //missing ID 051,068,102,127,160,186 + // 0-Icy Snow + new[] { 018, 076, 096, 100, 107 }, + // 1-Polar + new[] { 010, 018, 020, 049, 076, 096, 100, 107 }, + // 2-Tundra + new[] { 001, 081, 096, }, + // 3-Continental + new[] { 010, 067, 073, 074, 075, 077, 078, 084, 087, 094, 096, 097, 100, 107, 136}, + // 4-Garden + new[] { 065, 082, 095, 097, 101, 110, 125}, + // 5-Elegant + new[] { 001 }, + // 6-Meadow + new[] { 066, 077, 078, 083, 086, 088, 105, 108, 122}, + // 7-Modern + new[] { 018, 049}, + // 8-Marine + new[] { 020, 064, 066, 070, 071, 073, 077, 078, 079, 080, 083, 089, 090, 091, 098, 099, 103, 105, 123, 124, 126, 184, 185}, + // 9-Archipelago + new[] { 008, 009, 011, 012, 013, 017, 021, 023, 024, 028, 029, 032, 034, 035, 036, 037, 038, 043, 044, 045, 047, 048, 049, 052, 085, 104,}, + // 10-High-Plains + new[] { 018, 036, 049, 100, 113}, + // 11-Sandstorm + new[] { 072, 109, 118, 119, 120, 121, 168, 174}, + // 12-River + new[] { 065, 069, 085, 093, 104, 105, 114, 115, 116, 117}, + // 13-Monsoon + new[] { 001, 128, 144, 169}, + // 14-Savanna + new[] { 010, 015, 016, 041, 042, 050}, + // 15-Sun + new[] { 036, 014, 019, 026, 030, 033, 036, 039, 065, 092, 106, 111, 112}, + // 16-Ocean + new[] { 049, 077}, + // 17-Jungle + new[] { 016, 021, 022, 025, 027, 031, 040, 046, 052, 169, 153, 156}, + }; + private static readonly CountryTable[] RegionFormTable = + { + new CountryTable{ + countryID = 001, // Japan + mainform = 05, // Elegant + otherforms = new[] + { + new FormSubregionTable { form = 02, region = new[] {03,04} }, + new FormSubregionTable { form = 13, region = new[] {48} }, + } + }, + new CountryTable{ + countryID = 049, // USA + mainform = 07, // Modern + otherforms = new[] + { + new FormSubregionTable { form = 01, region = new[] {03,09,21,23,24,32,33,36,40,41,48,50} }, + new FormSubregionTable { form = 09, region = new[] {53} }, + new FormSubregionTable { form = 10, region = new[] {06,07,08,15,28,34,35,39,46,49} }, + } + }, + new CountryTable{ + countryID = 018, // Canada + mainform = 01, // Polar + otherforms = new[] + { + new FormSubregionTable { form = 01, region = new[] {12,13,14} }, + new FormSubregionTable { form = 07, region = new[] {05} }, + new FormSubregionTable { form = 10, region = new[] {04} }, + } + }, + new CountryTable{ + countryID = 016, // Brazil + mainform = 14, // Savanna + otherforms = new[] + { + new FormSubregionTable { form = 17, region = new[] {03,06} }, + } + }, + new CountryTable{ + countryID = 010, // Argentina + mainform = 14, // Savanna + otherforms = new[] + { + new FormSubregionTable { form = 01, region = new[] {21,24} }, + new FormSubregionTable { form = 03, region = new[] {16} }, + } + }, + new CountryTable{ + countryID = 020, // Chile + mainform = 08, // Marine + otherforms = new[] + { + new FormSubregionTable { form = 01, region = new[] {12} }, + } + }, + new CountryTable{ + countryID = 036, // Mexico + mainform = 15, // Sun + otherforms = new[] + { + new FormSubregionTable { form = 09, region = new[] {32} }, + new FormSubregionTable { form = 10, region = new[] {04,08,09,12,15,19,20,23,26,27,29} }, + } + }, + new CountryTable{ + countryID = 052, // Venezuela + mainform = 09, // Archipelago + otherforms = new[] + { + new FormSubregionTable { form = 17, region = new[] {17} }, + } + }, + new CountryTable{ + countryID = 065, // Australia + mainform = 09, // River + otherforms = new[] + { + new FormSubregionTable { form = 04, region = new[] {07} }, + new FormSubregionTable { form = 15, region = new[] {04} }, + } + }, + new CountryTable{ + countryID = 066, // Austria + mainform = 08, // Marine + otherforms = new[] + { + new FormSubregionTable { form = 06, region = new[] {10} }, + } + }, + new CountryTable{ + countryID = 073, // Czecg Republic + mainform = 08, // Marine + otherforms = new[] + { + new FormSubregionTable { form = 03, region = new[] {03} }, + } + }, + new CountryTable{ + countryID = 076, // Finland + mainform = 00, // Icy Snow + otherforms = new[] + { + new FormSubregionTable { form = 01, region = new[] {27} }, + } + }, + new CountryTable{ + countryID = 077, // France + mainform = 06, // Meadow + otherforms = new[] + { + new FormSubregionTable { form = 03, region = new[] {18} }, + new FormSubregionTable { form = 08, region = new[] {04,06,08,19} }, + new FormSubregionTable { form = 16, region = new[] {27} }, + } + }, + new CountryTable{ + countryID = 078, // Germany + mainform = 03, // Continental + otherforms = new[] + { + new FormSubregionTable { form = 06, region = new[] {04,13} }, + new FormSubregionTable { form = 08, region = new[] {05} }, + } + }, + new CountryTable{ + countryID = 078, // Italy + mainform = 08, // Marine + otherforms = new[] + { + new FormSubregionTable { form = 06, region = new[] {04,06} }, + } + }, + new CountryTable{ + countryID = 085, // Lesotho + mainform = 09, // Archipelago ?? + otherforms = new[] + { + new FormSubregionTable { form = 12, region = new[] {04} }, + } + }, + new CountryTable{ + countryID = 096, // Norway + mainform = 03, // Continental ?? + otherforms = new[] + { + new FormSubregionTable { form = 00, region = new[] {11} }, + new FormSubregionTable { form = 01, region = new[] {12,15,16,17,20,22} }, + new FormSubregionTable { form = 02, region = new[] {13,14} }, + } + }, + new CountryTable{ + countryID = 097, // Poland + mainform = 03, // Continental + otherforms = new[] + { + new FormSubregionTable { form = 04, region = new[] {11} }, + } + }, + new CountryTable{ + countryID = 100, // Russia + mainform = 01, // Polar + otherforms = new[] + { + new FormSubregionTable { form = 00, region = new[] {14,22,34,38,40,52,66,88} }, + new FormSubregionTable { form = 03, region = new[] {29,46,51,69} }, + new FormSubregionTable { form = 10, region = new[] {20,24,25,28,33,71,73} }, + } + }, + new CountryTable{ + countryID = 104, //South Africa + mainform = 12, // River ?? + otherforms = new[] + { + new FormSubregionTable { form = 03, region = new[] {03,05} }, + } + }, + new CountryTable{ + countryID = 105, // Spain + mainform = 08, // Marine + otherforms = new[] + { + new FormSubregionTable { form = 06, region = new[] {11} }, + new FormSubregionTable { form = 12, region = new[] {07} }, + } + }, + new CountryTable{ + countryID = 107, // Sweden + mainform = 03, // Continental + otherforms = new[] + { + new FormSubregionTable { form = 00, region = new[] {11,21} }, + new FormSubregionTable { form = 01, region = new[] {09,13} }, + } + }, + new CountryTable{ + countryID = 169, // India + mainform = 13, // Monsoon ?? + otherforms = new[] + { + new FormSubregionTable { form = 17, region = new[] {12} }, + } + }, + }; + + public static bool CheckVivillonPattern(int form, int pkmcountry, int pkmregion) + { + if (VivillonCountryTable[form].Contains(pkmcountry)) + { + if (RegionFormTable.Any(ct => ct.countryID == pkmcountry)) + { + CountryTable ct = RegionFormTable.Where(t => t.countryID == pkmcountry).ToArray()[0]; + if (ct.mainform == form) + return !(ct.otherforms.SelectMany(e => e.region).Contains(pkmregion)); //true if Mainform not in other specific region + else + return ct.otherforms.Any(e => e.form == form && e.region.Contains(pkmregion)); + } + else + return true; // No subregion + } + else + return false; // Country mismatch + } + } +} \ No newline at end of file diff --git a/PKHeX/PKHeX.Core.csproj b/PKHeX/PKHeX.Core.csproj index 6d6380b34..855a7bc08 100644 --- a/PKHeX/PKHeX.Core.csproj +++ b/PKHeX/PKHeX.Core.csproj @@ -175,6 +175,7 @@ + @@ -711,10 +712,8 @@ - - @@ -837,7 +836,6 @@ - diff --git a/PKHeX/Resources/text/zh/legality_zh.txt b/PKHeX/Resources/text/zh/legality_zh.txt index fdc137dfe..f0cfe2db3 100644 --- a/PKHeX/Resources/text/zh/legality_zh.txt +++ b/PKHeX/Resources/text/zh/legality_zh.txt @@ -59,8 +59,8 @@ V26 = 单项努力值不能超过252。 V27 = 所有努力值相等。 V31 = 所有个体为0。 V32 = 所有个体值相等。 -V28 = 至少有 {0} 项个体值 {get; set;} = 31。 -V29 = 在朋友原野区捕获的宝可梦至少有两项个体 {get; set;} = 31。 +V28 = 至少有 {0} 项个体值 = 31。 +V29 = 在朋友原野区捕获的宝可梦至少有两项个体 = 31。 V30 = 个体值与神秘礼物数据不一致。 V38 = 初训家名称太长。 V39 = 不正确初代四色配信初训家名。 @@ -142,9 +142,10 @@ V108 = 隐藏特性与相遇方式不一致。 V109 = 特性被特性胶囊改变。 V110 = 特性与神秘礼物不一致。 V111 = 非帮手宝可梦拥有隐藏特性。 -V300 = Hidden Ability on non-horde/friend safari wild encounter. +V300 = 在非群战/朋友原野区获得隐藏特性。 V112 = 隐藏特性不可获得。 V217 = 隐藏洞穴捕获的宝可梦必定为隐藏特性。 +V218 = 在野外普通相遇不可能有隐藏特性。 V115 = 特性与特性值一致。 V113 = 特性与PID不一致。 V114 = 特性与特性值不一致。 @@ -164,15 +165,15 @@ V127 = 跳过历史检查,因为其他检查已经为不合法。 V128 = 没有历史数据块供检查。 V129 = 初训家牵绊度应为0。 V130 = 不能为任意OT回忆。 -V124 = 对于前代传送的宝可梦,当前持有人不能为前代初训家。 +V124 = 对于通过前代传送获得的宝可梦,当前持有人不能为前代初训家。 V131 = 持有人性别不合法: {0} V132 = 配信的初训家亲密度与初始亲密度不一致。 V133 = 配信的初训家牵绊度应为0。 V134 = 当前持有人不能为配信的初训家。 V138 = 华丽大赛状态值应为0。 -V301 = Invalid Console Region. -V302 = Geolocation: Country is not in 3DS region. -V303 = Geolocation: Country is in 3DS region. +V301 = 不合法主机系统。 +V302 = 地理位置: 国家不在3DS区域内。 +V303 = 地理位置: 国家在3DS区域内。 V137 = 地理位置回忆: 回忆应该存在。 V135 = 地理位置回忆: 间隔/空白存在。 V136 = 地理位置回忆: 地区没有国家。 @@ -187,7 +188,7 @@ V144 = 未交换: 美丽度足够但仍为1级。 V148 = 回忆: 持有人回忆里没有持有人的名字。 V150 = 回忆: 缺失持有人回忆。 V152 = 回忆: 缺失初训家回忆。 -V329 = Memory: Not cleared properly. +V329 = 回忆: 未完全清理。 V149 = 回忆: 蛋不能作为持有人的回忆。 V151 = 回忆: 蛋不能作为初训家的回忆。 V164 = {0} 回忆: 当前种类能在游戏中捕获。 @@ -204,8 +205,8 @@ V198 = {0} 回忆: 回忆强度应为序号 {1}。 V199 = {0} 回忆: 文本值应为序号 {1}。 V200 = {0} 回忆: 感受应为序号 {1}。 V168 = 重复招式。 -V176 = 无效招式。 -V166 = 无效招式 (写生)。 +V176 = 不合法招式。 +V166 = 不合法招式 (写生)。 V169 = 凯路迪欧的招式与形态不匹配。 V181 = 应为以下可回忆招式: {0} V170 = 缺失可回忆招式: {0} @@ -221,28 +222,28 @@ V156 = 应该有连接交换持有人的回忆。 V157 = 持有人回忆文本值(某处)。 V158 = 持有人回忆强度值应为(1st)。 V159 = 持有人回忆感受值应为0-9。 -V318 = Form is Valid. -V304 = Form Count is out of range. Expected <= {0}, got {1}. -V305 = Cosplay Pikachu cannot have the default form. -V306 = Only Cosplay Pikachu can have this form. -V307 = Event Pikachu cannot have the default form. -V308 = Held item does not match Form. -V309 = Held item matches Form. -V310 = Form cannot exist outside of a battle. -V311 = Event Vivillon pattern on pre-evolution. -V312 = Invalid Vivillon pattern. -V313 = Valid Vivillon pattern. -V314 = Invalid Eternal Flower encounter. -V315 = Valid Eternal Flower encounter. -V316 = Form cannot exist outside of Party. -V317 = Form cannot be obtained for pre-Alola generation games. -V319 = Cannot apply PP Ups to an Egg. -V320 = Cannot increase Contest Stats of an Egg. -V321 = Mystery Gift Fateful Encounter. -V322 = Mystery Gift Fateful Encounter flag missing. -V323 = Special ingame Fateful Encounter. -V324 = Special ingame Fateful Encounter flag missing. -V325 = Fateful Encounter should not be checked. -V326 = Special ingame N's Sparkle flag missing. -V327 = Special ingame N's Sparkle flag should not be checked. -V328 = Version Specific evolution requires a trade to opposite version. A Handling Trainer is required. \ No newline at end of file +V318 = 不合法形态。 +V304 = 形态数超过最大值。 应该 <= {0}, 实际是 {1}。 +V305 = 换装皮卡丘不能有普通形态。 +V306 = 只有换装皮卡丘能有该形态。 +V307 = 配信皮卡丘不能有普通形态。 +V308 = 持有物与形态不一致。 +V309 = 持有物与形态一致。 +V310 = 该形态不可能存在对战外。 +V311 = 退化形态拥有配信彩粉蝶花纹。 +V312 = 不合法彩粉蝶花纹。 +V313 = 合法彩粉蝶花纹。 +V314 = 花丛遇见不合法。 +V315 = 花丛遇见合法。 +V316 = 该形态不可能存在队伍外。 +V317 = 该形态不能在阿罗拉以前的世代获得。 +V319 = 不能对蛋使用PP提升剂。 +V320 = 不能增加蛋的华丽大赛状态。 +V321 = 神秘礼物命中注定般的遇见。 +V322 = 神秘礼物缺失命中注定般的遇见。 +V323 = 特殊游戏内宝可梦命中注定般的遇见。 +V324 = 特殊游戏内宝可梦缺失命中注定般的遇见。 +V325 = 命中注定般的遇见不应被勾选。 +V326 = 特殊游戏内宝可梦N的闪光标记缺失。 +V327 = 特殊游戏内宝可梦N的闪光标记不应勾选。 +V328 = 版本特定进化需要。 需要一个最近持有人。 \ No newline at end of file diff --git a/PKHeX/Resources/text/zh/text_Games_zh.txt b/PKHeX/Resources/text/zh/text_Games_zh.txt index 9f26c7f3e..668ee3dee 100644 --- a/PKHeX/Resources/text/zh/text_Games_zh.txt +++ b/PKHeX/Resources/text/zh/text_Games_zh.txt @@ -33,7 +33,7 @@ Y Go -紅 -藍色[INT]/綠色[JP] -藍色[JP] -黃色 \ No newline at end of file +红 +蓝[国际]/绿[日] +蓝[日] +黄 \ No newline at end of file