2016-03-12 17:16:41 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2017-03-25 17:24:56 +00:00
|
|
|
|
using static PKHeX.Core.LegalityCheckStrings;
|
2016-03-11 04:36:32 +00:00
|
|
|
|
|
2017-01-08 07:54:09 +00:00
|
|
|
|
namespace PKHeX.Core
|
2016-03-11 04:36:32 +00:00
|
|
|
|
{
|
|
|
|
|
public enum Severity
|
|
|
|
|
{
|
|
|
|
|
Indeterminate = -2,
|
|
|
|
|
Invalid = -1,
|
|
|
|
|
Fishy = 0,
|
|
|
|
|
Valid = 1,
|
|
|
|
|
NotImplemented = 2,
|
|
|
|
|
}
|
2017-01-08 07:54:09 +00:00
|
|
|
|
internal enum CheckIdentifier
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
|
|
|
|
Move,
|
|
|
|
|
RelearnMove,
|
|
|
|
|
Encounter,
|
|
|
|
|
History,
|
|
|
|
|
ECPID,
|
|
|
|
|
Shiny,
|
|
|
|
|
EC,
|
|
|
|
|
PID,
|
|
|
|
|
Gender,
|
|
|
|
|
EVs,
|
|
|
|
|
Language,
|
2017-02-15 01:33:57 +00:00
|
|
|
|
Nickname,
|
2016-10-23 19:48:49 +00:00
|
|
|
|
Trainer,
|
|
|
|
|
IVs,
|
|
|
|
|
None,
|
|
|
|
|
Level,
|
|
|
|
|
Ball,
|
|
|
|
|
Memory,
|
|
|
|
|
Geography,
|
|
|
|
|
Form,
|
|
|
|
|
Egg,
|
|
|
|
|
Misc,
|
|
|
|
|
Fateful,
|
|
|
|
|
Ribbon,
|
|
|
|
|
Training,
|
2016-12-01 03:37:53 +00:00
|
|
|
|
Ability,
|
2016-12-02 02:48:38 +00:00
|
|
|
|
Evolution,
|
2017-03-25 17:24:56 +00:00
|
|
|
|
Special,
|
|
|
|
|
Nature
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
|
|
|
|
public class CheckResult
|
2016-03-11 04:36:32 +00:00
|
|
|
|
{
|
2017-01-08 07:54:09 +00:00
|
|
|
|
internal readonly Severity Judgement = Severity.Valid;
|
2017-03-21 07:18:38 +00:00
|
|
|
|
internal string Comment = V;
|
2016-03-11 04:36:32 +00:00
|
|
|
|
public bool Valid => Judgement >= Severity.Fishy;
|
2016-03-25 07:10:11 +00:00
|
|
|
|
public bool Flag;
|
2017-03-18 23:17:42 +00:00
|
|
|
|
internal readonly CheckIdentifier Identifier;
|
2016-03-11 04:36:32 +00:00
|
|
|
|
|
2017-02-15 06:06:15 +00:00
|
|
|
|
internal CheckResult(CheckIdentifier i) { Identifier = i; }
|
2017-01-08 07:54:09 +00:00
|
|
|
|
internal CheckResult(Severity s, string c, CheckIdentifier i)
|
2016-03-11 04:36:32 +00:00
|
|
|
|
{
|
|
|
|
|
Judgement = s;
|
|
|
|
|
Comment = c;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
Identifier = i;
|
2016-03-11 04:36:32 +00:00
|
|
|
|
}
|
2016-03-14 03:19:04 +00:00
|
|
|
|
}
|
|
|
|
|
public partial class LegalityAnalysis
|
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyGender()
|
2016-07-04 01:36:04 +00:00
|
|
|
|
{
|
2016-10-29 06:41:22 +00:00
|
|
|
|
if (pkm.PersonalInfo.Gender == 255 && pkm.Gender != 2)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V203, CheckIdentifier.Gender);
|
2017-03-25 17:24:56 +00:00
|
|
|
|
|
|
|
|
|
// Check for PID relationship to Gender & Nature if applicable
|
|
|
|
|
int gen = pkm.GenNumber;
|
|
|
|
|
|
|
|
|
|
bool PIDGender = 3 <= gen && gen <= 5;
|
|
|
|
|
if (!PIDGender)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
bool genderValid = pkm.getGenderIsValid();
|
|
|
|
|
if (!genderValid && pkm.Format > 5 && (pkm.Species == 183 || pkm.Species == 184))
|
|
|
|
|
{
|
|
|
|
|
var gv = pkm.PID & 0xFF;
|
|
|
|
|
if (gv > 63 && pkm.Gender == 1) // evolved from azurill after transferring to keep gender
|
|
|
|
|
genderValid = true;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
|
|
|
|
|
if (genderValid)
|
|
|
|
|
AddLine(Severity.Valid, V250, CheckIdentifier.Gender);
|
|
|
|
|
else
|
|
|
|
|
AddLine(Severity.Invalid, V251, CheckIdentifier.Gender);
|
|
|
|
|
|
|
|
|
|
bool PIDNature = gen != 5;
|
|
|
|
|
if (!PIDNature)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (pkm.PID % 25 == pkm.Nature)
|
|
|
|
|
AddLine(Severity.Valid, V252, CheckIdentifier.Nature);
|
|
|
|
|
else
|
|
|
|
|
AddLine(Severity.Invalid, V253, CheckIdentifier.Nature);
|
2016-07-04 01:36:04 +00:00
|
|
|
|
}
|
2017-02-26 15:55:22 +00:00
|
|
|
|
private void verifyItem()
|
|
|
|
|
{
|
2017-02-26 19:43:26 +00:00
|
|
|
|
if (!Legal.getHeldItemAllowed(pkm.Format, pkm.HeldItem))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V204, CheckIdentifier.Form);
|
2017-02-26 15:55:22 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyECPID()
|
2016-03-11 04:36:32 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.EncryptionConstant == 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V201, CheckIdentifier.EC);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
|
|
|
|
if (pkm.PID == 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V207, CheckIdentifier.PID);
|
2016-03-11 04:36:32 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.GenNumber >= 6 && pkm.PID == pkm.EncryptionConstant)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V208, CheckIdentifier.PID);
|
2016-03-11 04:36:32 +00:00
|
|
|
|
|
2016-06-20 04:22:43 +00:00
|
|
|
|
if (EncounterType == typeof (EncounterStatic))
|
|
|
|
|
{
|
|
|
|
|
var enc = (EncounterStatic) EncounterMatch;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (enc.Shiny != null && (bool) enc.Shiny ^ pkm.IsShiny)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V209, CheckIdentifier.Shiny);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
2017-04-02 13:39:39 +00:00
|
|
|
|
if (EncounterType == typeof(EncounterSlot[]))
|
|
|
|
|
{
|
|
|
|
|
if (pkm.IsShiny && (EncounterMatch as EncounterSlot[]).All(slot => slot.Type == SlotType.HiddenGrotto))
|
|
|
|
|
{
|
|
|
|
|
AddLine(Severity.Invalid, V221, CheckIdentifier.Shiny);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
int wIndex = Array.IndexOf(Legal.WurmpleEvolutions, pkm.Species);
|
|
|
|
|
if (pkm.GenNumber >= 6)
|
2016-04-08 00:56:39 +00:00
|
|
|
|
{
|
2016-04-21 07:28:40 +00:00
|
|
|
|
// Wurmple -> Silcoon/Cascoon
|
|
|
|
|
if (wIndex > -1)
|
|
|
|
|
{
|
|
|
|
|
// Check if Wurmple was the origin (only Egg and Wild Encounter)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.WasEgg || (EncounterType == typeof(EncounterSlot[]) && (EncounterMatch as EncounterSlot[]).All(slot => slot.Species == 265)))
|
|
|
|
|
if ((pkm.EncryptionConstant >> 16)%10/5 != wIndex/2)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V210, CheckIdentifier.EC);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (pkm.Species == 265)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, string.Format(V212, (pkm.EncryptionConstant >> 16)%10/5 == 0 ? V213 : V214), CheckIdentifier.EC);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int xor = pkm.TSV ^ pkm.PSV;
|
|
|
|
|
if (xor < 16 && xor >= 8 && (pkm.PID ^ 0x80000000) == pkm.EncryptionConstant)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V211, CheckIdentifier.EC);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-04-21 07:28:40 +00:00
|
|
|
|
}
|
2016-04-08 00:56:39 +00:00
|
|
|
|
}
|
2017-02-14 02:06:01 +00:00
|
|
|
|
|
|
|
|
|
// abort if specimen wasn't transferred x->6
|
|
|
|
|
if (pkm.Format < 6 || !(3 <= pkm.GenNumber && pkm.GenNumber <= 5))
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2016-03-11 04:36:32 +00:00
|
|
|
|
// When transferred to Generation 6, the Encryption Constant is copied from the PID.
|
|
|
|
|
// The PID is then checked to see if it becomes shiny with the new Shiny rules (>>4 instead of >>3)
|
|
|
|
|
// If the PID is nonshiny->shiny, the top bit is flipped.
|
|
|
|
|
|
|
|
|
|
// Check to see if the PID and EC are properly configured.
|
2016-12-23 02:18:35 +00:00
|
|
|
|
bool xorPID = ((pkm.TID ^ pkm.SID ^ (int)(pkm.PID & 0xFFFF) ^ (int)(pkm.PID >> 16)) & ~0x7) == 8;
|
2016-03-11 04:36:32 +00:00
|
|
|
|
bool valid = xorPID
|
2016-10-23 19:48:49 +00:00
|
|
|
|
? pkm.EncryptionConstant == (pkm.PID ^ 0x8000000)
|
|
|
|
|
: pkm.EncryptionConstant == pkm.PID;
|
2016-03-11 04:36:32 +00:00
|
|
|
|
|
|
|
|
|
if (!valid)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
|
|
|
|
AddLine(Severity.Invalid,
|
|
|
|
|
xorPID
|
2017-03-21 07:18:38 +00:00
|
|
|
|
? V215
|
|
|
|
|
: V216, CheckIdentifier.ECPID);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
2016-03-11 04:36:32 +00:00
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyNickname()
|
2016-03-11 04:36:32 +00:00
|
|
|
|
{
|
|
|
|
|
// If the Pokémon is not nicknamed, it should match one of the language strings.
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.Nickname.Length == 0)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V2, CheckIdentifier.Nickname);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (pkm.Species > PKX.SpeciesLang[0].Length)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Indeterminate, V3, CheckIdentifier.Nickname);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-27 05:35:26 +00:00
|
|
|
|
if (pkm.VC)
|
|
|
|
|
{
|
|
|
|
|
string pk = pkm.Nickname;
|
|
|
|
|
var langset = PKX.SpeciesLang.FirstOrDefault(s => s.Contains(pk)) ?? PKX.SpeciesLang[2];
|
|
|
|
|
int lang = Array.IndexOf(PKX.SpeciesLang, langset);
|
|
|
|
|
|
|
|
|
|
if (pk.Length > (lang == 2 ? 10 : 5))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V1, CheckIdentifier.Nickname);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-20 01:06:02 +00:00
|
|
|
|
if (!Encounter.Valid)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (pkm.Format <= 6 && pkm.Language > 8)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Indeterminate, V4, CheckIdentifier.Language);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-11-09 16:23:47 +00:00
|
|
|
|
if (pkm.Format <= 7 && pkm.Language > 10)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Indeterminate, V5, CheckIdentifier.Language);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-28 05:05:51 +00:00
|
|
|
|
if (EncounterType == typeof(EncounterTrade))
|
2016-03-27 00:23:53 +00:00
|
|
|
|
{
|
2017-03-25 17:24:56 +00:00
|
|
|
|
verifyNicknameTrade();
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-03-27 00:23:53 +00:00
|
|
|
|
}
|
2016-03-20 01:06:02 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.IsEgg)
|
2016-03-16 04:15:40 +00:00
|
|
|
|
{
|
2017-03-25 17:24:56 +00:00
|
|
|
|
verifyNicknameEgg();
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-03-16 04:15:40 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
|
|
|
|
string nickname = pkm.Nickname.Replace("'", "’");
|
|
|
|
|
if (pkm.IsNicknamed)
|
2016-03-11 04:36:32 +00:00
|
|
|
|
{
|
2016-03-20 01:06:02 +00:00
|
|
|
|
for (int i = 0; i < PKX.SpeciesLang.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
string[] lang = PKX.SpeciesLang[i];
|
|
|
|
|
int index = Array.IndexOf(lang, nickname);
|
|
|
|
|
if (index < 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
AddLine(Severity.Fishy, index == pkm.Species && i != pkm.Language
|
2017-03-21 07:18:38 +00:00
|
|
|
|
? V15
|
|
|
|
|
: V16, CheckIdentifier.Nickname);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-03-20 01:06:02 +00:00
|
|
|
|
}
|
2017-04-04 03:02:40 +00:00
|
|
|
|
if (nickname.Any(c => 0x4E00 <= c && c <= 0x9FFF)) // East Asian Scripts
|
|
|
|
|
{
|
|
|
|
|
AddLine(Severity.Invalid, V222, CheckIdentifier.Nickname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V17, CheckIdentifier.Nickname);
|
2016-03-16 01:56:18 +00:00
|
|
|
|
}
|
2017-02-13 01:00:03 +00:00
|
|
|
|
else if (pkm.Format < 3)
|
|
|
|
|
{
|
|
|
|
|
// pk1/pk2 IsNicknamed getter checks for match, logic should only reach here if matches.
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V18, CheckIdentifier.Nickname);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2016-03-16 01:56:18 +00:00
|
|
|
|
{
|
2016-07-11 05:22:55 +00:00
|
|
|
|
// Can't have another language name if it hasn't evolved or wasn't a language-traded egg.
|
2017-03-19 22:40:49 +00:00
|
|
|
|
bool match = PKX.getSpeciesNameGeneration(pkm.Species, pkm.Language, pkm.Format) == nickname;
|
2017-03-25 17:24:56 +00:00
|
|
|
|
if (pkm.WasTradedEgg || Legal.getHasEvolved(pkm))
|
|
|
|
|
match |= !PKX.getIsNicknamedAnyLanguage(pkm.Species, nickname, pkm.Format);
|
|
|
|
|
if (pkm.Format == 5 && !pkm.IsNative) // transfer
|
|
|
|
|
match |= PKX.getSpeciesNameGeneration(pkm.Species, pkm.Language, 4) == nickname;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
|
|
|
|
if (!match)
|
2017-02-21 06:03:07 +00:00
|
|
|
|
{
|
|
|
|
|
if ((EncounterMatch as MysteryGift)?.CardID == 2046 && (pkm.SID << 16 | pkm.TID) == 0x79F57B49)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V19, CheckIdentifier.Nickname);
|
2017-02-21 06:03:07 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V20, CheckIdentifier.Nickname);
|
2017-02-21 06:03:07 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V18, CheckIdentifier.Nickname);
|
2016-03-11 04:36:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
private void verifyNicknameEgg()
|
|
|
|
|
{
|
|
|
|
|
if (!pkm.IsNicknamed && (pkm.Format != 7))
|
|
|
|
|
AddLine(Severity.Invalid, V12, CheckIdentifier.Egg);
|
|
|
|
|
else if (PKX.SpeciesLang[pkm.Language][0] != pkm.Nickname)
|
|
|
|
|
AddLine(Severity.Invalid, V13, CheckIdentifier.Egg);
|
|
|
|
|
else
|
|
|
|
|
AddLine(Severity.Valid, V14, CheckIdentifier.Egg);
|
|
|
|
|
}
|
|
|
|
|
private void verifyNicknameTrade()
|
|
|
|
|
{
|
|
|
|
|
string[] validOT = new string[0];
|
|
|
|
|
int index = -1;
|
|
|
|
|
if (pkm.XY)
|
|
|
|
|
{
|
|
|
|
|
validOT = Legal.TradeXY[pkm.Language];
|
|
|
|
|
index = Array.IndexOf(Legal.TradeGift_XY, EncounterMatch);
|
|
|
|
|
}
|
|
|
|
|
else if (pkm.AO)
|
|
|
|
|
{
|
|
|
|
|
validOT = Legal.TradeAO[pkm.Language];
|
|
|
|
|
index = Array.IndexOf(Legal.TradeGift_AO, EncounterMatch);
|
|
|
|
|
}
|
|
|
|
|
else if (pkm.SM)
|
|
|
|
|
{
|
|
|
|
|
// TODO
|
|
|
|
|
AddLine(Severity.Valid, V194, CheckIdentifier.Nickname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if (pkm.Format <= 2 || pkm.VC)
|
|
|
|
|
{
|
|
|
|
|
var et = EncounterOriginal as EncounterTrade;
|
|
|
|
|
if (et?.TID == 0) // Gen1 Trade
|
|
|
|
|
{
|
|
|
|
|
if (!Legal.getEncounterTrade1Valid(pkm))
|
|
|
|
|
AddLine(Severity.Invalid, V10, CheckIdentifier.Trainer);
|
|
|
|
|
}
|
|
|
|
|
else // Gen2
|
|
|
|
|
{
|
|
|
|
|
return; // already checked all relevant properties when fetching with getValidEncounterTradeVC2
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-30 06:31:02 +00:00
|
|
|
|
else if (3 <= pkm.Format && pkm.Format <= 5)
|
|
|
|
|
{
|
|
|
|
|
// Suppressing temporarily
|
2017-03-28 09:02:46 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-25 17:24:56 +00:00
|
|
|
|
if (validOT.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
AddLine(Severity.Indeterminate, V7, CheckIdentifier.Trainer);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (index == -1 || validOT.Length < index * 2)
|
|
|
|
|
{
|
|
|
|
|
AddLine(Severity.Indeterminate, V8, CheckIdentifier.Trainer);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string nick = validOT[index];
|
|
|
|
|
string OT = validOT[validOT.Length / 2 + index];
|
|
|
|
|
|
|
|
|
|
if (nick != pkm.Nickname)
|
|
|
|
|
AddLine(Severity.Fishy, V9, CheckIdentifier.Nickname);
|
|
|
|
|
else if (OT != pkm.OT_Name)
|
|
|
|
|
AddLine(Severity.Invalid, V10, CheckIdentifier.Trainer);
|
|
|
|
|
else
|
|
|
|
|
AddLine(Severity.Valid, V11, CheckIdentifier.Nickname);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyEVs()
|
2016-03-11 04:36:32 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
var evs = pkm.EVs;
|
2016-03-14 03:19:04 +00:00
|
|
|
|
int sum = evs.Sum();
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.IsEgg && sum > 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V22, CheckIdentifier.EVs);
|
2017-03-25 17:24:56 +00:00
|
|
|
|
else if (sum == 0 && pkm.CurrentLevel - Math.Max(1, pkm.Met_Level) > 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V23, CheckIdentifier.EVs);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (sum == 508)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V24, CheckIdentifier.EVs);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (sum > 510)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V25, CheckIdentifier.EVs);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (pkm.Format >= 6 && evs.Any(ev => ev > 252))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V26, CheckIdentifier.EVs);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (evs.All(ev => pkm.EVs[0] == ev) && evs[0] != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V27, CheckIdentifier.EVs);
|
2016-03-11 04:36:32 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyIVs()
|
2016-03-11 04:36:32 +00:00
|
|
|
|
{
|
2017-03-10 04:27:03 +00:00
|
|
|
|
var e = EncounterMatch as EncounterStatic;
|
2017-01-01 01:20:13 +00:00
|
|
|
|
if ((EncounterMatch as EncounterStatic)?.IV3 == true)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
2017-03-10 04:27:03 +00:00
|
|
|
|
int IVCount = 3;
|
|
|
|
|
if (e.Version == GameVersion.RBY && pkm.Species == 151)
|
|
|
|
|
IVCount = 5; // VC Mew
|
|
|
|
|
if (pkm.IVs.Count(iv => iv == 31) < IVCount)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V28, IVCount), CheckIdentifier.IVs);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-01-01 01:20:13 +00:00
|
|
|
|
if ((EncounterMatch as EncounterSlot[])?.All(slot => slot.Type == SlotType.FriendSafari) == true)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.IVs.Count(iv => iv == 31) < 2)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V29, CheckIdentifier.IVs);
|
2017-01-01 01:20:13 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-02-02 05:27:14 +00:00
|
|
|
|
if (EncounterIsMysteryGift)
|
|
|
|
|
{
|
|
|
|
|
int[] IVs;
|
|
|
|
|
switch (((MysteryGift) EncounterMatch).Format)
|
|
|
|
|
{
|
|
|
|
|
case 7: IVs = ((WC7)EncounterMatch).IVs; break;
|
2017-03-10 04:27:03 +00:00
|
|
|
|
case 6: IVs = ((WC6)EncounterMatch).IVs; break;
|
|
|
|
|
case 5: IVs = ((PGF)EncounterMatch).IVs; break;
|
2017-02-02 05:27:14 +00:00
|
|
|
|
default: IVs = null; break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IVs != null)
|
|
|
|
|
{
|
|
|
|
|
var pkIVs = pkm.IVs;
|
|
|
|
|
bool valid = true;
|
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
|
if (IVs[i] <= 31 && IVs[i] != pkIVs[i])
|
|
|
|
|
valid = false;
|
|
|
|
|
if (!valid)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V30, CheckIdentifier.IVs);
|
2017-02-02 05:27:14 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.IVs.Sum() == 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V31, CheckIdentifier.IVs);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (pkm.IVs[0] < 30 && pkm.IVs.All(iv => pkm.IVs[0] == iv))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V32, CheckIdentifier.IVs);
|
2016-03-11 04:36:32 +00:00
|
|
|
|
}
|
2017-02-13 01:00:03 +00:00
|
|
|
|
private void verifyDVs()
|
|
|
|
|
{
|
|
|
|
|
// todo
|
|
|
|
|
}
|
2017-01-27 05:35:26 +00:00
|
|
|
|
private void verifyOT()
|
2016-03-11 04:36:32 +00:00
|
|
|
|
{
|
2016-04-08 05:27:36 +00:00
|
|
|
|
if (EncounterType == typeof(EncounterTrade))
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return; // Already matches Encounter Trade information
|
|
|
|
|
|
|
|
|
|
if (pkm.TID == 0 && pkm.SID == 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V33, CheckIdentifier.Trainer);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
else if (pkm.VC)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.SID != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V34, CheckIdentifier.Trainer);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (pkm.TID == pkm.SID)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V35, CheckIdentifier.Trainer);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (pkm.TID == 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V36, CheckIdentifier.Trainer);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (pkm.SID == 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V37, CheckIdentifier.Trainer);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
|
|
|
|
|
if (pkm.VC)
|
2017-02-13 01:00:03 +00:00
|
|
|
|
verifyG1OT();
|
|
|
|
|
}
|
|
|
|
|
private void verifyG1OT()
|
|
|
|
|
{
|
|
|
|
|
string tr = pkm.OT_Name;
|
|
|
|
|
string pk = pkm.Nickname;
|
|
|
|
|
var langset = PKX.SpeciesLang.FirstOrDefault(s => s.Contains(pk)) ?? PKX.SpeciesLang[2];
|
|
|
|
|
int lang = Array.IndexOf(PKX.SpeciesLang, langset);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
|
2017-02-13 01:00:03 +00:00
|
|
|
|
if (tr.Length > (lang == 2 ? 7 : 5))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V38, CheckIdentifier.Trainer);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
if (pkm.Species == 151)
|
|
|
|
|
{
|
|
|
|
|
if (tr != "GF" && tr != "ゲーフリ") // if there are more events with special OTs, may be worth refactoring
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V39, CheckIdentifier.Trainer);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
}
|
2016-03-11 04:36:32 +00:00
|
|
|
|
}
|
2016-11-11 10:31:50 +00:00
|
|
|
|
|
|
|
|
|
private void verifyHyperTraining()
|
|
|
|
|
{
|
|
|
|
|
if (pkm.Format < 7)
|
|
|
|
|
return; // No Hyper Training before Gen VII
|
|
|
|
|
|
|
|
|
|
var IVs = new[] { pkm.IV_HP, pkm.IV_ATK, pkm.IV_DEF, pkm.IV_SPA, pkm.IV_SPD, pkm.IV_SPE };
|
|
|
|
|
var HTs = new[] { pkm.HT_HP, pkm.HT_ATK, pkm.HT_DEF, pkm.HT_SPA, pkm.HT_SPD, pkm.HT_SPE };
|
2016-11-11 11:23:38 +00:00
|
|
|
|
|
|
|
|
|
if (HTs.Any(ht => ht) && pkm.CurrentLevel != 100)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V40, CheckIdentifier.IVs);
|
2016-11-11 11:23:38 +00:00
|
|
|
|
|
2016-11-11 10:31:50 +00:00
|
|
|
|
if (IVs.All(iv => iv == 31) && HTs.Any(ht => ht))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V41, CheckIdentifier.IVs);
|
2016-11-11 10:31:50 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 6; i++) // Check individual IVs
|
|
|
|
|
{
|
|
|
|
|
if ((IVs[i] == 31) && HTs[i])
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V42, CheckIdentifier.IVs);
|
2016-11-11 10:31:50 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-02-13 01:00:03 +00:00
|
|
|
|
|
|
|
|
|
private CheckResult verifyEncounterLink()
|
2016-03-12 03:43:40 +00:00
|
|
|
|
{
|
2017-02-13 01:00:03 +00:00
|
|
|
|
// Should NOT be Fateful, and should be in Database
|
|
|
|
|
EncounterLink enc = EncounterMatch as EncounterLink;
|
|
|
|
|
if (enc == null)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V43, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
|
|
|
|
|
if (pkm.XY && !enc.XY)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V44, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
if (pkm.AO && !enc.ORAS)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V45, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
|
|
|
|
|
if (enc.Shiny != null && (bool)enc.Shiny ^ pkm.IsShiny)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V47, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
|
|
|
|
|
return pkm.FatefulEncounter
|
2017-03-21 07:18:38 +00:00
|
|
|
|
? new CheckResult(Severity.Invalid, V48, CheckIdentifier.Encounter)
|
|
|
|
|
: new CheckResult(Severity.Valid, V49, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyEncounterEvent()
|
|
|
|
|
{
|
|
|
|
|
MysteryGift MatchedGift = EncounterMatch as MysteryGift;
|
2017-03-25 17:24:56 +00:00
|
|
|
|
if (MatchedGift == null)
|
|
|
|
|
return null;
|
|
|
|
|
return new CheckResult(Severity.Valid, string.Format(V21, MatchedGift.CardID.ToString("0000"), MatchedGift.CardTitle), CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
}
|
2017-03-20 04:36:03 +00:00
|
|
|
|
|
2017-02-13 01:00:03 +00:00
|
|
|
|
private CheckResult verifyEncounterEgg()
|
|
|
|
|
{
|
2017-03-20 04:36:03 +00:00
|
|
|
|
// Check Species
|
2017-04-01 01:35:43 +00:00
|
|
|
|
if (Legal.NoHatchFromEgg.Contains(pkm.Species) && EncounterMatch == null)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V50, CheckIdentifier.Encounter);
|
2017-04-01 16:45:13 +00:00
|
|
|
|
if (pkm.WasGiftEgg && EncounterMatch == null)
|
|
|
|
|
return new CheckResult(Severity.Invalid, V359, CheckIdentifier.Encounter);
|
|
|
|
|
if (pkm.WasEventEgg && EncounterMatch == null)
|
|
|
|
|
return new CheckResult(Severity.Invalid, V360, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
switch (pkm.GenNumber)
|
2017-01-27 05:35:26 +00:00
|
|
|
|
{
|
2017-03-20 04:36:03 +00:00
|
|
|
|
case 1:
|
|
|
|
|
case 2: return new CheckResult(CheckIdentifier.Encounter); // no met location info
|
|
|
|
|
case 3: return verifyEncounterEgg3();
|
|
|
|
|
case 4: return pkm.IsEgg ? verifyUnhatchedEgg(2002) : verifyEncounterEgg4();
|
|
|
|
|
case 5: return pkm.IsEgg ? verifyUnhatchedEgg(30002) : verifyEncounterEgg5();
|
|
|
|
|
case 6: return pkm.IsEgg ? verifyUnhatchedEgg(30002) : verifyEncounterEgg6();
|
|
|
|
|
case 7: return pkm.IsEgg ? verifyUnhatchedEgg(30002) : verifyEncounterEgg7();
|
|
|
|
|
|
|
|
|
|
default: // none of the above
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V51, CheckIdentifier.Encounter);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
}
|
2017-03-20 04:36:03 +00:00
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyEncounterEgg3()
|
|
|
|
|
{
|
2017-03-25 17:24:56 +00:00
|
|
|
|
return pkm.Format == 3 ? verifyEncounterEgg3Native() : verifyEncounterEgg3Transfer();
|
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyEncounterEgg3Native()
|
|
|
|
|
{
|
|
|
|
|
if (pkm.Met_Level != 0)
|
|
|
|
|
return new CheckResult(Severity.Invalid, string.Format(V52, 0), CheckIdentifier.Encounter);
|
|
|
|
|
if (pkm.IsEgg)
|
2017-02-13 01:00:03 +00:00
|
|
|
|
{
|
2017-03-25 18:02:33 +00:00
|
|
|
|
var loc = pkm.FRLG ? Legal.ValidEggMet_FRLG : Legal.ValidEggMet_RSE;
|
|
|
|
|
if (!loc.Contains(pkm.Met_Location))
|
2017-03-25 17:24:56 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V55, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
}
|
2017-03-20 04:36:03 +00:00
|
|
|
|
else
|
2017-02-13 01:00:03 +00:00
|
|
|
|
{
|
2017-03-25 17:24:56 +00:00
|
|
|
|
var locs = pkm.FRLG ? Legal.ValidMet_FRLG : pkm.E ? Legal.ValidMet_E : Legal.ValidMet_RS;
|
|
|
|
|
if (locs.Contains(pkm.Met_Location))
|
|
|
|
|
return new CheckResult(Severity.Valid, V53, CheckIdentifier.Encounter);
|
|
|
|
|
if (Legal.ValidMet_FRLG.Contains(pkm.Met_Location) || Legal.ValidMet_E.Contains(pkm.Met_Location) || Legal.ValidMet_RS.Contains(pkm.Met_Location))
|
|
|
|
|
return new CheckResult(Severity.Valid, V56, CheckIdentifier.Encounter);
|
|
|
|
|
return new CheckResult(Severity.Invalid, V54, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V53, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
private CheckResult verifyEncounterEgg3Transfer()
|
|
|
|
|
{
|
|
|
|
|
if (pkm.IsEgg)
|
|
|
|
|
return new CheckResult(Severity.Invalid, V57, CheckIdentifier.Encounter);
|
|
|
|
|
if (pkm.Met_Level < 5)
|
|
|
|
|
return new CheckResult(Severity.Invalid, V58, CheckIdentifier.Encounter);
|
|
|
|
|
if (pkm.Egg_Location != 0)
|
|
|
|
|
return new CheckResult(Severity.Invalid, V59, CheckIdentifier.Encounter);
|
|
|
|
|
if (pkm.Format == 4 && pkm.Met_Location != 0x37) // Pal Park
|
|
|
|
|
return new CheckResult(Severity.Invalid, V60, CheckIdentifier.Encounter);
|
|
|
|
|
if (pkm.Format != 4 && pkm.Met_Location != 30001)
|
|
|
|
|
return new CheckResult(Severity.Invalid, V61, CheckIdentifier.Encounter);
|
|
|
|
|
|
|
|
|
|
return new CheckResult(Severity.Valid, V53, CheckIdentifier.Encounter);
|
|
|
|
|
}
|
2017-03-20 04:36:03 +00:00
|
|
|
|
private CheckResult verifyEncounterEgg4()
|
|
|
|
|
{
|
|
|
|
|
if (pkm.Format == 4)
|
|
|
|
|
return verifyEncounterEggLevelLoc(0, pkm.HGSS ? Legal.ValidMet_HGSS : pkm.Pt ? Legal.ValidMet_Pt : Legal.ValidMet_DP);
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (pkm.IsEgg)
|
|
|
|
|
return new CheckResult(Severity.Invalid, V57, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
// transferred
|
|
|
|
|
if (pkm.Met_Level < 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V58, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
|
|
|
|
|
if (pkm.Met_Location != 30001)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V61, CheckIdentifier.Encounter);
|
|
|
|
|
return new CheckResult(Severity.Valid, V63, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyEncounterEgg5()
|
|
|
|
|
{
|
|
|
|
|
return verifyEncounterEggLevelLoc(1, pkm.B2W2 ? Legal.ValidMet_B2W2 : Legal.ValidMet_BW);
|
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyEncounterEgg6()
|
|
|
|
|
{
|
|
|
|
|
if (pkm.AO)
|
|
|
|
|
return verifyEncounterEggLevelLoc(1, Legal.ValidMet_AO);
|
|
|
|
|
|
|
|
|
|
if (pkm.Egg_Location == 318)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V55, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
|
|
|
|
|
return verifyEncounterEggLevelLoc(1, Legal.ValidMet_XY);
|
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyEncounterEgg7()
|
|
|
|
|
{
|
2017-02-13 01:00:03 +00:00
|
|
|
|
if (pkm.SM)
|
2017-03-20 04:36:03 +00:00
|
|
|
|
return verifyEncounterEggLevelLoc(1, Legal.ValidMet_SM);
|
|
|
|
|
|
|
|
|
|
// no other games
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V51, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
}
|
2017-03-20 04:36:03 +00:00
|
|
|
|
private CheckResult verifyEncounterEggLevelLoc(int eggLevel, int[] MetLocations)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.Met_Level != eggLevel)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, string.Format(V52, eggLevel), CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
return MetLocations.Contains(pkm.Met_Location)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
? new CheckResult(Severity.Valid, V53, CheckIdentifier.Encounter)
|
|
|
|
|
: new CheckResult(Severity.Invalid, V54, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyUnhatchedEgg(int tradeLoc)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.Egg_Location == tradeLoc)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V62, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
|
|
|
|
|
if (pkm.Met_Location == tradeLoc)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V56, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
return pkm.Met_Location == 0
|
2017-03-21 07:18:38 +00:00
|
|
|
|
? new CheckResult(Severity.Valid, V63, CheckIdentifier.Encounter)
|
|
|
|
|
: new CheckResult(Severity.Invalid, V59, CheckIdentifier.Encounter);
|
2017-03-20 04:36:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-13 01:00:03 +00:00
|
|
|
|
private CheckResult verifyEncounterSafari()
|
|
|
|
|
{
|
2017-03-20 07:03:31 +00:00
|
|
|
|
switch (pkm.Species)
|
|
|
|
|
{
|
|
|
|
|
case 670: // Floette
|
|
|
|
|
case 671: // Florges
|
|
|
|
|
if (!new[] {0, 1, 3}.Contains(pkm.AltForm)) // 0/1/3 - RBY
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V64, CheckIdentifier.Encounter);
|
2017-03-20 07:03:31 +00:00
|
|
|
|
break;
|
|
|
|
|
case 710: // Pumpkaboo
|
|
|
|
|
case 711: // Goregeist
|
2017-03-25 17:24:56 +00:00
|
|
|
|
if (pkm.AltForm != 0) // Average
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V6, CheckIdentifier.Encounter);
|
2017-03-20 07:03:31 +00:00
|
|
|
|
break;
|
|
|
|
|
case 586: // Sawsbuck
|
|
|
|
|
if (pkm.AltForm != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V65, CheckIdentifier.Encounter);
|
2017-03-20 07:03:31 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2017-02-13 01:00:03 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V66, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyEncounterWild()
|
|
|
|
|
{
|
|
|
|
|
EncounterSlot[] enc = (EncounterSlot[])EncounterMatch;
|
|
|
|
|
|
|
|
|
|
if (enc.Any(slot => slot.Normal))
|
|
|
|
|
return enc.All(slot => slot.Pressure)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
? new CheckResult(Severity.Valid, V67, CheckIdentifier.Encounter)
|
|
|
|
|
: new CheckResult(Severity.Valid, V68, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
|
|
|
|
|
// Decreased Level Encounters
|
|
|
|
|
if (enc.Any(slot => slot.WhiteFlute))
|
|
|
|
|
return enc.All(slot => slot.Pressure)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
? new CheckResult(Severity.Valid, V69, CheckIdentifier.Encounter)
|
|
|
|
|
: new CheckResult(Severity.Valid, V70, CheckIdentifier.Encounter);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
|
2017-02-13 01:00:03 +00:00
|
|
|
|
// Increased Level Encounters
|
|
|
|
|
if (enc.Any(slot => slot.BlackFlute))
|
|
|
|
|
return enc.All(slot => slot.Pressure)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
? new CheckResult(Severity.Valid, V71, CheckIdentifier.Encounter)
|
|
|
|
|
: new CheckResult(Severity.Valid, V72, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
|
|
|
|
|
if (enc.Any(slot => slot.Pressure))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V67, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V73, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyEncounterStatic()
|
|
|
|
|
{
|
|
|
|
|
var s = (EncounterStatic)EncounterMatch;
|
2017-02-14 02:06:01 +00:00
|
|
|
|
|
2017-03-31 07:04:29 +00:00
|
|
|
|
// Check for Unreleased Encounters / Collisions
|
|
|
|
|
switch (pkm.GenNumber)
|
2017-03-26 23:51:19 +00:00
|
|
|
|
{
|
2017-03-31 07:04:29 +00:00
|
|
|
|
case 3:
|
|
|
|
|
if (pkm.Species == 151 && s.Location == 201 && pkm.Language != 1) // Non-JP Mew (Old Sea Map)
|
|
|
|
|
return new CheckResult(Severity.Invalid, V353, CheckIdentifier.Encounter);
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
if (pkm.Species == 493 && s.Location == 086) // Azure Flute Arceus
|
|
|
|
|
return new CheckResult(Severity.Invalid, V352, CheckIdentifier.Encounter);
|
|
|
|
|
if (pkm.Species == 492 && s.Location == 063 && !pkm.Pt) // DP Shaymin
|
|
|
|
|
return new CheckResult(Severity.Invalid, V354, CheckIdentifier.Encounter);
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
if (s.EggLocation == 60002 && vRelearn.All(rl => rl.Valid))
|
|
|
|
|
return null; // not gift egg
|
|
|
|
|
break;
|
2017-03-26 23:51:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-14 02:06:01 +00:00
|
|
|
|
// Re-parse relearn moves
|
2017-03-31 07:04:29 +00:00
|
|
|
|
if (pkm.Format >= 6)
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
vRelearn[i] = pkm.RelearnMoves[i] != s.Relearn[i]
|
|
|
|
|
? new CheckResult(Severity.Invalid, V74, CheckIdentifier.RelearnMove)
|
|
|
|
|
: new CheckResult(CheckIdentifier.RelearnMove);
|
|
|
|
|
|
|
|
|
|
return new CheckResult(Severity.Valid, V75, CheckIdentifier.Encounter);
|
2017-02-13 01:00:03 +00:00
|
|
|
|
}
|
2017-02-14 02:06:01 +00:00
|
|
|
|
private CheckResult verifyEncounterTrade()
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V76, CheckIdentifier.Encounter);
|
2017-02-14 02:06:01 +00:00
|
|
|
|
}
|
2017-02-27 05:46:00 +00:00
|
|
|
|
private CheckResult verifyEncounterG12()
|
2017-02-13 05:02:24 +00:00
|
|
|
|
{
|
2017-03-12 23:36:23 +00:00
|
|
|
|
var obj = Legal.getEncounter12(pkm, Legal.AllowGBCartEra && pkm.Format < 3);
|
2017-02-27 05:46:00 +00:00
|
|
|
|
if (obj == null)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
|
2017-02-13 05:02:24 +00:00
|
|
|
|
|
2017-02-27 05:46:00 +00:00
|
|
|
|
EncounterMatch = obj.Item1;
|
2017-02-28 04:57:24 +00:00
|
|
|
|
if (EncounterMatch is bool)
|
|
|
|
|
{
|
|
|
|
|
pkm.WasEgg = true;
|
|
|
|
|
return verifyEncounterEgg();
|
|
|
|
|
}
|
2017-02-27 05:46:00 +00:00
|
|
|
|
if (EncounterMatch is EncounterSlot[])
|
2017-02-13 05:02:24 +00:00
|
|
|
|
return verifyEncounterWild();
|
2017-04-04 02:59:29 +00:00
|
|
|
|
if (EncounterMatch is List<EncounterStatic>)
|
|
|
|
|
{
|
|
|
|
|
EncounterStaticMatch = (List<EncounterStatic>)EncounterMatch;
|
|
|
|
|
EncounterMatch = EncounterStaticMatch.First();
|
2017-02-25 07:15:16 +00:00
|
|
|
|
return verifyEncounterStatic();
|
2017-04-04 02:59:29 +00:00
|
|
|
|
}
|
2017-02-27 05:46:00 +00:00
|
|
|
|
if (EncounterMatch is EncounterTrade)
|
2017-02-23 05:19:29 +00:00
|
|
|
|
return verifyEncounterTrade();
|
2017-02-27 05:46:00 +00:00
|
|
|
|
|
2017-02-25 07:15:16 +00:00
|
|
|
|
// shouldn't ever hit, above 3*invalid check should abort
|
|
|
|
|
Console.WriteLine($"Gen1 encounter fallthrough: {pkm.FileName}");
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
|
2017-02-13 05:02:24 +00:00
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
private CheckResult verifyEncounterVC()
|
2017-02-13 01:00:03 +00:00
|
|
|
|
{
|
2017-03-25 17:24:56 +00:00
|
|
|
|
int baseSpecies = Legal.getBaseSpecies(pkm);
|
|
|
|
|
bool g1 = pkm.VC1 || pkm.Format == 1;
|
2017-02-14 02:06:01 +00:00
|
|
|
|
|
2017-03-25 17:24:56 +00:00
|
|
|
|
if ((g1 && baseSpecies > Legal.MaxSpeciesID_1) || (baseSpecies > Legal.MaxSpeciesID_2))
|
|
|
|
|
return new CheckResult(Severity.Invalid, V77, CheckIdentifier.Encounter);
|
2016-03-24 00:57:22 +00:00
|
|
|
|
|
2017-03-25 17:24:56 +00:00
|
|
|
|
// Get EncounterMatch prior to parsing transporter legality
|
|
|
|
|
var result = verifyEncounterG12();
|
|
|
|
|
EncounterOriginal = EncounterMatch;
|
|
|
|
|
|
|
|
|
|
if (pkm.Format > 2) // transported to 7+
|
|
|
|
|
AddLine(verifyVCEncounter(baseSpecies));
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
private CheckResult verifyEncounter()
|
|
|
|
|
{
|
2017-03-31 07:04:29 +00:00
|
|
|
|
// Special considerations have to be applied when encounter info is lost on transfer.
|
|
|
|
|
// Generation 1/2 PKM do not reliably store met location or original version.
|
2017-03-25 17:24:56 +00:00
|
|
|
|
if (pkm.VC || pkm.Format < 3)
|
|
|
|
|
return verifyEncounterVC();
|
2017-02-13 05:02:24 +00:00
|
|
|
|
|
2017-03-31 07:04:29 +00:00
|
|
|
|
// Generation 3/4 PKM do not retain met location when transferred.
|
|
|
|
|
if (!pkm.HasOriginalMetLocation)
|
2017-03-26 22:48:50 +00:00
|
|
|
|
{
|
2017-03-31 07:04:29 +00:00
|
|
|
|
if (pkm.Gen3)
|
|
|
|
|
return verifyEncounterG3Transfer();
|
|
|
|
|
if (pkm.Gen4)
|
|
|
|
|
return verifyEncounterG4Transfer();
|
2017-03-26 22:48:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-31 07:04:29 +00:00
|
|
|
|
if (pkm.WasLink)
|
|
|
|
|
return verifyEncounterLink();
|
2017-03-26 23:15:24 +00:00
|
|
|
|
|
2017-02-14 02:06:01 +00:00
|
|
|
|
bool wasEvent = pkm.WasEvent || pkm.WasEventEgg;
|
|
|
|
|
if (wasEvent)
|
2016-03-12 03:43:40 +00:00
|
|
|
|
{
|
2017-02-13 01:00:03 +00:00
|
|
|
|
var result = verifyEncounterEvent();
|
|
|
|
|
if (result != null)
|
|
|
|
|
return result;
|
2016-03-12 03:43:40 +00:00
|
|
|
|
}
|
2017-03-26 22:37:56 +00:00
|
|
|
|
|
2017-04-04 02:59:29 +00:00
|
|
|
|
if (null != (EncounterStaticMatch = Legal.getValidStaticEncounter(pkm)))
|
2016-11-11 01:39:38 +00:00
|
|
|
|
{
|
2017-04-04 02:59:29 +00:00
|
|
|
|
EncounterMatch = EncounterStaticMatch.First();
|
2017-02-13 01:00:03 +00:00
|
|
|
|
var result = verifyEncounterStatic();
|
|
|
|
|
if (result != null)
|
|
|
|
|
return result;
|
2016-11-11 01:39:38 +00:00
|
|
|
|
|
2017-02-14 02:06:01 +00:00
|
|
|
|
EncounterMatch = null; // Reset Encounter Object, test for remaining encounters
|
|
|
|
|
}
|
2017-03-26 22:11:09 +00:00
|
|
|
|
|
2017-03-26 22:37:56 +00:00
|
|
|
|
if (pkm.WasEgg)
|
2017-02-13 01:00:03 +00:00
|
|
|
|
return verifyEncounterEgg();
|
2017-02-14 02:06:01 +00:00
|
|
|
|
|
|
|
|
|
if (null != (EncounterMatch = Legal.getValidFriendSafari(pkm)))
|
2017-02-13 01:00:03 +00:00
|
|
|
|
return verifyEncounterSafari();
|
2017-02-14 02:06:01 +00:00
|
|
|
|
|
|
|
|
|
if (null != (EncounterMatch = Legal.getValidWildEncounters(pkm)))
|
2017-02-13 01:00:03 +00:00
|
|
|
|
return verifyEncounterWild();
|
2017-02-14 02:06:01 +00:00
|
|
|
|
|
|
|
|
|
if (null != (EncounterMatch = Legal.getValidIngameTrade(pkm)))
|
|
|
|
|
return verifyEncounterTrade();
|
2016-04-21 02:47:40 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return wasEvent
|
|
|
|
|
? new CheckResult(Severity.Invalid, V78, CheckIdentifier.Encounter)
|
|
|
|
|
: new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
|
2016-03-12 03:43:40 +00:00
|
|
|
|
}
|
2017-03-26 22:37:56 +00:00
|
|
|
|
|
|
|
|
|
private CheckResult verifyEncounterG3Transfer()
|
|
|
|
|
{
|
2017-03-27 19:10:30 +00:00
|
|
|
|
// WasEventEgg is not possible in gen 3 pal park pokemon, are indistinguible from normal eggs
|
|
|
|
|
bool wasEvent = pkm.WasEvent;
|
2017-03-26 22:37:56 +00:00
|
|
|
|
CheckResult EggResult = null;
|
2017-03-27 19:10:30 +00:00
|
|
|
|
CheckResult G3Result = null;
|
2017-03-30 19:13:38 +00:00
|
|
|
|
object G3Encounter = null;
|
2017-03-26 22:37:56 +00:00
|
|
|
|
bool WasEgg = Legal.getWasEgg23(pkm) && !Legal.NoHatchFromEgg.Contains(pkm.Species);
|
|
|
|
|
if (WasEgg)
|
|
|
|
|
{
|
|
|
|
|
pkm.WasEgg = true;
|
|
|
|
|
EggResult = verifyEncounterEgg3Transfer();
|
2017-03-26 22:48:50 +00:00
|
|
|
|
if (pkm.IsEgg)
|
|
|
|
|
return EggResult;
|
2017-03-26 22:37:56 +00:00
|
|
|
|
}
|
2017-03-27 19:10:30 +00:00
|
|
|
|
|
2017-03-31 07:04:29 +00:00
|
|
|
|
EncounterMatch = null;
|
2017-04-01 01:35:43 +00:00
|
|
|
|
if (null != (EncounterMatch = Legal.getValidIngameTrade(pkm)))
|
2017-03-26 22:37:56 +00:00
|
|
|
|
{
|
2017-04-01 01:35:43 +00:00
|
|
|
|
if ((G3Result = verifyEncounterTrade())?.Valid ?? false)
|
2017-03-30 19:13:38 +00:00
|
|
|
|
G3Encounter = EncounterMatch;
|
2017-03-26 22:37:56 +00:00
|
|
|
|
}
|
2017-04-01 01:35:43 +00:00
|
|
|
|
else if (null != (EncounterMatch = Legal.getValidWildEncounters(pkm)))
|
2017-03-26 22:37:56 +00:00
|
|
|
|
{
|
2017-04-01 01:35:43 +00:00
|
|
|
|
if ((G3Result = verifyEncounterWild())?.Valid ?? false)
|
2017-03-31 07:04:29 +00:00
|
|
|
|
G3Encounter = EncounterMatch;
|
|
|
|
|
}
|
2017-04-04 02:59:29 +00:00
|
|
|
|
else if (null != (EncounterStaticMatch = Legal.getValidStaticEncounter(pkm)))
|
2017-03-31 07:04:29 +00:00
|
|
|
|
{
|
2017-04-04 02:59:29 +00:00
|
|
|
|
EncounterMatch = EncounterStaticMatch.First();
|
2017-04-01 01:35:43 +00:00
|
|
|
|
if ((G3Result = verifyEncounterStatic())?.Valid ?? false)
|
2017-03-31 07:04:29 +00:00
|
|
|
|
G3Encounter = EncounterMatch;
|
2017-03-26 22:37:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-27 19:10:30 +00:00
|
|
|
|
// Check events after static, to match Mew/Deoxys static encounters
|
|
|
|
|
if (wasEvent && G3Result == null && pkm.Species != 151 && pkm.Species != 386)
|
|
|
|
|
{
|
|
|
|
|
G3Result = verifyEncounterEvent() ?? new CheckResult(Severity.Invalid, V78, CheckIdentifier.Encounter);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-27 19:20:54 +00:00
|
|
|
|
// Now check Mew and Deoxys, they can be event or static encounters both with fatefull encounter
|
|
|
|
|
if (pkm.Species == 151 || pkm.Species == 386)
|
2017-03-27 19:10:30 +00:00
|
|
|
|
{
|
|
|
|
|
var EventResult = verifyEncounterEvent();
|
2017-03-27 19:20:54 +00:00
|
|
|
|
// Only return event if is valid, if not return result from static encounter
|
2017-03-27 19:10:30 +00:00
|
|
|
|
if (EventResult?.Valid ?? false)
|
|
|
|
|
G3Result = EventResult;
|
|
|
|
|
}
|
2017-03-26 23:00:52 +00:00
|
|
|
|
|
2017-03-26 22:37:56 +00:00
|
|
|
|
// Even if EggResult is not returned WasEgg is keep true to check in verifymoves first the
|
|
|
|
|
// non egg encounter moves and after that egg encounter moves, because there is no way to tell
|
|
|
|
|
// what of the two encounters was the real origin
|
2017-03-30 19:13:38 +00:00
|
|
|
|
if (EggResult != null && G3Result != null)
|
2017-03-26 22:37:56 +00:00
|
|
|
|
{
|
2017-03-27 19:10:30 +00:00
|
|
|
|
// keep the valid encounter, also if both are valid returns non egg information, because
|
2017-03-26 22:37:56 +00:00
|
|
|
|
// there is more data in the pokemon to found normal encounter
|
2017-03-27 19:10:30 +00:00
|
|
|
|
if (EggResult.Valid && !G3Result.Valid)
|
2017-03-30 19:13:38 +00:00
|
|
|
|
{
|
2017-03-27 19:10:30 +00:00
|
|
|
|
G3Result = EggResult;
|
2017-03-30 19:13:38 +00:00
|
|
|
|
G3Encounter = null;
|
|
|
|
|
}
|
2017-03-26 22:37:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-30 19:13:38 +00:00
|
|
|
|
if (G3Result?.Valid ?? false)
|
|
|
|
|
EncounterMatch = G3Encounter;
|
|
|
|
|
|
2017-03-31 07:04:29 +00:00
|
|
|
|
if (pkm.Format == 4 && pkm.Met_Location != 0x37) // Pal Park
|
|
|
|
|
AddLine(Severity.Invalid, V60, CheckIdentifier.Encounter);
|
|
|
|
|
if (pkm.Format != 4 && pkm.Met_Location != 30001)
|
|
|
|
|
AddLine(Severity.Invalid, V61, CheckIdentifier.Encounter);
|
2017-03-27 19:10:30 +00:00
|
|
|
|
|
2017-03-31 07:04:29 +00:00
|
|
|
|
return G3Result ?? new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
|
2017-03-26 22:37:56 +00:00
|
|
|
|
}
|
2017-03-26 23:15:24 +00:00
|
|
|
|
private CheckResult verifyEncounterG4Transfer()
|
|
|
|
|
{
|
|
|
|
|
CheckResult Gen4Result = null;
|
|
|
|
|
|
|
|
|
|
bool wasEvent = pkm.WasEvent || pkm.WasEventEgg;
|
|
|
|
|
if (wasEvent)
|
|
|
|
|
{
|
|
|
|
|
var result = verifyEncounterEvent();
|
|
|
|
|
if (result != null)
|
|
|
|
|
Gen4Result = result;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-04 02:59:29 +00:00
|
|
|
|
if (Gen4Result == null && null != (EncounterStaticMatch = Legal.getValidStaticEncounter(pkm)))
|
2017-03-26 23:15:24 +00:00
|
|
|
|
{
|
2017-04-04 02:59:29 +00:00
|
|
|
|
EncounterMatch = EncounterStaticMatch.First();
|
2017-03-26 23:15:24 +00:00
|
|
|
|
var result = verifyEncounterStatic();
|
|
|
|
|
if (result != null)
|
2017-04-01 01:35:43 +00:00
|
|
|
|
return result;
|
2017-03-26 23:15:24 +00:00
|
|
|
|
|
|
|
|
|
EncounterMatch = null; // Reset Encounter Object, test for remaining encounters
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkm.WasEgg) // Invalid transfer is already checked in encounter egg
|
|
|
|
|
return verifyEncounterEgg();
|
|
|
|
|
|
|
|
|
|
if (Gen4Result == null && null != (EncounterMatch = Legal.getValidFriendSafari(pkm)))
|
|
|
|
|
Gen4Result = verifyEncounterSafari();
|
|
|
|
|
|
|
|
|
|
if (Gen4Result == null && null != (EncounterMatch = Legal.getValidWildEncounters(pkm)))
|
|
|
|
|
Gen4Result = verifyEncounterWild();
|
|
|
|
|
|
|
|
|
|
if (Gen4Result == null && null != (EncounterMatch = Legal.getValidIngameTrade(pkm)))
|
|
|
|
|
Gen4Result = verifyEncounterTrade();
|
|
|
|
|
|
2017-03-27 19:10:30 +00:00
|
|
|
|
if (Gen4Result == null)
|
|
|
|
|
Gen4Result = wasEvent
|
|
|
|
|
? new CheckResult(Severity.Invalid, V78, CheckIdentifier.Encounter)
|
|
|
|
|
: new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
|
2017-03-26 23:15:24 +00:00
|
|
|
|
|
2017-04-01 01:35:43 +00:00
|
|
|
|
// Transfer Legality
|
|
|
|
|
|
2017-04-01 21:38:50 +00:00
|
|
|
|
// PokéTransfer
|
|
|
|
|
int loc = pkm.Met_Location;
|
|
|
|
|
if (loc == 30001)
|
|
|
|
|
return Gen4Result;
|
2017-03-27 19:10:30 +00:00
|
|
|
|
|
2017-04-01 21:38:50 +00:00
|
|
|
|
// Crown
|
|
|
|
|
switch (pkm.Species)
|
|
|
|
|
{
|
|
|
|
|
case 251: // Celebi
|
|
|
|
|
if (pkm.Met_Location == 30010 || pkm.Met_Location == 30011) // unused || used
|
|
|
|
|
return Gen4Result;
|
|
|
|
|
return new CheckResult(Severity.Invalid, V351, CheckIdentifier.Encounter);
|
|
|
|
|
|
|
|
|
|
case 243: // Raikou
|
|
|
|
|
case 244: // Entei
|
|
|
|
|
case 245: // Suicune
|
|
|
|
|
if (pkm.Met_Location == 30012 || pkm.Met_Location == 30013) // unused || used
|
|
|
|
|
return Gen4Result;
|
|
|
|
|
return new CheckResult(Severity.Invalid, V351, CheckIdentifier.Encounter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// No Match
|
|
|
|
|
return new CheckResult(Severity.Invalid, V61, CheckIdentifier.Encounter);
|
2017-03-26 23:15:24 +00:00
|
|
|
|
}
|
2017-01-27 05:35:26 +00:00
|
|
|
|
private CheckResult verifyVCEncounter(int baseSpecies)
|
|
|
|
|
{
|
|
|
|
|
// Sanitize Species to non-future species#
|
|
|
|
|
int species = pkm.Species;
|
|
|
|
|
if ((pkm.VC1 && species > Legal.MaxSpeciesID_1) ||
|
|
|
|
|
(pkm.VC2 && species > Legal.MaxSpeciesID_2))
|
|
|
|
|
species = baseSpecies;
|
2017-02-14 02:06:01 +00:00
|
|
|
|
|
|
|
|
|
// Check existing EncounterMatch
|
2017-02-23 05:30:37 +00:00
|
|
|
|
if ((EncounterOriginal ?? EncounterMatch) == null)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
|
2017-02-15 06:06:15 +00:00
|
|
|
|
|
2017-04-04 02:59:29 +00:00
|
|
|
|
var s = EncounterMatch as List<EncounterStatic>;
|
|
|
|
|
var sgb = s?.Where(v => GameVersion.GBCartEraOnly.Contains(v.Version) || v.Version == GameVersion.VCEvents).FirstOrDefault();
|
|
|
|
|
if (sgb != null)
|
2017-02-15 06:06:15 +00:00
|
|
|
|
{
|
|
|
|
|
bool exceptions = false;
|
2017-04-04 02:59:29 +00:00
|
|
|
|
exceptions |= sgb.Version == GameVersion.VCEvents && baseSpecies == 151 && pkm.TID == 22796;
|
2017-02-15 06:06:15 +00:00
|
|
|
|
if (!exceptions)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(new CheckResult(Severity.Invalid, V79, CheckIdentifier.Encounter));
|
2017-02-15 06:06:15 +00:00
|
|
|
|
}
|
2017-03-10 04:27:03 +00:00
|
|
|
|
|
|
|
|
|
EncounterMatch = Legal.getRBYStaticTransfer(species);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
var ematch = (EncounterStatic) EncounterMatch;
|
|
|
|
|
|
|
|
|
|
if (pkm.Met_Location != ematch.Location)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V81, CheckIdentifier.Encounter);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
if (pkm.Egg_Location != ematch.EggLocation)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V59, CheckIdentifier.Encounter);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
|
2017-03-26 08:25:21 +00:00
|
|
|
|
if (species == 150 && pkm.Moves.Contains(6)) // pay day
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V82, CheckIdentifier.Encounter);
|
2017-02-13 06:40:47 +00:00
|
|
|
|
|
2017-01-27 05:35:26 +00:00
|
|
|
|
return new CheckResult(CheckIdentifier.Encounter);
|
|
|
|
|
}
|
2017-02-14 06:49:32 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyLevel()
|
2016-03-19 05:49:21 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
MysteryGift MatchedGift = EncounterMatch as MysteryGift;
|
|
|
|
|
if (MatchedGift != null && MatchedGift.Level != pkm.Met_Level)
|
|
|
|
|
{
|
2017-03-26 08:25:21 +00:00
|
|
|
|
if (pkm.HasOriginalMetLocation && (!(MatchedGift is WC7) || ((WC7) MatchedGift).MetLevel != pkm.Met_Level))
|
2016-11-13 23:40:34 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(new CheckResult(Severity.Invalid, V83, CheckIdentifier.Level));
|
2016-11-13 23:40:34 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
2016-12-12 01:13:59 +00:00
|
|
|
|
if (MatchedGift != null && MatchedGift.Level > pkm.CurrentLevel)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(new CheckResult(Severity.Invalid, V84, CheckIdentifier.Level));
|
2016-12-12 01:13:59 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
|
|
|
|
int lvl = pkm.CurrentLevel;
|
2017-03-19 23:52:56 +00:00
|
|
|
|
if (pkm.IsEgg)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
int elvl = pkm.Format <= 3 ? 5 : 1;
|
|
|
|
|
if (elvl != lvl)
|
|
|
|
|
AddLine(Severity.Invalid, string.Format(V52, elvl), CheckIdentifier.Level);
|
2017-03-19 23:52:56 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (lvl < pkm.Met_Level)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V85, CheckIdentifier.Level);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if ((pkm.WasEgg || EncounterMatch == null) && !Legal.getEvolutionValid(pkm) && pkm.Species != 350)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V86, CheckIdentifier.Level);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else if (lvl > pkm.Met_Level && lvl > 1 && lvl != 100 && pkm.EXP == PKX.getEXP(pkm.Stat_Level, pkm.Species))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Fishy, V87, CheckIdentifier.Level);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V88, CheckIdentifier.Level);
|
2016-03-19 05:49:21 +00:00
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
|
2016-11-08 16:43:57 +00:00
|
|
|
|
private void verifyMedals()
|
|
|
|
|
{
|
|
|
|
|
if (pkm.Format < 6)
|
|
|
|
|
return;
|
2017-03-25 17:24:56 +00:00
|
|
|
|
|
|
|
|
|
verifyMedalsRegular();
|
|
|
|
|
verifyMedalsEvent();
|
|
|
|
|
}
|
|
|
|
|
private void verifyMedalsRegular()
|
|
|
|
|
{
|
2016-11-08 16:43:57 +00:00
|
|
|
|
var TrainNames = ReflectUtil.getPropertiesStartWithPrefix(pkm.GetType(), "SuperTrain").ToArray();
|
|
|
|
|
var TrainCount = TrainNames.Count(MissionName => ReflectUtil.GetValue(pkm, MissionName) as bool? == true);
|
|
|
|
|
if (pkm.IsEgg && TrainCount > 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V89, CheckIdentifier.Training); }
|
|
|
|
|
else if (TrainCount > 0 && pkm.GenNumber > 6)
|
|
|
|
|
{ AddLine(Severity.Invalid, V90, CheckIdentifier.Training); }
|
2017-01-25 17:17:20 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (pkm.Format >= 7)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.SecretSuperTrainingUnlocked)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V91, CheckIdentifier.Training); }
|
2017-01-25 17:17:20 +00:00
|
|
|
|
if (pkm.SecretSuperTrainingComplete)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V92, CheckIdentifier.Training); }
|
2017-01-25 17:17:20 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (TrainCount == 30 ^ pkm.SecretSuperTrainingComplete)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V93, CheckIdentifier.Training); }
|
2017-01-25 17:17:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
}
|
|
|
|
|
private void verifyMedalsEvent()
|
|
|
|
|
{
|
2016-11-08 16:43:57 +00:00
|
|
|
|
var DistNames = ReflectUtil.getPropertiesStartWithPrefix(pkm.GetType(), "DistSuperTrain");
|
|
|
|
|
var DistCount = DistNames.Count(MissionName => ReflectUtil.GetValue(pkm, MissionName) as bool? == true);
|
|
|
|
|
if (pkm.IsEgg && DistCount > 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V89, CheckIdentifier.Training); }
|
|
|
|
|
else if (DistCount > 0 && pkm.GenNumber > 6)
|
|
|
|
|
{ AddLine(Severity.Invalid, V90, CheckIdentifier.Training); }
|
2016-11-08 16:43:57 +00:00
|
|
|
|
else if (DistCount > 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Fishy, V94, CheckIdentifier.Training); }
|
2016-11-08 16:43:57 +00:00
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyRibbons()
|
2016-03-20 22:20:11 +00:00
|
|
|
|
{
|
|
|
|
|
if (!Encounter.Valid)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-09-17 19:21:23 +00:00
|
|
|
|
|
2016-03-20 22:20:11 +00:00
|
|
|
|
List<string> missingRibbons = new List<string>();
|
|
|
|
|
List<string> invalidRibbons = new List<string>();
|
2016-09-03 15:10:22 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.IsEgg)
|
2016-09-03 15:10:22 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
var RibbonNames = ReflectUtil.getPropertiesStartWithPrefix(pkm.GetType(), "Ribbon");
|
|
|
|
|
foreach (object RibbonValue in RibbonNames.Select(RibbonName => ReflectUtil.GetValue(pkm, RibbonName)))
|
2016-09-03 15:10:22 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (RibbonValue as bool? == true) // Boolean
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V95, CheckIdentifier.Ribbon); return; }
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if ((RibbonValue as int?) > 0) // Count
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V95, CheckIdentifier.Ribbon); return; }
|
2016-09-03 15:10:22 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-09-03 15:10:22 +00:00
|
|
|
|
}
|
2016-03-20 22:20:11 +00:00
|
|
|
|
|
|
|
|
|
// Check Event Ribbons
|
2016-10-23 19:48:49 +00:00
|
|
|
|
var RibbonData = ReflectUtil.getPropertiesStartWithPrefix(pkm.GetType(), "Ribbon");
|
|
|
|
|
MysteryGift MatchedGift = EncounterMatch as MysteryGift;
|
|
|
|
|
string[] EventRib =
|
2016-03-20 22:20:11 +00:00
|
|
|
|
{
|
2016-12-11 18:30:41 +00:00
|
|
|
|
nameof(PK6.RibbonCountry), nameof(PK6.RibbonNational), nameof(PK6.RibbonEarth), nameof(PK6.RibbonWorld), nameof(PK6.RibbonClassic),
|
|
|
|
|
nameof(PK6.RibbonPremier), nameof(PK6.RibbonEvent), nameof(PK6.RibbonBirthday), nameof(PK6.RibbonSpecial), nameof(PK6.RibbonSouvenir),
|
|
|
|
|
nameof(PK6.RibbonWishing), nameof(PK6.RibbonChampionBattle), nameof(PK6.RibbonChampionRegional), nameof(PK6.RibbonChampionNational), nameof(PK6.RibbonChampionWorld)
|
2016-03-20 22:20:11 +00:00
|
|
|
|
};
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (MatchedGift != null) // Wonder Card
|
2016-03-20 22:20:11 +00:00
|
|
|
|
{
|
2017-03-25 17:24:56 +00:00
|
|
|
|
var mgRibbons = MatchedGift.Format == 4 ? EventRib : ReflectUtil.getPropertiesStartWithPrefix(MatchedGift.Content.GetType(), "Ribbon");
|
2016-10-23 19:48:49 +00:00
|
|
|
|
var commonRibbons = mgRibbons.Intersect(RibbonData).ToArray();
|
|
|
|
|
|
|
|
|
|
foreach (string r in commonRibbons)
|
2016-03-20 22:20:11 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
bool? pk = ReflectUtil.getBooleanState(pkm, r);
|
2017-03-25 17:24:56 +00:00
|
|
|
|
bool? mg = ReflectUtil.getBooleanState(MatchedGift.Content, r);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pk != mg) // Mismatch
|
|
|
|
|
{
|
|
|
|
|
if (pk ?? false)
|
|
|
|
|
missingRibbons.Add(r);
|
|
|
|
|
else
|
|
|
|
|
invalidRibbons.Add(r);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-03-20 22:20:11 +00:00
|
|
|
|
}
|
2016-03-28 05:05:51 +00:00
|
|
|
|
else if (EncounterType == typeof(EncounterLink))
|
2016-03-23 02:47:13 +00:00
|
|
|
|
{
|
|
|
|
|
// No Event Ribbons except Classic (unless otherwise specified, ie not for Demo)
|
|
|
|
|
for (int i = 0; i < EventRib.Length; i++)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
|
|
|
|
if (i == 4)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, EventRib[i]) == true)
|
2016-03-23 02:47:13 +00:00
|
|
|
|
invalidRibbons.Add(EventRibName[i]);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
2016-03-23 02:47:13 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
bool classic = ReflectUtil.getBooleanState(pkm, EventRib[4]) == true;
|
|
|
|
|
if (classic ^ ((EncounterLink)EncounterMatch).Classic)
|
|
|
|
|
(classic ? invalidRibbons : missingRibbons).Add(EventRibName[4]);
|
2016-03-23 02:47:13 +00:00
|
|
|
|
}
|
2016-11-13 17:37:28 +00:00
|
|
|
|
else if (EncounterType == typeof(EncounterStatic))
|
|
|
|
|
{
|
|
|
|
|
// No Event Ribbons except Wishing (which is only for Magearna)
|
|
|
|
|
for (int i = 0; i < EventRib.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
if (i == 10)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, EventRib[i]) == true)
|
|
|
|
|
invalidRibbons.Add(EventRibName[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool wishing = ReflectUtil.getBooleanState(pkm, EventRib[10]) == true;
|
|
|
|
|
if (wishing ^ ((EncounterStatic)EncounterMatch).RibbonWishing)
|
|
|
|
|
(wishing ? invalidRibbons : missingRibbons).Add(EventRibName[10]);
|
|
|
|
|
}
|
2016-03-23 02:47:13 +00:00
|
|
|
|
else // No ribbons
|
2016-03-20 22:20:11 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < EventRib.Length; i++)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, EventRib[i]) == true)
|
2016-03-20 22:20:11 +00:00
|
|
|
|
invalidRibbons.Add(EventRibName[i]);
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
|
|
|
|
// Unobtainable ribbons for Gen Origin
|
|
|
|
|
if (pkm.GenNumber > 3)
|
|
|
|
|
{
|
2016-12-11 18:30:41 +00:00
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, nameof(PK3.RibbonChampionG3Hoenn)) == true)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
invalidRibbons.Add(V96); // RSE HoF
|
2016-12-11 18:30:41 +00:00
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, nameof(PK3.RibbonArtist)) == true)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
invalidRibbons.Add(V97); // RSE Master Rank Portrait
|
2016-12-11 18:30:41 +00:00
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, nameof(PK3.RibbonNational)) == true && pkm.Version != (int)GameVersion.CXD)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
invalidRibbons.Add(V98); // RSE HoF
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
|
|
|
|
if (pkm.GenNumber > 4)
|
|
|
|
|
{
|
2016-12-11 18:30:41 +00:00
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, nameof(PK4.RibbonChampionSinnoh)) == true)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
invalidRibbons.Add(V99); // DPPt HoF
|
2016-12-11 18:30:41 +00:00
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, nameof(PK4.RibbonLegend)) == true)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
invalidRibbons.Add(V100); // HGSS Defeat Red @ Mt.Silver
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
|
|
|
|
if (pkm.Format >= 6 && pkm.GenNumber >= 6)
|
|
|
|
|
{
|
2016-12-11 18:30:41 +00:00
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, nameof(PK6.RibbonCountMemoryContest)) == true)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
invalidRibbons.Add(V106); // Gen3/4 Contest
|
2016-12-11 18:30:41 +00:00
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, nameof(PK6.RibbonCountMemoryBattle)) == true)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
invalidRibbons.Add(V105); // Gen3/4 Battle
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
2016-12-11 18:30:41 +00:00
|
|
|
|
if (ReflectUtil.getBooleanState(pkm, nameof(PK6.RibbonRecord)) == true)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
invalidRibbons.Add(V104); // Unobtainable
|
2016-03-20 22:20:11 +00:00
|
|
|
|
|
|
|
|
|
if (missingRibbons.Count + invalidRibbons.Count == 0)
|
2016-09-03 15:10:22 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V103, CheckIdentifier.Ribbon);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-09-03 15:10:22 +00:00
|
|
|
|
}
|
2016-03-20 22:20:11 +00:00
|
|
|
|
|
|
|
|
|
string[] result = new string[2];
|
|
|
|
|
if (missingRibbons.Count > 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
result[0] = string.Format(V101, string.Join(", ", missingRibbons));
|
2016-03-20 22:20:11 +00:00
|
|
|
|
if (invalidRibbons.Count > 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
result[1] = string.Format(V102, string.Join(", ", invalidRibbons));
|
2017-03-17 06:16:11 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Join(Environment.NewLine, result.Where(s => !string.IsNullOrEmpty(s))), CheckIdentifier.Ribbon);
|
2016-03-20 22:20:11 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyAbility()
|
2016-03-21 15:01:08 +00:00
|
|
|
|
{
|
2016-10-29 06:41:22 +00:00
|
|
|
|
int[] abilities = pkm.PersonalInfo.Abilities;
|
2017-03-18 23:17:42 +00:00
|
|
|
|
if (abilities[1] == 0)
|
|
|
|
|
abilities[1] = abilities[0];
|
2016-10-23 19:48:49 +00:00
|
|
|
|
int abilval = Array.IndexOf(abilities, pkm.Ability);
|
2016-03-21 15:01:08 +00:00
|
|
|
|
if (abilval < 0)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V107, CheckIdentifier.Ability);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-03-21 15:01:08 +00:00
|
|
|
|
|
2016-03-23 02:47:13 +00:00
|
|
|
|
if (EncounterMatch != null)
|
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
// Check Hidden Ability Mismatches
|
|
|
|
|
if (pkm.GenNumber >= 5)
|
2016-03-31 02:55:27 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
bool valid = true;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (EncounterType == typeof(EncounterStatic))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.AbilityNumber == 4 ^ ((EncounterStatic) EncounterMatch).Ability == 4)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
valid = false;
|
|
|
|
|
}
|
|
|
|
|
else if (EncounterType == typeof(EncounterTrade))
|
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.AbilityNumber == 4 ^ ((EncounterTrade) EncounterMatch).Ability == 4)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
valid = false;
|
|
|
|
|
}
|
|
|
|
|
else if (EncounterType == typeof(EncounterLink))
|
|
|
|
|
{
|
2016-11-13 20:01:52 +00:00
|
|
|
|
if (pkm.AbilityNumber != ((EncounterLink)EncounterMatch).Ability)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
valid = false;
|
|
|
|
|
}
|
|
|
|
|
if (!valid)
|
|
|
|
|
{
|
|
|
|
|
AddLine(Severity.Invalid, V108, CheckIdentifier.Ability);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
2017-03-22 23:47:14 +00:00
|
|
|
|
if (pkm.GenNumber == 5)
|
|
|
|
|
{
|
2017-03-23 02:43:31 +00:00
|
|
|
|
if (EncounterType == typeof(EncounterSlot[]))
|
2017-03-22 23:47:14 +00:00
|
|
|
|
{
|
2017-03-23 02:43:31 +00:00
|
|
|
|
bool grotto = ((EncounterSlot[])EncounterMatch).All(slot => slot.Type == SlotType.HiddenGrotto); //encounter only at HiddenGrotto
|
|
|
|
|
if (pkm.AbilityNumber == 4 ^ grotto)
|
2017-03-22 23:47:14 +00:00
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, grotto ? V217 : V108, CheckIdentifier.Ability);
|
2017-03-22 23:47:14 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.GenNumber == 6)
|
|
|
|
|
{
|
2017-03-06 06:08:00 +00:00
|
|
|
|
if (EncounterIsMysteryGift)
|
|
|
|
|
{
|
|
|
|
|
var wc = EncounterMatch as WC6;
|
|
|
|
|
var type = wc?.AbilityType;
|
2017-03-10 01:19:36 +00:00
|
|
|
|
int abilNumber = pkm.AbilityNumber;
|
|
|
|
|
if (type < 3 && abilNumber != 1 << type) // set number
|
|
|
|
|
{
|
|
|
|
|
if (type < 2 && abilNumber < 3 && abilities[0] != abilities[1]) // 0/1 required, not hidden, and ability can be changed
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V109, CheckIdentifier.Ability);
|
2017-03-10 01:19:36 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V110, CheckIdentifier.Ability);
|
2017-03-10 01:19:36 +00:00
|
|
|
|
}
|
|
|
|
|
else if (type == 3 && abilNumber == 4) // 1/2 only
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V110, CheckIdentifier.Ability);
|
2017-03-06 06:08:00 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (EncounterType == typeof(EncounterSlot[]) && pkm.AbilityNumber == 4)
|
|
|
|
|
{
|
|
|
|
|
var slots = (EncounterSlot[])EncounterMatch;
|
|
|
|
|
bool valid = slots.Any(slot => slot.DexNav ||
|
|
|
|
|
slot.Type == SlotType.FriendSafari ||
|
|
|
|
|
slot.Type == SlotType.Horde);
|
2016-03-31 02:55:27 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (!valid)
|
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V300, CheckIdentifier.Ability);
|
2016-11-23 01:04:53 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-02 13:39:39 +00:00
|
|
|
|
if (Legal.Ban_NoHidden6.Contains(pkm.SpecForm) && pkm.AbilityNumber == 4)
|
|
|
|
|
{
|
|
|
|
|
AddLine(Severity.Invalid, V112, CheckIdentifier.Ability);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2016-11-23 01:04:53 +00:00
|
|
|
|
}
|
|
|
|
|
if (pkm.GenNumber == 7)
|
|
|
|
|
{
|
2017-03-06 06:08:00 +00:00
|
|
|
|
if (EncounterIsMysteryGift)
|
|
|
|
|
{
|
|
|
|
|
var wc = EncounterMatch as WC7;
|
|
|
|
|
var type = wc?.AbilityType;
|
2017-03-10 01:19:36 +00:00
|
|
|
|
int abilNumber = pkm.AbilityNumber;
|
|
|
|
|
if (type < 3 && abilNumber != 1 << type) // set number
|
|
|
|
|
{
|
|
|
|
|
if (type < 2 && abilNumber < 3 && abilities[0] != abilities[1]) // 0/1 required, not hidden, and ability can be changed
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V109, CheckIdentifier.Ability);
|
2017-03-10 01:19:36 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V110, CheckIdentifier.Ability);
|
2017-03-10 01:19:36 +00:00
|
|
|
|
}
|
|
|
|
|
else if (type == 3 && abilNumber == 4) // 1/2 only
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V110, CheckIdentifier.Ability);
|
2017-03-06 06:08:00 +00:00
|
|
|
|
}
|
2016-11-23 01:04:53 +00:00
|
|
|
|
if (EncounterType == typeof(EncounterSlot[]) && pkm.AbilityNumber == 4)
|
|
|
|
|
{
|
|
|
|
|
var slots = (EncounterSlot[])EncounterMatch;
|
|
|
|
|
bool valid = slots.Any(slot => slot.Type == SlotType.SOS);
|
|
|
|
|
|
|
|
|
|
if (!valid)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V111, CheckIdentifier.Ability);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-02 13:39:39 +00:00
|
|
|
|
if (Legal.Ban_NoHidden7.Contains(pkm.SpecForm) && pkm.AbilityNumber == 4)
|
2016-12-02 02:48:38 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V112, CheckIdentifier.Ability);
|
2016-12-02 02:48:38 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-31 02:55:27 +00:00
|
|
|
|
}
|
2016-03-23 02:47:13 +00:00
|
|
|
|
}
|
2016-03-22 04:50:39 +00:00
|
|
|
|
|
2017-02-14 02:06:01 +00:00
|
|
|
|
if (3 <= pkm.Format && pkm.Format <= 5) // 3-5
|
|
|
|
|
{
|
2017-03-25 17:24:56 +00:00
|
|
|
|
if (pkm.Version != (int) GameVersion.CXD && abilities[0] != abilities[1] && pkm.AbilityNumber != 1 << abilval)
|
2017-02-14 02:06:01 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V113, CheckIdentifier.Ability);
|
2017-02-14 02:06:01 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else
|
2017-02-14 02:06:01 +00:00
|
|
|
|
{
|
|
|
|
|
if (abilities[pkm.AbilityNumber >> 1] != pkm.Ability)
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V114, CheckIdentifier.Ability);
|
2017-02-14 02:06:01 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V115, CheckIdentifier.Ability);
|
2016-03-21 15:01:08 +00:00
|
|
|
|
}
|
2017-02-23 05:19:29 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
private void verifyBallEquals(params int[] balls)
|
|
|
|
|
{
|
|
|
|
|
int ball = pkm.Ball;
|
|
|
|
|
if (balls.Any(b => b == ball))
|
|
|
|
|
AddLine(Severity.Valid, V119, CheckIdentifier.Ball);
|
|
|
|
|
else
|
|
|
|
|
AddLine(Severity.Invalid, V118, CheckIdentifier.Ball);
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyBall()
|
2016-03-21 15:01:08 +00:00
|
|
|
|
{
|
2017-02-28 04:57:24 +00:00
|
|
|
|
if (pkm.Format < 3)
|
|
|
|
|
return; // no ball info saved
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
2016-03-23 02:47:13 +00:00
|
|
|
|
if (!Encounter.Valid)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2016-11-09 07:37:53 +00:00
|
|
|
|
if (EncounterIsMysteryGift)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
2017-03-31 08:12:49 +00:00
|
|
|
|
if (pkm.Species == 490 && ((MysteryGift)EncounterMatch).Ball == 0)
|
2017-03-30 18:58:30 +00:00
|
|
|
|
// there is no ball data in Manaphy Mystery Gift
|
|
|
|
|
verifyBallEquals(4); // Pokeball
|
|
|
|
|
else
|
|
|
|
|
verifyBallEquals(((MysteryGift)EncounterMatch).Ball);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (EncounterType == typeof (EncounterLink))
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(((EncounterLink)EncounterMatch).Ball);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (EncounterType == typeof (EncounterTrade))
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(4); // Pokeball
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-13 19:12:55 +00:00
|
|
|
|
|
2017-04-04 03:02:40 +00:00
|
|
|
|
if (pkm.Species == 292) // Shedinja
|
|
|
|
|
{
|
|
|
|
|
verifyBallEquals(4); // Pokeball
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-13 19:28:39 +00:00
|
|
|
|
if (pkm.Ball == 0x14 && pkm.Gen7) // Heavy Ball
|
2017-03-13 19:12:55 +00:00
|
|
|
|
{
|
2017-03-14 01:38:56 +00:00
|
|
|
|
var lineage = Legal.getLineage(pkm);
|
|
|
|
|
if (lineage.Any(e => Legal.AlolanCaptureNoHeavyBall.Contains(e)))
|
2017-03-15 04:13:39 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V116, CheckIdentifier.Ball);
|
2017-03-15 04:13:39 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-13 19:12:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-29 05:30:23 +00:00
|
|
|
|
if (EncounterType == typeof(EncounterStatic))
|
2016-04-21 03:46:18 +00:00
|
|
|
|
{
|
|
|
|
|
EncounterStatic enc = EncounterMatch as EncounterStatic;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (enc?.Gift ?? false)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(enc.Ball);
|
2017-03-30 06:31:02 +00:00
|
|
|
|
else if (pkm.Met_Location == 75 && pkm.Gen5) // DreamWorld
|
|
|
|
|
verifyBallEquals(Legal.DreamWorldBalls);
|
2016-11-08 16:43:57 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(Legal.getWildBalls(pkm));
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (EncounterType == typeof (EncounterSlot[]))
|
|
|
|
|
{
|
2017-03-30 11:18:05 +00:00
|
|
|
|
EncounterSlot[] enc = EncounterMatch as EncounterSlot[];
|
|
|
|
|
|
2017-01-25 03:49:40 +00:00
|
|
|
|
if (pkm.Met_Location == 30016 && pkm.Gen7) // Poké Pelago
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(4); // Pokeball
|
2017-03-30 11:24:38 +00:00
|
|
|
|
// For gen3/4 safari zones and BCC getValidWildEncounters already filter to not return
|
2017-03-30 11:18:05 +00:00
|
|
|
|
// mixed possible encounters between safari, BCC and other encounters
|
|
|
|
|
// That means is the first encounter is not safari then there is no safari encounter in the array
|
|
|
|
|
else if (3 <= pkm.GenNumber && pkm.GenNumber <= 4 && Legal.IsSafariSlot(enc.First().Type))
|
2017-03-31 08:12:49 +00:00
|
|
|
|
verifyBallEquals(5); // Safari Ball
|
|
|
|
|
else if (pkm.GenNumber == 4 && enc.First().Type == SlotType.BugContest)
|
|
|
|
|
verifyBallEquals(0x18); // Sport Ball
|
2016-11-08 16:43:57 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(Legal.getWildBalls(pkm));
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkm.WasEgg)
|
|
|
|
|
{
|
2017-02-23 05:19:29 +00:00
|
|
|
|
verifyBallEgg();
|
|
|
|
|
return;
|
2016-11-11 05:10:28 +00:00
|
|
|
|
}
|
2016-03-28 05:05:51 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(4); // Pokeball
|
2016-11-11 05:10:28 +00:00
|
|
|
|
}
|
2017-02-23 05:19:29 +00:00
|
|
|
|
private void verifyBallEgg()
|
|
|
|
|
{
|
|
|
|
|
if (pkm.GenNumber < 6) // No inheriting Balls
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(4); // Must be Pokéball -- no ball inheritance.
|
2017-02-23 05:19:29 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkm.Ball == 0x01) // Master Ball
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V117, CheckIdentifier.Ball); return; }
|
2017-02-23 05:19:29 +00:00
|
|
|
|
if (pkm.Ball == 0x10) // Cherish Ball
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V120, CheckIdentifier.Ball); return; }
|
2017-02-23 05:19:29 +00:00
|
|
|
|
if (pkm.Ball == 0x04) // Poké Ball
|
2017-03-21 07:18:38 +00:00
|
|
|
|
{ AddLine(Severity.Valid, V119, CheckIdentifier.Ball); return; }
|
2017-02-23 05:19:29 +00:00
|
|
|
|
|
|
|
|
|
switch (pkm.GenNumber)
|
|
|
|
|
{
|
|
|
|
|
case 6: // Gen6 Inheritance Rules
|
|
|
|
|
verifyBallEggGen6();
|
|
|
|
|
return;
|
|
|
|
|
case 7: // Gen7 Inheritance Rules
|
|
|
|
|
verifyBallEggGen7();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void verifyBallEggGen6()
|
2016-11-11 05:10:28 +00:00
|
|
|
|
{
|
|
|
|
|
if (pkm.Gender == 2) // Genderless
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(4); // Must be Pokéball as ball can only pass via mother (not Ditto!)
|
2016-11-11 05:10:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (Legal.BreedMaleOnly.Contains(pkm.Species))
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(4); // Must be Pokéball as ball can only pass via mother (not Ditto!)
|
2016-11-11 05:10:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
int ball = pkm.Ball;
|
|
|
|
|
|
|
|
|
|
if (ball >= 26)
|
|
|
|
|
{
|
|
|
|
|
AddLine(Severity.Invalid, V126, CheckIdentifier.Ball);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (ball == 0x05) // Safari Ball
|
2016-11-11 05:10:28 +00:00
|
|
|
|
{
|
|
|
|
|
if (Legal.getLineage(pkm).All(e => !Legal.Inherit_Safari.Contains(e)))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
else if (pkm.AbilityNumber == 4)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V122, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
2016-11-11 05:10:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (0x10 < ball && ball < 0x18) // Apricorn Ball
|
2016-11-11 05:10:28 +00:00
|
|
|
|
{
|
2017-02-04 18:42:56 +00:00
|
|
|
|
if (Legal.getLineage(pkm).All(e => !Legal.Inherit_Apricorn6.Contains(e)))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
if (pkm.AbilityNumber == 4)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V122, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-03-22 04:31:06 +00:00
|
|
|
|
|
2016-11-11 05:10:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (ball == 0x18) // Sport Ball
|
2016-11-11 05:10:28 +00:00
|
|
|
|
{
|
|
|
|
|
if (Legal.getLineage(pkm).All(e => !Legal.Inherit_Sport.Contains(e)))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
else if (pkm.AbilityNumber == 4)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V122, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-03-23 02:47:13 +00:00
|
|
|
|
|
2016-11-11 05:10:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (ball == 0x19) // Dream Ball
|
2016-11-11 05:10:28 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (Legal.getLineage(pkm).Any(e => Legal.Inherit_Dream.Contains(e)))
|
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
2016-11-26 01:54:32 +00:00
|
|
|
|
if (pkm.AbilityNumber == 4 && Legal.Ban_DreamHidden.Contains(pkm.Species))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V122, CheckIdentifier.Ball);
|
2016-11-26 01:54:32 +00:00
|
|
|
|
|
2016-11-11 05:10:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (0x0D <= ball && ball <= 0x0F)
|
2016-11-11 05:10:28 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (!Legal.Ban_Gen4Ball_6.Contains(pkm.Species))
|
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
|
|
|
|
|
return;
|
2016-03-29 05:30:23 +00:00
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (0x02 <= ball && ball <= 0x0C) // Don't worry, Ball # 0x05 was already checked.
|
2016-11-11 05:10:28 +00:00
|
|
|
|
{
|
|
|
|
|
if (Legal.Ban_Gen3Ball.Contains(pkm.Species))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2017-04-02 13:39:39 +00:00
|
|
|
|
else if (pkm.AbilityNumber == 4 && Legal.Ban_Gen3BallHidden.Contains(pkm.SpecForm))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V122, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-03-21 15:01:08 +00:00
|
|
|
|
|
2016-11-11 05:10:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkm.Species > 650 && pkm.Species != 700) // Sylveon
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (Legal.getWildBalls(pkm).Contains(pkm.Ball))
|
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-11-12 14:52:40 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V125, CheckIdentifier.Ball);
|
2016-03-21 15:01:08 +00:00
|
|
|
|
}
|
2017-02-23 05:19:29 +00:00
|
|
|
|
private void verifyBallEggGen7()
|
2016-11-11 05:10:28 +00:00
|
|
|
|
{
|
2016-11-12 05:23:33 +00:00
|
|
|
|
var Lineage = Legal.getLineage(pkm).ToArray();
|
2016-12-02 02:48:38 +00:00
|
|
|
|
if (722 <= pkm.Species && pkm.Species <= 730) // G7 Starters
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(4);
|
2016-12-02 02:48:38 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
int ball = pkm.Ball;
|
|
|
|
|
if (ball == 0x05) // Safari Ball
|
2016-11-12 05:23:33 +00:00
|
|
|
|
{
|
2017-04-04 03:02:40 +00:00
|
|
|
|
if (!Lineage.Any(e => Legal.Inherit_Safari.Contains(e) || Legal.Inherit_SafariMale.Contains(e)))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2017-04-04 03:02:40 +00:00
|
|
|
|
else if (pkm.AbilityNumber == 4 && Lineage.Any(e => Legal.Ban_SafariBallHidden_7.Contains(e)))
|
|
|
|
|
AddLine(Severity.Invalid, V122, CheckIdentifier.Ball);
|
|
|
|
|
else
|
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-12 05:23:33 +00:00
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (0x10 < ball && ball < 0x18) // Apricorn Ball
|
2016-11-12 05:23:33 +00:00
|
|
|
|
{
|
2017-04-04 03:02:40 +00:00
|
|
|
|
if (!Lineage.Any(e => Legal.Inherit_Apricorn7.Contains(e)))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2017-04-04 03:02:40 +00:00
|
|
|
|
else if (pkm.AbilityNumber == 4 && (Lineage.Contains(029) || Lineage.Contains(032))) // Nido
|
|
|
|
|
AddLine(Severity.Invalid, V122, CheckIdentifier.Ball);
|
|
|
|
|
else
|
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-12 05:23:33 +00:00
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (ball == 0x18) // Sport Ball
|
2016-11-12 05:23:33 +00:00
|
|
|
|
{
|
2017-04-04 03:02:40 +00:00
|
|
|
|
if (!Lineage.Any(e => Legal.Inherit_Sport.Contains(e)))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2017-04-04 03:02:40 +00:00
|
|
|
|
else if (pkm.AbilityNumber == 4 && (Lineage.Contains(313) || Lineage.Contains(314))) // Volbeat/Illumise
|
|
|
|
|
AddLine(Severity.Invalid, V122, CheckIdentifier.Ball);
|
|
|
|
|
else
|
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-12 05:23:33 +00:00
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (ball == 0x19) // Dream Ball
|
2016-11-12 05:23:33 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (Lineage.Any(e => Legal.Inherit_Dream.Contains(e) || Legal.Inherit_DreamMale.Contains(e)))
|
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-12 05:23:33 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2016-11-12 05:23:33 +00:00
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (0x0D <= ball && ball <= 0x0F) // Dusk Heal Quick
|
2016-11-12 05:23:33 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (!Legal.Ban_Gen4Ball_7.Contains(pkm.Species))
|
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-12 05:23:33 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2016-11-12 05:23:33 +00:00
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (0x02 <= ball && ball <= 0x0C) // Don't worry, Ball # 0x05 was already checked.
|
2016-11-12 05:23:33 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (!Legal.Ban_Gen3Ball_7.Contains(pkm.Species))
|
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-12 05:23:33 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V121, CheckIdentifier.Ball);
|
2016-11-12 05:23:33 +00:00
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2016-11-12 14:52:40 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (ball == 26)
|
2016-11-12 14:52:40 +00:00
|
|
|
|
{
|
2016-11-14 06:24:29 +00:00
|
|
|
|
if ((pkm.Species > 731 && pkm.Species <= 785) || Lineage.Any(e => Legal.PastGenAlolanNatives.Contains(e)))
|
2016-11-12 14:52:40 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-12 14:52:40 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (Lineage.Any(e => Legal.PastGenAlolanScans.Contains(e)))
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, V123, CheckIdentifier.Ball);
|
2016-11-12 14:52:40 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// next statement catches all new alolans
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkm.Species > 721)
|
2016-11-11 05:10:28 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyBallEquals(Legal.getWildBalls(pkm));
|
2016-11-11 05:10:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-11-12 14:52:40 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (ball >= 27)
|
|
|
|
|
{
|
|
|
|
|
AddLine(Severity.Invalid, V126, CheckIdentifier.Ball);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
AddLine(Severity.Invalid, V125, CheckIdentifier.Ball);
|
2016-11-11 05:10:28 +00:00
|
|
|
|
}
|
2017-02-14 06:49:32 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private CheckResult verifyHistory()
|
2016-03-22 04:31:06 +00:00
|
|
|
|
{
|
2016-03-23 02:47:13 +00:00
|
|
|
|
if (!Encounter.Valid)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V127, CheckIdentifier.History);
|
2016-12-08 02:28:24 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.GenNumber < 6)
|
2016-12-08 02:28:24 +00:00
|
|
|
|
{
|
|
|
|
|
if (pkm.Format < 6)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V128, CheckIdentifier.History);
|
2016-12-08 02:28:24 +00:00
|
|
|
|
|
|
|
|
|
if (pkm.OT_Affection > 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V129, CheckIdentifier.History);
|
2016-12-08 02:28:24 +00:00
|
|
|
|
if (pkm.OT_Memory > 0 || pkm.OT_Feeling > 0 || pkm.OT_Intensity > 0 || pkm.OT_TextVar > 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V130, CheckIdentifier.History);
|
2016-12-08 02:28:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-02-07 06:19:10 +00:00
|
|
|
|
if (pkm.Format >= 6 && pkm.GenNumber != pkm.Format && pkm.CurrentHandler != 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V124, CheckIdentifier.History);
|
2017-02-07 06:19:10 +00:00
|
|
|
|
|
2016-12-08 02:28:24 +00:00
|
|
|
|
if (pkm.HT_Gender > 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, string.Format(V131, pkm.HT_Gender), CheckIdentifier.History);
|
2017-01-25 17:17:20 +00:00
|
|
|
|
|
2017-01-11 01:14:48 +00:00
|
|
|
|
MysteryGift mg = EncounterMatch as MysteryGift;
|
2016-03-23 05:49:46 +00:00
|
|
|
|
WC6 MatchedWC6 = EncounterMatch as WC6;
|
2017-01-11 01:14:48 +00:00
|
|
|
|
WC7 MatchedWC7 = EncounterMatch as WC7;
|
2016-03-22 04:31:06 +00:00
|
|
|
|
if (MatchedWC6?.OT.Length > 0) // Has Event OT -- null propagation yields false if MatchedWC6=null
|
|
|
|
|
{
|
2017-01-11 01:14:48 +00:00
|
|
|
|
if (pkm.OT_Friendship != PersonalTable.AO[MatchedWC6.Species].BaseFriendship)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V132, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.OT_Affection != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V133, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.CurrentHandler != 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V134, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
}
|
2017-01-11 01:14:48 +00:00
|
|
|
|
else if (MatchedWC7?.OT.Length > 0) // Has Event OT -- null propagation yields false if MatchedWC7=null
|
|
|
|
|
{
|
|
|
|
|
if (pkm.OT_Friendship != PersonalTable.SM[MatchedWC7.Species].BaseFriendship)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V132, CheckIdentifier.History);
|
2017-01-11 01:14:48 +00:00
|
|
|
|
if (pkm.OT_Affection != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V133, CheckIdentifier.History);
|
2017-01-11 01:14:48 +00:00
|
|
|
|
if (pkm.CurrentHandler != 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V134, CheckIdentifier.History);
|
2017-01-11 01:14:48 +00:00
|
|
|
|
}
|
|
|
|
|
else if (mg != null && mg.Format < 6 && pkm.Format >= 6)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.OT_Affection != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V133, CheckIdentifier.History);
|
2017-01-11 01:14:48 +00:00
|
|
|
|
if (pkm.CurrentHandler != 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V134, CheckIdentifier.History);
|
2017-01-11 01:14:48 +00:00
|
|
|
|
}
|
2017-01-31 01:49:28 +00:00
|
|
|
|
|
|
|
|
|
// Geolocations
|
|
|
|
|
var geo = new[]
|
2016-11-11 03:29:00 +00:00
|
|
|
|
{
|
2017-01-31 01:49:28 +00:00
|
|
|
|
pkm.Geo1_Country, pkm.Geo2_Country, pkm.Geo3_Country, pkm.Geo4_Country, pkm.Geo5_Country,
|
|
|
|
|
pkm.Geo1_Region, pkm.Geo2_Region, pkm.Geo3_Region, pkm.Geo4_Region, pkm.Geo5_Region,
|
|
|
|
|
};
|
2017-01-27 13:59:08 +00:00
|
|
|
|
|
2017-01-31 01:49:28 +00:00
|
|
|
|
// Check sequential order (no zero gaps)
|
|
|
|
|
bool geoEnd = false;
|
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
|
|
|
{
|
|
|
|
|
if (geoEnd && geo[i] != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V135, CheckIdentifier.History);
|
2017-01-27 13:59:08 +00:00
|
|
|
|
|
2017-01-31 01:49:28 +00:00
|
|
|
|
if (geo[i] != 0)
|
|
|
|
|
continue;
|
|
|
|
|
if (geo[i + 5] != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V136, CheckIdentifier.History);
|
2017-01-31 01:49:28 +00:00
|
|
|
|
geoEnd = true;
|
|
|
|
|
}
|
|
|
|
|
if (pkm.Format >= 7)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.VC1)
|
2017-01-27 13:59:08 +00:00
|
|
|
|
{
|
|
|
|
|
var hasGeo = geo.Any(d => d != 0);
|
|
|
|
|
|
|
|
|
|
if (!hasGeo)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V137, CheckIdentifier.History);
|
2017-01-27 13:59:08 +00:00
|
|
|
|
}
|
2016-12-03 03:50:02 +00:00
|
|
|
|
|
2017-01-25 17:17:20 +00:00
|
|
|
|
if (pkm.GenNumber >= 7 && pkm.CNTs.Any(stat => stat > 0))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V138, CheckIdentifier.History);
|
2016-12-03 03:50:02 +00:00
|
|
|
|
|
|
|
|
|
if (!pkm.WasEvent && pkm.HT_Name.Length == 0) // Is not Traded
|
|
|
|
|
{
|
|
|
|
|
if (pkm.CurrentHandler != 0) // Badly edited; PKHeX doesn't trip this.
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V139, CheckIdentifier.History);
|
2016-12-03 03:50:02 +00:00
|
|
|
|
if (pkm.HT_Friendship != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V140, CheckIdentifier.History);
|
2016-12-03 03:50:02 +00:00
|
|
|
|
if (pkm.HT_Affection != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V141, CheckIdentifier.History);
|
2016-12-03 03:50:02 +00:00
|
|
|
|
|
|
|
|
|
// We know it is untraded (HT is empty), if it must be trade evolved flag it.
|
2017-01-02 22:23:24 +00:00
|
|
|
|
if (Legal.getHasTradeEvolved(pkm) // if evo chain requires a trade
|
|
|
|
|
&& (EncounterMatch as EncounterSlot[])?.Any(slot => slot.Species == pkm.Species) != true // Wild Encounter
|
|
|
|
|
&& (EncounterMatch as EncounterStatic)?.Species != pkm.Species) // Static Encounter
|
2016-12-03 03:50:02 +00:00
|
|
|
|
{
|
|
|
|
|
if (pkm.Species != 350) // Milotic
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V142, CheckIdentifier.History);
|
2016-12-03 03:50:02 +00:00
|
|
|
|
if (pkm.CNT_Beauty < 170) // Beauty Contest Stat Requirement
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V143, CheckIdentifier.History);
|
2016-12-03 03:50:02 +00:00
|
|
|
|
if (pkm.CurrentLevel == 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V144, CheckIdentifier.History);
|
2016-12-03 03:50:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V145, CheckIdentifier.History);
|
2016-11-11 03:29:00 +00:00
|
|
|
|
}
|
2017-04-01 21:20:00 +00:00
|
|
|
|
|
|
|
|
|
// Determine if we should check for Handling Trainer Memories
|
|
|
|
|
// A Pokémon is untraded if...
|
|
|
|
|
bool untraded = pkm.HT_Name.Length == 0 || pkm.Geo1_Country == 0;
|
|
|
|
|
if (EncounterIsMysteryGift)
|
|
|
|
|
{
|
|
|
|
|
untraded |= !pkm.WasEventEgg;
|
|
|
|
|
untraded &= pkm.WasEgg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkm.WasLink && (EncounterMatch as EncounterLink)?.OT == false)
|
|
|
|
|
untraded = false;
|
|
|
|
|
else if (pkm.GenNumber < 6)
|
|
|
|
|
untraded = false;
|
|
|
|
|
|
|
|
|
|
if (untraded) // Is not Traded
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
|
|
|
|
if (pkm.HT_Name.Length != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V146, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.Geo1_Country != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V147, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.HT_Memory != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V148, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.CurrentHandler != 0) // Badly edited; PKHeX doesn't trip this.
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V139, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.HT_Friendship != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V140, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.HT_Affection != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V141, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.XY && pkm.CNTs.Any(stat => stat > 0))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V138, CheckIdentifier.History);
|
2016-03-22 04:31:06 +00:00
|
|
|
|
|
|
|
|
|
// We know it is untraded (HT is empty), if it must be trade evolved flag it.
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (Legal.getHasTradeEvolved(pkm) && (EncounterMatch as EncounterSlot[])?.Any(slot => slot.Species == pkm.Species) != true)
|
2016-03-22 04:31:06 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.Species != 350) // Milotic
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V142, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.CNT_Beauty < 170) // Beauty Contest Stat Requirement
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V143, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.CurrentLevel == 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V144, CheckIdentifier.History);
|
2016-03-22 04:31:06 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // Is Traded
|
|
|
|
|
{
|
2017-02-23 05:19:29 +00:00
|
|
|
|
if (pkm.Format == 6 && pkm.HT_Memory == 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V150, CheckIdentifier.History);
|
2016-03-22 04:31:06 +00:00
|
|
|
|
}
|
2016-03-31 01:53:34 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
// Memory ChecksResult
|
|
|
|
|
if (pkm.IsEgg)
|
2016-03-31 01:53:34 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.HT_Memory != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V149, CheckIdentifier.History);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.OT_Memory != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V151, CheckIdentifier.History);
|
2016-03-31 01:53:34 +00:00
|
|
|
|
}
|
|
|
|
|
else if (EncounterType != typeof(WC6))
|
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.OT_Memory == 0 ^ !pkm.Gen6)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V152, CheckIdentifier.History);
|
2016-11-11 06:11:53 +00:00
|
|
|
|
if (pkm.GenNumber < 6 && pkm.OT_Affection != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, V129, CheckIdentifier.History);
|
2016-03-31 01:53:34 +00:00
|
|
|
|
}
|
2016-03-22 04:31:06 +00:00
|
|
|
|
// Unimplemented: Ingame Trade Memories
|
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, V145, CheckIdentifier.History);
|
2016-03-22 04:31:06 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private CheckResult verifyCommonMemory(int handler)
|
2016-05-07 06:16:35 +00:00
|
|
|
|
{
|
|
|
|
|
int m = 0;
|
2016-05-09 23:09:40 +00:00
|
|
|
|
int t = 0;
|
2016-05-07 06:16:35 +00:00
|
|
|
|
string resultPrefix = "";
|
|
|
|
|
switch (handler)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
2016-10-23 19:48:49 +00:00
|
|
|
|
m = pkm.OT_Memory;
|
|
|
|
|
t = pkm.OT_TextVar;
|
2017-03-21 07:18:38 +00:00
|
|
|
|
resultPrefix = V205;
|
2016-05-07 06:16:35 +00:00
|
|
|
|
break;
|
|
|
|
|
case 1:
|
2016-10-23 19:48:49 +00:00
|
|
|
|
m = pkm.HT_Memory;
|
|
|
|
|
t = pkm.HT_TextVar;
|
2017-03-21 07:18:38 +00:00
|
|
|
|
resultPrefix = V206;
|
2016-05-07 06:16:35 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
int matchingMoveMemory = Array.IndexOf(Legal.MoveSpecificMemories[0], m);
|
2017-02-21 03:40:50 +00:00
|
|
|
|
if (matchingMoveMemory != -1 && pkm.Species != 235 && !Legal.getCanLearnMachineMove(pkm, Legal.MoveSpecificMemories[1][matchingMoveMemory], 6))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, string.Format(V153, resultPrefix), CheckIdentifier.Memory);
|
2017-02-21 03:40:50 +00:00
|
|
|
|
|
2016-05-09 23:09:40 +00:00
|
|
|
|
if (m == 6 && !Legal.LocationsWithPKCenter[0].Contains(t))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, string.Format(V154, resultPrefix), CheckIdentifier.Memory);
|
2017-02-21 03:40:50 +00:00
|
|
|
|
|
2016-05-10 01:19:31 +00:00
|
|
|
|
if (m == 21) // {0} saw {2} carrying {1} on its back. {4} that {3}.
|
2017-02-21 03:40:50 +00:00
|
|
|
|
if (!Legal.getCanLearnMachineMove(new PK6 {Species = t, EXP = PKX.getEXP(100, t)}, 19, 6))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, string.Format(V153, resultPrefix), CheckIdentifier.Memory);
|
2017-02-21 03:40:50 +00:00
|
|
|
|
|
|
|
|
|
if ((m == 16 || m == 48) && (t == 0 || !Legal.getCanKnowMove(pkm, t, 6)))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, string.Format(V153, resultPrefix), CheckIdentifier.Memory);
|
2017-02-21 03:40:50 +00:00
|
|
|
|
|
|
|
|
|
if (m == 49 && (t == 0 || !Legal.getCanRelearnMove(pkm, t, 6))) // {0} was able to remember {2} at {1}'s instruction. {4} that {3}.
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Invalid, string.Format(V153, resultPrefix), CheckIdentifier.Memory);
|
2017-02-21 03:40:50 +00:00
|
|
|
|
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, string.Format(V155, resultPrefix), CheckIdentifier.Memory);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void verifyOTMemoryIs(int[] values)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.OT_Memory != values[0])
|
|
|
|
|
AddLine(Severity.Invalid, string.Format(V197, V205, values[0]), CheckIdentifier.Memory);
|
|
|
|
|
if (pkm.OT_Intensity != values[1])
|
|
|
|
|
AddLine(Severity.Invalid, string.Format(V198, V205, values[1]), CheckIdentifier.Memory);
|
|
|
|
|
if (pkm.OT_TextVar != values[2])
|
|
|
|
|
AddLine(Severity.Invalid, string.Format(V199, V205, values[2]), CheckIdentifier.Memory);
|
|
|
|
|
if (pkm.OT_Feeling != values[3])
|
|
|
|
|
AddLine(Severity.Invalid, string.Format(V200, V205, values[3]), CheckIdentifier.Memory);
|
2016-05-07 06:16:35 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyOTMemory()
|
2016-05-06 03:05:22 +00:00
|
|
|
|
{
|
2016-11-26 01:30:39 +00:00
|
|
|
|
if (pkm.Format < 6)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-11-26 01:30:39 +00:00
|
|
|
|
|
|
|
|
|
if (!History.Valid)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-05-06 03:05:22 +00:00
|
|
|
|
|
2016-11-26 01:30:39 +00:00
|
|
|
|
if (pkm.GenNumber < 6)
|
2016-05-06 03:05:22 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyOTMemoryIs(new [] {0,0,0,0}); // empty
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-05-06 03:05:22 +00:00
|
|
|
|
}
|
2016-11-26 01:30:39 +00:00
|
|
|
|
|
2017-01-25 17:17:20 +00:00
|
|
|
|
if (EncounterType == typeof(EncounterTrade))
|
|
|
|
|
{
|
|
|
|
|
// Undocumented, uncommon, and insignificant -- don't bother.
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-01-26 02:51:15 +00:00
|
|
|
|
if (EncounterType == typeof(WC6))
|
2016-05-06 03:05:22 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
WC6 g = EncounterMatch as WC6;
|
|
|
|
|
verifyOTMemoryIs(new[] {g.OT_Memory, g.OT_Intensity, g.OT_TextVar, g.OT_Feeling});
|
|
|
|
|
return;
|
2016-05-06 03:05:22 +00:00
|
|
|
|
}
|
2016-11-26 01:30:39 +00:00
|
|
|
|
if (EncounterType == typeof(WC7))
|
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
WC7 g = EncounterMatch as WC7;
|
|
|
|
|
verifyOTMemoryIs(new[] {g.OT_Memory, g.OT_Intensity, g.OT_TextVar, g.OT_Feeling});
|
|
|
|
|
return;
|
2016-11-26 01:30:39 +00:00
|
|
|
|
}
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (pkm.GenNumber >= 7)
|
2016-11-26 01:30:39 +00:00
|
|
|
|
{
|
2017-03-21 07:18:38 +00:00
|
|
|
|
verifyOTMemoryIs(new[] {0, 0, 0, 0}); // empty
|
2016-11-26 01:30:39 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
switch (pkm.OT_Memory)
|
2016-05-06 03:05:22 +00:00
|
|
|
|
{
|
2016-05-25 05:20:19 +00:00
|
|
|
|
case 2: // {0} hatched from an Egg and saw {1} for the first time at... {2}. {4} that {3}.
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (!pkm.WasEgg && pkm.Egg_Location != 60004)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V160, V205), CheckIdentifier.Memory);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2016-05-06 03:05:22 +00:00
|
|
|
|
case 4: // {0} became {1}’s friend when it arrived via Link Trade at... {2}. {4} that {3}.
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V161, V205), CheckIdentifier.Memory);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2016-05-09 23:09:40 +00:00
|
|
|
|
case 6: // {0} went to the Pokémon Center in {2} with {1} and had its tired body healed there. {4} that {3}.
|
2016-10-23 19:48:49 +00:00
|
|
|
|
int matchingOriginGame = Array.IndexOf(Legal.LocationsWithPKCenter[0], pkm.OT_TextVar);
|
2016-05-10 00:51:35 +00:00
|
|
|
|
if (matchingOriginGame != -1)
|
|
|
|
|
{
|
|
|
|
|
int gameID = Legal.LocationsWithPKCenter[1][matchingOriginGame];
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.XY && gameID != 0 || pkm.AO && gameID != 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V162, V205), CheckIdentifier.Memory);
|
2016-05-10 00:51:35 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
AddLine(verifyCommonMemory(0));
|
|
|
|
|
return;
|
|
|
|
|
|
2016-05-06 03:35:18 +00:00
|
|
|
|
case 14:
|
2016-11-09 06:10:32 +00:00
|
|
|
|
if (!Legal.getCanBeCaptured(pkm.OT_TextVar, pkm.GenNumber, (GameVersion)pkm.Version))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V165, V205), CheckIdentifier.Memory);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Valid, string.Format(V164, V205), CheckIdentifier.Memory);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-05-06 03:05:22 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.XY && Legal.Memory_NotXY.Contains(pkm.OT_Memory))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V163, V205), CheckIdentifier.Memory);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.AO && Legal.Memory_NotAO.Contains(pkm.OT_Memory))
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V163, V205), CheckIdentifier.Memory);
|
2016-05-06 03:05:22 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
AddLine(verifyCommonMemory(0));
|
2016-05-06 03:05:22 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyHTMemory()
|
2016-05-06 03:05:22 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.Format < 6)
|
|
|
|
|
return;
|
|
|
|
|
|
2016-05-06 03:05:22 +00:00
|
|
|
|
if (!History.Valid)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-05-06 03:05:22 +00:00
|
|
|
|
|
2017-03-12 23:36:23 +00:00
|
|
|
|
if (pkm.Format >= 7)
|
2016-11-26 01:30:39 +00:00
|
|
|
|
{
|
2017-03-12 23:36:23 +00:00
|
|
|
|
/*
|
|
|
|
|
* Bank Transfer adds in the Link Trade Memory.
|
|
|
|
|
* Trading 7<->7 between games (not Bank) clears this data.
|
|
|
|
|
*/
|
|
|
|
|
if (pkm.HT_Memory == 0)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.HT_TextVar != 0 || pkm.HT_Intensity != 0 || pkm.HT_Feeling != 0)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V329, CheckIdentifier.Memory);
|
2017-01-27 13:59:08 +00:00
|
|
|
|
return;
|
2017-03-12 23:36:23 +00:00
|
|
|
|
}
|
2017-01-27 04:13:27 +00:00
|
|
|
|
|
2017-01-27 13:59:08 +00:00
|
|
|
|
if (pkm.HT_Memory != 4)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V156, CheckIdentifier.Memory);
|
2017-01-27 05:35:26 +00:00
|
|
|
|
if (pkm.HT_TextVar != 0)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V157, CheckIdentifier.Memory);
|
2017-01-27 13:59:08 +00:00
|
|
|
|
if (pkm.HT_Intensity != 1)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V158, CheckIdentifier.Memory);
|
2017-01-27 13:59:08 +00:00
|
|
|
|
if (pkm.HT_Feeling > 10)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V159, CheckIdentifier.Memory);
|
2016-11-26 01:30:39 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
switch (pkm.HT_Memory)
|
2016-05-06 03:05:22 +00:00
|
|
|
|
{
|
2017-01-27 04:13:27 +00:00
|
|
|
|
case 0:
|
2017-01-27 13:59:08 +00:00
|
|
|
|
if (string.IsNullOrEmpty(pkm.HT_Name))
|
2017-01-27 04:13:27 +00:00
|
|
|
|
return;
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, V150, CheckIdentifier.Memory); return;
|
2016-05-06 03:05:22 +00:00
|
|
|
|
case 1: // {0} met {1} at... {2}. {1} threw a Poké Ball at it, and they started to travel together. {4} that {3}.
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V202, V206), CheckIdentifier.Memory); return;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
2016-05-06 03:05:22 +00:00
|
|
|
|
case 2: // {0} hatched from an Egg and saw {1} for the first time at... {2}. {4} that {3}.
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V160, V206), CheckIdentifier.Memory); return;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
2016-05-06 03:35:18 +00:00
|
|
|
|
case 14:
|
2017-03-21 07:18:38 +00:00
|
|
|
|
if (Legal.getCanBeCaptured(pkm.HT_TextVar, pkm.GenNumber))
|
|
|
|
|
AddLine(Severity.Valid, string.Format(V164, V206), CheckIdentifier.Memory);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else
|
2017-03-21 07:18:38 +00:00
|
|
|
|
AddLine(Severity.Invalid, string.Format(V165, V206), CheckIdentifier.Memory);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-05-06 03:05:22 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
AddLine(verifyCommonMemory(1));
|
2016-05-06 03:05:22 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyRegion()
|
2016-05-11 23:20:31 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.Format < 6)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
bool pass;
|
|
|
|
|
switch (pkm.ConsoleRegion)
|
2016-05-11 23:20:31 +00:00
|
|
|
|
{
|
2016-05-12 04:18:05 +00:00
|
|
|
|
case 0: // Japan
|
2016-10-23 19:48:49 +00:00
|
|
|
|
pass = pkm.Country == 1;
|
2016-05-11 23:20:31 +00:00
|
|
|
|
break;
|
2016-05-12 04:18:05 +00:00
|
|
|
|
case 1: // Americas
|
2016-10-23 19:48:49 +00:00
|
|
|
|
pass = 8 <= pkm.Country && pkm.Country <= 52 || new[] {153, 156, 168, 174, 186}.Contains(pkm.Country);
|
2016-05-11 23:20:31 +00:00
|
|
|
|
break;
|
2016-05-12 04:18:05 +00:00
|
|
|
|
case 2: // Europe
|
2016-10-23 19:48:49 +00:00
|
|
|
|
pass = 64 <= pkm.Country && pkm.Country <= 127 || new[] {169, 184, 185}.Contains(pkm.Country);
|
2016-05-11 23:20:31 +00:00
|
|
|
|
break;
|
2016-05-12 04:18:05 +00:00
|
|
|
|
case 4: // China
|
2016-10-23 19:48:49 +00:00
|
|
|
|
pass = pkm.Country == 144 || pkm.Country == 160;
|
2016-05-11 23:20:31 +00:00
|
|
|
|
break;
|
2016-05-12 04:18:05 +00:00
|
|
|
|
case 5: // Korea
|
2016-10-23 19:48:49 +00:00
|
|
|
|
pass = pkm.Country == 136;
|
2016-05-11 23:20:31 +00:00
|
|
|
|
break;
|
2016-05-12 04:18:05 +00:00
|
|
|
|
case 6: // Taiwan
|
2016-10-23 19:48:49 +00:00
|
|
|
|
pass = pkm.Country == 128;
|
2016-05-11 23:20:31 +00:00
|
|
|
|
break;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
default:
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(new CheckResult(Severity.Invalid, V301, CheckIdentifier.Geography));
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-05-11 23:20:31 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
|
|
|
|
if (!pass)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V302, CheckIdentifier.Geography);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Valid, V303, CheckIdentifier.Geography);
|
2016-05-11 23:20:31 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyForm()
|
2016-04-14 10:17:03 +00:00
|
|
|
|
{
|
|
|
|
|
if (!Encounter.Valid)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
2016-04-14 10:17:03 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.Format < 4)
|
|
|
|
|
return;
|
|
|
|
|
|
2016-11-09 05:43:22 +00:00
|
|
|
|
if (pkm.AltForm > pkm.PersonalInfo.FormeCount)
|
|
|
|
|
{
|
2016-11-14 15:33:39 +00:00
|
|
|
|
bool valid = false;
|
|
|
|
|
int species = pkm.Species;
|
|
|
|
|
if (species == 201) // Unown
|
|
|
|
|
{
|
2017-03-25 17:24:56 +00:00
|
|
|
|
int maxCount = pkm.GenNumber == 2 ? 26 : 28; // A-Z : A-Z?!
|
|
|
|
|
if (pkm.AltForm < maxCount)
|
2016-11-14 15:33:39 +00:00
|
|
|
|
valid = true;
|
|
|
|
|
}
|
|
|
|
|
if (species == 414 && pkm.AltForm < 3) // Wormadam base form kept
|
2017-03-25 17:24:56 +00:00
|
|
|
|
valid = true;
|
2016-11-14 15:33:39 +00:00
|
|
|
|
|
|
|
|
|
if ((species == 664 || species == 665) && pkm.AltForm < 18) // Vivillon Pre-evolutions
|
|
|
|
|
valid = true;
|
|
|
|
|
|
|
|
|
|
if (!valid) // ignore list
|
2017-03-23 03:12:45 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, string.Format(V304, pkm.PersonalInfo.FormeCount, pkm.AltForm), CheckIdentifier.Form); return; }
|
2016-11-09 05:43:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
switch (pkm.Species)
|
2016-04-14 10:17:03 +00:00
|
|
|
|
{
|
2016-11-14 02:25:33 +00:00
|
|
|
|
case 25: // Pikachu
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.Format == 6 && pkm.AltForm != 0 ^ EncounterType == typeof(EncounterStatic))
|
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
string msg = EncounterType == typeof (EncounterStatic) ? V305 : V306;
|
2017-02-21 03:40:50 +00:00
|
|
|
|
AddLine(Severity.Invalid, msg, CheckIdentifier.Form);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-11-09 07:37:53 +00:00
|
|
|
|
if (pkm.Format == 7 && pkm.AltForm != 0 ^ EncounterIsMysteryGift)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
{
|
2016-11-14 02:25:33 +00:00
|
|
|
|
var gift = EncounterMatch as WC7;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (gift != null && gift.Form != pkm.AltForm)
|
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V307, CheckIdentifier.Form);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-04-23 21:16:12 +00:00
|
|
|
|
break;
|
2017-01-31 22:01:32 +00:00
|
|
|
|
case 487: // Giratina
|
2017-02-03 03:30:17 +00:00
|
|
|
|
if (pkm.AltForm == 1 ^ pkm.HeldItem == 112) // Origin form only with Griseous Orb
|
2017-01-31 22:01:32 +00:00
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V308, CheckIdentifier.Form);
|
2017-01-31 22:01:32 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-02-01 04:11:11 +00:00
|
|
|
|
case 493: // Arceus
|
|
|
|
|
{
|
|
|
|
|
int item = pkm.HeldItem;
|
|
|
|
|
int form = 0;
|
|
|
|
|
if ((298 <= item && item <= 313) || item == 644)
|
|
|
|
|
form = Array.IndexOf(Legal.Arceus_Plate, item) + 1;
|
|
|
|
|
else if (777 <= item && item <= 793)
|
|
|
|
|
form = Array.IndexOf(Legal.Arceus_ZCrystal, item) + 1;
|
|
|
|
|
if (form != pkm.AltForm)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V308, CheckIdentifier.Form);
|
2017-02-01 04:11:11 +00:00
|
|
|
|
else if (form != 0)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Valid, V309, CheckIdentifier.Form);
|
2017-02-01 04:11:11 +00:00
|
|
|
|
}
|
2017-02-13 01:06:09 +00:00
|
|
|
|
break;
|
2017-03-23 06:34:35 +00:00
|
|
|
|
case 647: // Keldeo
|
|
|
|
|
{
|
|
|
|
|
int index = Array.IndexOf(pkm.Moves, 548); // Secret Sword
|
|
|
|
|
bool noSword = index < 0;
|
|
|
|
|
if (pkm.AltForm == 0 ^ noSword) // mismatch
|
|
|
|
|
vMoves[noSword ? 0 : index] = new CheckResult(Severity.Invalid, V169, CheckIdentifier.Move);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-02-13 01:06:09 +00:00
|
|
|
|
case 649: // Genesect
|
|
|
|
|
{
|
|
|
|
|
int item = pkm.HeldItem;
|
|
|
|
|
int form = 0;
|
|
|
|
|
if (116 <= item && item <= 119)
|
|
|
|
|
form = item - 115;
|
|
|
|
|
|
|
|
|
|
if (form != pkm.AltForm)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V308, CheckIdentifier.Form);
|
2017-02-13 01:06:09 +00:00
|
|
|
|
else
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Valid, V309, CheckIdentifier.Form);
|
2017-02-13 01:06:09 +00:00
|
|
|
|
}
|
2017-02-01 04:11:11 +00:00
|
|
|
|
break;
|
2016-11-14 02:25:33 +00:00
|
|
|
|
case 658: // Greninja
|
2016-11-09 05:43:22 +00:00
|
|
|
|
if (pkm.AltForm > 1) // Ash Battle Bond active
|
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V310, CheckIdentifier.Form);
|
2016-11-09 05:43:22 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2016-11-14 02:25:33 +00:00
|
|
|
|
case 664: // Scatterbug
|
|
|
|
|
case 665: // Spewpa
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.AltForm > 17) // Fancy & Pokéball
|
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V311, CheckIdentifier.Form);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
if (!Legal.CheckVivillonPattern(pkm.AltForm, pkm.Country, pkm.Region))
|
|
|
|
|
AddLine(Severity.Fishy, V312, CheckIdentifier.Form);
|
2016-04-14 10:17:03 +00:00
|
|
|
|
break;
|
2016-11-14 02:25:33 +00:00
|
|
|
|
case 666: // Vivillon
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.AltForm > 17) // Fancy & Pokéball
|
|
|
|
|
{
|
2016-11-09 07:37:53 +00:00
|
|
|
|
if (!EncounterIsMysteryGift)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V312, CheckIdentifier.Form);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Valid, V313, CheckIdentifier.Form);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
if (!Legal.CheckVivillonPattern(pkm.AltForm, pkm.Country, pkm.Region))
|
|
|
|
|
AddLine(Severity.Fishy, V312, CheckIdentifier.Form);
|
2016-04-14 10:17:03 +00:00
|
|
|
|
break;
|
2016-11-14 02:25:33 +00:00
|
|
|
|
case 670: // Floette
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.AltForm == 5) // Eternal Flower -- Never Released
|
|
|
|
|
{
|
2016-11-09 07:37:53 +00:00
|
|
|
|
if (!EncounterIsMysteryGift)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V314, CheckIdentifier.Form);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
else
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Valid, V315, CheckIdentifier.Form);
|
2016-10-23 19:48:49 +00:00
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
2016-04-14 10:17:03 +00:00
|
|
|
|
break;
|
2016-11-14 02:25:33 +00:00
|
|
|
|
case 718: // Zygarde
|
2016-11-09 05:43:22 +00:00
|
|
|
|
if (pkm.AltForm >= 4)
|
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V310, CheckIdentifier.Form);
|
2016-11-09 05:43:22 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-02-01 04:11:11 +00:00
|
|
|
|
case 773: // Silvally
|
|
|
|
|
{
|
|
|
|
|
int item = pkm.HeldItem;
|
|
|
|
|
int form = 0;
|
|
|
|
|
if ((904 <= item && item <= 920) || item == 644)
|
|
|
|
|
form = item - 903;
|
|
|
|
|
if (form != pkm.AltForm)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V308, CheckIdentifier.Form);
|
2017-02-01 04:11:11 +00:00
|
|
|
|
else if (form != 0)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Valid, V309, CheckIdentifier.Form);
|
2017-02-01 04:11:11 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2016-11-14 02:25:33 +00:00
|
|
|
|
case 774: // Minior
|
|
|
|
|
if (pkm.AltForm < 7)
|
2016-11-09 05:43:22 +00:00
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V310, CheckIdentifier.Form);
|
2016-11-09 05:43:22 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-02-03 03:27:48 +00:00
|
|
|
|
|
|
|
|
|
// Party Only Forms
|
|
|
|
|
case 492: // Shaymin
|
|
|
|
|
case 676: // Furfrou
|
|
|
|
|
case 720: // Hoopa
|
|
|
|
|
if (pkm.AltForm != 0 && pkm.Box > -1) // has form but stored in box
|
2017-02-03 03:30:17 +00:00
|
|
|
|
{
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V316, CheckIdentifier.Form);
|
2017-02-03 03:30:17 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2017-02-03 03:27:48 +00:00
|
|
|
|
break;
|
2016-04-14 10:17:03 +00:00
|
|
|
|
}
|
2016-11-14 02:19:09 +00:00
|
|
|
|
|
2017-02-02 05:59:39 +00:00
|
|
|
|
if (pkm.Format >= 7 && pkm.GenNumber < 7 && pkm.AltForm != 0)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.Species == 25 || Legal.AlolanOriginForms.Contains(pkm.Species))
|
2017-03-23 03:12:45 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V317, CheckIdentifier.Form); return; }
|
2017-02-02 05:59:39 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.AltForm > 0 && new[] {Legal.BattleForms, Legal.BattleMegas, Legal.BattlePrimals}.Any(arr => arr.Contains(pkm.Species)))
|
2017-03-23 03:12:45 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V310, CheckIdentifier.Form); return; }
|
2016-04-14 10:17:03 +00:00
|
|
|
|
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Valid, V318, CheckIdentifier.Form);
|
2016-04-14 10:17:03 +00:00
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private void verifyMisc()
|
2016-04-22 02:32:22 +00:00
|
|
|
|
{
|
2017-01-26 19:16:21 +00:00
|
|
|
|
if (pkm.Format == 7 && ((PK7)pkm).PelagoEventStatus != 0)
|
|
|
|
|
{
|
|
|
|
|
// TODO: Figure out what PelagoEventStati are legal.
|
|
|
|
|
}
|
2017-01-25 07:34:50 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.IsEgg)
|
2016-09-03 15:10:22 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (new[] {pkm.Move1_PPUps, pkm.Move2_PPUps, pkm.Move3_PPUps, pkm.Move4_PPUps}.Any(ppup => ppup > 0))
|
2017-03-23 03:12:45 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V319, CheckIdentifier.Misc); return; }
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.CNTs.Any(stat => stat > 0))
|
2017-03-23 03:12:45 +00:00
|
|
|
|
{ AddLine(Severity.Invalid, V320, CheckIdentifier.Misc); return; }
|
2016-09-03 15:10:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-12-11 02:55:04 +00:00
|
|
|
|
if (Encounter.Valid)
|
2016-04-22 02:32:22 +00:00
|
|
|
|
{
|
2016-12-11 02:55:04 +00:00
|
|
|
|
if (EncounterIsMysteryGift)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.FatefulEncounter)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Valid, V321, CheckIdentifier.Fateful);
|
2016-12-11 02:55:04 +00:00
|
|
|
|
else
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V322, CheckIdentifier.Fateful);
|
2016-12-11 02:55:04 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2016-11-13 17:37:28 +00:00
|
|
|
|
if (EncounterType == typeof (EncounterStatic))
|
|
|
|
|
{
|
|
|
|
|
var enc = EncounterMatch as EncounterStatic;
|
|
|
|
|
if (enc.Fateful)
|
2016-12-11 02:55:04 +00:00
|
|
|
|
{
|
|
|
|
|
if (pkm.FatefulEncounter)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Valid, V323, CheckIdentifier.Fateful);
|
2016-12-11 02:55:04 +00:00
|
|
|
|
else
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V324, CheckIdentifier.Fateful);
|
2016-12-11 02:55:04 +00:00
|
|
|
|
}
|
|
|
|
|
else if (pkm.FatefulEncounter)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V325, CheckIdentifier.Fateful);
|
2016-11-13 17:37:28 +00:00
|
|
|
|
}
|
2017-04-02 13:39:39 +00:00
|
|
|
|
else if (pkm.FatefulEncounter)
|
2017-03-30 22:14:52 +00:00
|
|
|
|
AddLine(Severity.Invalid, V325, CheckIdentifier.Fateful);
|
|
|
|
|
|
2017-04-02 13:39:39 +00:00
|
|
|
|
if (pkm.GenNumber == 5)
|
2017-03-19 17:44:46 +00:00
|
|
|
|
{
|
|
|
|
|
var enc = EncounterMatch as EncounterStatic;
|
|
|
|
|
bool req = enc?.NSparkle ?? false;
|
2017-04-02 13:39:39 +00:00
|
|
|
|
if (pkm.Format == 5)
|
|
|
|
|
{
|
|
|
|
|
bool has = ((PK5)pkm).NPokémon;
|
|
|
|
|
if (req && !has)
|
|
|
|
|
AddLine(Severity.Invalid, V326, CheckIdentifier.Fateful);
|
|
|
|
|
if (!req && has)
|
|
|
|
|
AddLine(Severity.Invalid, V327, CheckIdentifier.Fateful);
|
|
|
|
|
}
|
|
|
|
|
if (req)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.IVs.Any(iv => iv != 30))
|
|
|
|
|
AddLine(Severity.Invalid, V218, CheckIdentifier.IVs);
|
|
|
|
|
if (pkm.OT_Name != "N" || pkm.TID != 00002 || pkm.SID != 00000)
|
|
|
|
|
AddLine(Severity.Invalid, V219, CheckIdentifier.Trainer);
|
|
|
|
|
if (pkm.IsShiny)
|
|
|
|
|
AddLine(Severity.Invalid, V220, CheckIdentifier.Shiny);
|
|
|
|
|
}
|
2017-03-19 17:44:46 +00:00
|
|
|
|
}
|
2016-04-22 02:32:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-12-01 03:37:53 +00:00
|
|
|
|
private void verifyVersionEvolution()
|
|
|
|
|
{
|
|
|
|
|
if (pkm.Format < 7)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// No point using the evolution tree. Just handle certain species.
|
|
|
|
|
switch (pkm.Species)
|
|
|
|
|
{
|
|
|
|
|
case 745: // Lycanroc
|
|
|
|
|
if (!pkm.WasEgg)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (pkm.AltForm == 0 && pkm.Version == 31 // Moon
|
|
|
|
|
|| pkm.AltForm == 1 && pkm.Version == 30) // Sun
|
|
|
|
|
if (pkm.IsUntraded)
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V328, CheckIdentifier.Evolution);
|
2016-12-01 03:37:53 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 791: // Solgaleo
|
|
|
|
|
if (pkm.Version == 31 && pkm.IsUntraded)
|
|
|
|
|
{
|
|
|
|
|
if (EncounterIsMysteryGift && (EncounterMatch as MysteryGift).Species == pkm.Species) // Gifted via Mystery Gift
|
|
|
|
|
break;
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V328, CheckIdentifier.Evolution);
|
2016-12-01 03:37:53 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 792: // Lunala
|
|
|
|
|
if (pkm.Version == 30 && pkm.IsUntraded)
|
|
|
|
|
{
|
|
|
|
|
if (EncounterIsMysteryGift && (EncounterMatch as MysteryGift).Species == pkm.Species) // Gifted via Mystery Gift
|
|
|
|
|
break;
|
2017-03-23 03:12:45 +00:00
|
|
|
|
AddLine(Severity.Invalid, V328, CheckIdentifier.Evolution);
|
2016-12-01 03:37:53 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-28 04:57:24 +00:00
|
|
|
|
private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any)
|
2016-03-12 17:16:41 +00:00
|
|
|
|
{
|
2017-03-25 15:41:45 +00:00
|
|
|
|
var validLevelMoves = Legal.getValidMovesAllGens(pkm, EvoChainsAllGens, Tutor: false, Machine: false, RemoveTransferHM:false);
|
|
|
|
|
var validTMHM = Legal.getValidMovesAllGens(pkm, EvoChainsAllGens, LVL: false, Tutor: false, MoveReminder: false, RemoveTransferHM: false);
|
|
|
|
|
var validTutor = Legal.getValidMovesAllGens(pkm, EvoChainsAllGens, LVL: false, Machine: false, MoveReminder: false, RemoveTransferHM: false);
|
|
|
|
|
Legal.RemoveFutureMoves(pkm, EvoChainsAllGens, ref validLevelMoves, ref validTMHM, ref validTutor);
|
2017-04-01 18:32:59 +00:00
|
|
|
|
CheckResult[] res;
|
2017-03-23 06:34:35 +00:00
|
|
|
|
int[] Moves = pkm.Moves;
|
2017-04-01 16:45:13 +00:00
|
|
|
|
if (!pkm.IsEgg && pkm.Species == 235) // Smeargle can have any move except a few
|
|
|
|
|
res = parseMovesSketch(Moves);
|
|
|
|
|
else if (pkm.GenNumber < 6)
|
2017-04-01 18:32:59 +00:00
|
|
|
|
res = parseMovesPre3DS(game, validLevelMoves, validTMHM, validTutor, Moves);
|
2017-04-04 02:59:29 +00:00
|
|
|
|
else
|
|
|
|
|
res = parseMoves3DS(game, validLevelMoves, validTMHM, validTutor, Moves);
|
2017-03-23 06:34:35 +00:00
|
|
|
|
|
|
|
|
|
// Duplicate Moves Check
|
|
|
|
|
verifyNoEmptyDuplicates(Moves, res);
|
|
|
|
|
if (Moves[0] == 0) // Can't have an empty moveslot for the first move.
|
|
|
|
|
res[0] = new CheckResult(Severity.Invalid, V167, CheckIdentifier.Move);
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2017-03-26 17:17:30 +00:00
|
|
|
|
private GameVersion[] getBaseMovesIsEggGames()
|
2017-03-25 17:24:56 +00:00
|
|
|
|
{
|
2017-03-26 17:17:30 +00:00
|
|
|
|
GameVersion[] Games = { };
|
2017-03-25 17:24:56 +00:00
|
|
|
|
switch (pkm.GenNumber)
|
|
|
|
|
{
|
2017-03-26 02:57:38 +00:00
|
|
|
|
case 1:
|
|
|
|
|
case 2:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.GS, GameVersion.C };
|
|
|
|
|
break;
|
2017-03-25 17:24:56 +00:00
|
|
|
|
case 3:
|
2017-04-01 18:32:59 +00:00
|
|
|
|
switch ((GameVersion)pkm.Version)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
|
|
|
|
case GameVersion.R:
|
|
|
|
|
case GameVersion.S:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.RS};
|
|
|
|
|
break;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
case GameVersion.E:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.E };
|
|
|
|
|
break;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
case GameVersion.FR:
|
|
|
|
|
case GameVersion.LG:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.FRLG };
|
|
|
|
|
break;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
break;
|
|
|
|
|
case 4:
|
2017-03-26 13:39:09 +00:00
|
|
|
|
switch ((GameVersion)pkm.Version)
|
|
|
|
|
{
|
|
|
|
|
case GameVersion.D:
|
|
|
|
|
case GameVersion.P:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.DP };
|
|
|
|
|
break;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
case GameVersion.Pt:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.Pt };
|
|
|
|
|
break;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
case GameVersion.HG:
|
|
|
|
|
case GameVersion.SS:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.HGSS };
|
|
|
|
|
break;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
break;
|
|
|
|
|
case 5:
|
2017-03-26 13:39:09 +00:00
|
|
|
|
switch ((GameVersion)pkm.Version)
|
|
|
|
|
{
|
|
|
|
|
case GameVersion.B:
|
|
|
|
|
case GameVersion.W:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.BW };
|
|
|
|
|
break;
|
|
|
|
|
case GameVersion.Pt:
|
|
|
|
|
Games = new[] { GameVersion.Pt };
|
|
|
|
|
break;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
case GameVersion.B2:
|
|
|
|
|
case GameVersion.W2:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.B2W2 };
|
|
|
|
|
break;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
}
|
2017-03-25 17:24:56 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2017-03-26 17:17:30 +00:00
|
|
|
|
return Games;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
}
|
2017-04-01 16:45:13 +00:00
|
|
|
|
private CheckResult[] parseMovesIsEggPreRelearn(int[] Moves, int[] SpecialMoves, bool allowinherited)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
2017-03-27 02:10:31 +00:00
|
|
|
|
var ValidSpecialMoves = SpecialMoves.Where(m => m != 0).ToList();
|
2017-03-26 13:39:09 +00:00
|
|
|
|
// Some games can have different egg movepools. Have to check all situations.
|
2017-03-26 17:17:30 +00:00
|
|
|
|
GameVersion[] Games = getBaseMovesIsEggGames();
|
2017-03-26 13:39:09 +00:00
|
|
|
|
int splitctr = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species) ? 1 : 0;
|
2017-03-26 17:17:30 +00:00
|
|
|
|
foreach (var ver in Games)
|
2017-03-25 17:24:56 +00:00
|
|
|
|
{
|
2017-03-26 17:17:30 +00:00
|
|
|
|
for (int i = 0; i <= splitctr; i++)
|
2017-03-26 16:29:50 +00:00
|
|
|
|
{
|
2017-04-04 02:59:29 +00:00
|
|
|
|
var baseSpecies = Legal.getBaseSpecies(pkm, i);
|
|
|
|
|
if (baseSpecies != pkm.Species)
|
|
|
|
|
continue;
|
|
|
|
|
|
2017-03-26 17:17:30 +00:00
|
|
|
|
var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List<int>();
|
2017-03-27 02:10:31 +00:00
|
|
|
|
var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, ver, 100)?.ToList() ?? new List<int>();
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
var EggMoves = Legal.getEggMoves(pkm, i, ver)?.ToList() ?? new List<int>();
|
2017-03-27 02:10:31 +00:00
|
|
|
|
var InheritedTutorMoves = ver == GameVersion.C ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2)?.ToList() : new List<int>();
|
2017-03-26 17:17:30 +00:00
|
|
|
|
// Only TM Hm moves from the source game of the egg, not any other games from the same generation
|
2017-03-27 02:10:31 +00:00
|
|
|
|
var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, ver, false)?.ToList();
|
|
|
|
|
InheritedLvlMoves.RemoveAll(x => baseEggMoves.Contains(x));
|
2017-03-26 17:17:30 +00:00
|
|
|
|
|
|
|
|
|
if (pkm.Format > 2 || SpecialMoves.Any())
|
|
|
|
|
{
|
|
|
|
|
// For gen 2 is not possible to difference normal eggs from event eggs
|
|
|
|
|
// If there is no special moves assume normal egg
|
|
|
|
|
res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, ver);
|
|
|
|
|
if (res.All(r => r.Valid)) // moves is satisfactory
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2017-03-27 02:10:31 +00:00
|
|
|
|
if (pkm.Format != 2)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// For gen 2 if does not match special egg check for normal egg too
|
|
|
|
|
res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List<int>(), true, ver);
|
|
|
|
|
if (res.All(r => r.Valid)) // moves are satisfactory
|
|
|
|
|
return res;
|
2017-03-25 17:24:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2017-04-01 16:45:13 +00:00
|
|
|
|
private CheckResult[] parseMovesWasEggPreRelearn(int[] Moves, List<int>[] validLevelMoves, List<int>[] validTMHM, List<int>[] validTutor)
|
2017-03-26 15:20:55 +00:00
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
|
|
|
|
|
2017-04-01 16:45:13 +00:00
|
|
|
|
// Gen 3 could have an egg origin and a non-egg origin, check first non-egg origin
|
2017-03-31 07:04:29 +00:00
|
|
|
|
if (pkm.GenNumber == 3 && !pkm.HasOriginalMetLocation && EncounterMatch !=null)
|
2017-03-26 22:11:09 +00:00
|
|
|
|
{
|
2017-04-04 02:59:29 +00:00
|
|
|
|
res = EncounterStaticMatch?.Count > 1
|
|
|
|
|
? parseMovesStaticEncounters(Moves, validLevelMoves, validTMHM, validTutor)
|
|
|
|
|
: EventGiftMatch?.Count > 1
|
2017-03-31 07:04:29 +00:00
|
|
|
|
? parseMovesGetGift(Moves, validLevelMoves, validTMHM, validTutor) // Multiple possible Mystery Gifts matched, get the best match too
|
2017-04-01 16:45:13 +00:00
|
|
|
|
: parseMovesPreRelearnEncounter(Moves, validLevelMoves, validTMHM, validTutor, GameVersion.Any); // Everything else, non-egg encounters only
|
2017-03-31 07:04:29 +00:00
|
|
|
|
if (res.All(r => r.Valid)) // moves are satisfactory
|
2017-03-26 22:11:09 +00:00
|
|
|
|
return res;
|
2017-04-01 16:45:13 +00:00
|
|
|
|
// If non-egg encounter is not valid check egg-encounter with eggmoves and without special moves
|
2017-03-26 22:11:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-26 15:20:55 +00:00
|
|
|
|
// Some games can have different egg movepools. Have to check all situations.
|
|
|
|
|
GameVersion[] Games = { };
|
|
|
|
|
switch (pkm.GenNumber)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
case 2:
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = new[] { GameVersion.GS, GameVersion.C };
|
2017-03-26 15:20:55 +00:00
|
|
|
|
break;
|
|
|
|
|
case 3: // Generation 3 does not overwrite source game after pokemon hatched
|
2017-03-26 17:17:30 +00:00
|
|
|
|
Games = getBaseMovesIsEggGames();
|
2017-03-26 15:20:55 +00:00
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
Games = new[] { GameVersion.DP, GameVersion.Pt, GameVersion.HGSS };
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
Games = new[] { GameVersion.BW, GameVersion.B2W2 };
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
int splitctr = Legal.SplitBreed.Contains(pkm.Species) ? 1 : 0;
|
|
|
|
|
foreach (var ver in Games)
|
|
|
|
|
{
|
2017-04-04 02:59:29 +00:00
|
|
|
|
var EventEggMoves = pkm.WasEgg && !pkm.WasGiftEgg? Legal.getSpecialEggMoves(pkm, ver).ToArray() : new int[0];
|
2017-03-26 15:20:55 +00:00
|
|
|
|
for (int i = 0; i <= splitctr; i++)
|
|
|
|
|
{
|
|
|
|
|
var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, 100)?.ToArray() ?? new int[0];
|
2017-04-01 16:45:13 +00:00
|
|
|
|
var EggMoves = pkm.WasEgg && !pkm.WasGiftEgg ? Legal.getEggMoves(pkm, i, ver).ToArray() : new int[0];
|
|
|
|
|
|
|
|
|
|
res = parseMoves(Moves, validLevelMoves, new int[0], validTMHM, validTutor, new int[0], baseEggMoves, EggMoves, EventEggMoves);
|
|
|
|
|
|
2017-03-26 15:20:55 +00:00
|
|
|
|
if (res.All(r => r.Valid)) // moves is satisfactory
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2017-04-01 16:45:13 +00:00
|
|
|
|
private CheckResult[] parseMovesIsEggPreRelearnEvent(int[] Moves)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
|
|
|
|
foreach (MysteryGift mg in EventGiftMatch)
|
|
|
|
|
{
|
|
|
|
|
int[] SpecialMoves = mg.Moves;
|
2017-04-01 16:45:13 +00:00
|
|
|
|
CheckResult[] res = parseMovesIsEggPreRelearn(Moves, SpecialMoves, false);
|
2017-03-26 13:39:09 +00:00
|
|
|
|
if (res.Any(r => !r.Valid))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Match Found
|
|
|
|
|
EncounterMatch = mg;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
// no Mystery Gifts matched
|
2017-04-01 16:45:13 +00:00
|
|
|
|
return parseMovesIsEggPreRelearn(Moves, new int[0], false);
|
2017-03-26 13:39:09 +00:00
|
|
|
|
}
|
2017-03-23 06:34:35 +00:00
|
|
|
|
private CheckResult[] parseMovesSketch(int[] Moves)
|
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
res[i] = Legal.InvalidSketch.Contains(Moves[i])
|
|
|
|
|
? new CheckResult(Severity.Invalid, V166, CheckIdentifier.Move)
|
|
|
|
|
: new CheckResult(CheckIdentifier.Move);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2017-04-04 02:59:29 +00:00
|
|
|
|
private CheckResult[] parseMoves3DS(GameVersion game, List<int>[] validLevelMoves, List<int>[] validTMHM, List<int>[] validTutor, int[] Moves)
|
|
|
|
|
{
|
|
|
|
|
if (EventGiftMatch?.Count > 1) // Multiple possible Mystery Gifts matched, get the best match too
|
|
|
|
|
return parseMovesGetGift(Moves, validLevelMoves, validTMHM, validTutor);
|
|
|
|
|
else if (EncounterStaticMatch?.Count > 1) // Multiple possible Static Encounters matched, get the best match too
|
|
|
|
|
return parseMovesStaticEncounters(Moves, validLevelMoves, validTMHM, validTutor);
|
|
|
|
|
else if (pkm.WasEgg && Legal.SplitBreed.Contains(pkm.Species))
|
|
|
|
|
return parseMovesRelearnSplitBreed(Moves, validLevelMoves, validTMHM, validTutor, game);
|
|
|
|
|
else // Everything else
|
|
|
|
|
return parseMovesRelearn(Moves, validLevelMoves, validTMHM, validTutor, 0, game);
|
|
|
|
|
}
|
2017-04-01 18:32:59 +00:00
|
|
|
|
private CheckResult[] parseMovesPre3DS(GameVersion game, List<int>[] validLevelMoves, List<int>[] validTMHM, List<int>[] validTutor, int[] Moves)
|
|
|
|
|
{
|
|
|
|
|
if (pkm.IsEgg)
|
|
|
|
|
{
|
|
|
|
|
if (EventGiftMatch?.Count > 0)
|
|
|
|
|
return parseMovesIsEggPreRelearnEvent(Moves);
|
|
|
|
|
|
|
|
|
|
int[] SpecialMoves = (EncounterMatch as MysteryGift)?.Moves ??
|
2017-04-04 02:59:29 +00:00
|
|
|
|
(EncounterMatch as List<EncounterStatic>)?.First().Moves ??
|
|
|
|
|
(EncounterMatch as EncounterTrade)?.Moves;
|
2017-04-01 18:32:59 +00:00
|
|
|
|
var allowinherited = SpecialMoves == null && !pkm.WasGiftEgg && !pkm.WasEventEgg;
|
|
|
|
|
return parseMovesIsEggPreRelearn(Moves, SpecialMoves ?? new int[0], allowinherited);
|
|
|
|
|
}
|
|
|
|
|
if (pkm.WasEgg)
|
|
|
|
|
return parseMovesWasEggPreRelearn(Moves, validLevelMoves, validTMHM, validTutor);
|
|
|
|
|
|
|
|
|
|
if (EventGiftMatch?.Count > 1)
|
|
|
|
|
// Multiple possible non-egg Mystery Gifts matched, get the best match too
|
|
|
|
|
return parseMovesGetGift(Moves, validLevelMoves, validTMHM, validTutor);
|
2017-04-04 02:59:29 +00:00
|
|
|
|
if (EncounterStaticMatch?.Count > 1)
|
|
|
|
|
// Multiple possible Static Encounters matched, get the best match too
|
|
|
|
|
return parseMovesStaticEncounters(Moves, validLevelMoves, validTMHM, validTutor);
|
2017-04-01 18:32:59 +00:00
|
|
|
|
|
|
|
|
|
return parseMovesPreRelearnEncounter(Moves, validLevelMoves, validTMHM, validTutor, game);
|
|
|
|
|
}
|
2017-03-25 20:53:33 +00:00
|
|
|
|
private CheckResult[] parseMovesGetGift(int[] Moves, List<int>[] validLevelMoves, List<int>[] validTMHM, List<int>[] validTutor)
|
2017-03-23 06:34:35 +00:00
|
|
|
|
{
|
2017-04-04 02:59:29 +00:00
|
|
|
|
int[] RelearnMoves = pkm.GenNumber < 6 ? new int[0] : pkm.RelearnMoves;
|
2017-03-23 06:34:35 +00:00
|
|
|
|
foreach (MysteryGift mg in EventGiftMatch)
|
2016-04-16 18:35:16 +00:00
|
|
|
|
{
|
2017-03-23 06:34:35 +00:00
|
|
|
|
int[] SpecialMoves = mg.Moves;
|
2017-03-26 15:20:55 +00:00
|
|
|
|
CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, new int[0], new int[0], new int[0]);
|
2017-03-23 06:34:35 +00:00
|
|
|
|
if (res.Any(r => !r.Valid))
|
|
|
|
|
continue;
|
2016-07-04 23:06:07 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
// Match Found
|
|
|
|
|
EncounterMatch = mg;
|
2017-04-04 02:59:29 +00:00
|
|
|
|
if(pkm.GenNumber >= 6)
|
|
|
|
|
RelearnBase = mg.RelearnMoves;
|
2017-03-23 06:34:35 +00:00
|
|
|
|
return res;
|
2016-04-16 18:35:16 +00:00
|
|
|
|
}
|
2017-02-14 06:49:32 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
// no Mystery Gifts matched
|
2017-03-26 15:20:55 +00:00
|
|
|
|
return parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, new int[0], new int[0], new int[0], new int[0]);
|
2017-03-23 06:34:35 +00:00
|
|
|
|
}
|
2017-04-04 02:59:29 +00:00
|
|
|
|
private CheckResult[] parseMovesStaticEncounters(int[] Moves, List<int>[] validLevelMoves, List<int>[] validTMHM, List<int>[] validTutor)
|
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = null;
|
|
|
|
|
foreach (EncounterStatic stenc in EncounterStaticMatch)
|
|
|
|
|
{
|
|
|
|
|
int[] SpecialMoves = stenc.Moves;
|
|
|
|
|
res = parseMoves(Moves, validLevelMoves, new int[0], validTMHM, validTutor, SpecialMoves, new int[0], new int[0], new int[0]);
|
|
|
|
|
if (res.Any(r => !r.Valid))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Match Found
|
|
|
|
|
EncounterMatch = stenc;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2017-04-01 16:45:13 +00:00
|
|
|
|
private CheckResult[] parseMovesPreRelearnEncounter(int[] Moves, List<int>[] validLevelMoves, List<int>[] validTMHM, List<int>[] validTutor, GameVersion game)
|
2017-03-23 06:34:35 +00:00
|
|
|
|
{
|
|
|
|
|
int[] SpecialMoves = (EncounterMatch as MysteryGift)?.Moves ??
|
2017-04-04 02:59:29 +00:00
|
|
|
|
(EncounterMatch as List<EncounterStatic>)?.First().Moves ??
|
2017-03-23 06:34:35 +00:00
|
|
|
|
(EncounterMatch as EncounterTrade)?.Moves ??
|
|
|
|
|
new int[0];
|
2017-03-18 23:17:42 +00:00
|
|
|
|
|
2017-04-01 18:32:59 +00:00
|
|
|
|
return parseMoves(Moves, validLevelMoves, new int[0], validTMHM, validTutor, SpecialMoves, new int[0], new int[0], new int[0]);
|
2017-04-01 16:45:13 +00:00
|
|
|
|
}
|
|
|
|
|
private CheckResult[] parseMovesRelearnSplitBreed(int[] Moves, List<int>[] validLevelMoves, List<int>[] validTMHM, List<int>[] validTutor, GameVersion game)
|
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
|
|
|
|
int splitctr = Legal.SplitBreed.Contains(pkm.Species) ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i <= splitctr; i++)
|
|
|
|
|
{
|
|
|
|
|
res = parseMovesRelearn(Moves, validLevelMoves, validTMHM, validTutor, i, game);
|
2017-04-01 18:32:59 +00:00
|
|
|
|
if (res.All(r => r.Valid)) // moves are satisfactory
|
|
|
|
|
break;
|
2017-04-01 16:45:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
private CheckResult[] parseMovesRelearn(int[] Moves, List<int>[] validLevelMoves, List<int>[] validTMHM, List<int>[] validTutor, int SkipOption, GameVersion game)
|
|
|
|
|
{
|
2017-04-04 02:59:29 +00:00
|
|
|
|
int[] EggMoves = pkm.WasEgg && !pkm.WasGiftEgg && !pkm.WasEventEgg? Legal.getEggMoves(pkm, SkipOption, game).ToArray() : new int[0];
|
2017-04-01 16:45:13 +00:00
|
|
|
|
int[] RelearnMoves = pkm.RelearnMoves;
|
|
|
|
|
int[] SpecialMoves = (EncounterMatch as MysteryGift)?.Moves ??
|
2017-04-04 02:59:29 +00:00
|
|
|
|
(EncounterMatch as List<EncounterStatic>)?.First().Moves ??
|
2017-04-01 16:45:13 +00:00
|
|
|
|
(EncounterMatch as EncounterTrade)?.Moves ??
|
|
|
|
|
new int[0];
|
|
|
|
|
|
2017-04-04 02:59:29 +00:00
|
|
|
|
CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, new int[0], EggMoves, new int[0]);
|
2016-03-15 06:54:13 +00:00
|
|
|
|
|
2016-03-15 06:26:51 +00:00
|
|
|
|
for (int i = 0; i < 4; i++)
|
2017-04-01 16:45:13 +00:00
|
|
|
|
if ((pkm.IsEgg || res[i].Flag) && !RelearnMoves.Contains(Moves[i]))
|
2017-03-23 06:34:35 +00:00
|
|
|
|
res[i] = new CheckResult(Severity.Invalid, string.Format(V170, res[i].Comment), res[i].Identifier);
|
2016-03-15 06:26:51 +00:00
|
|
|
|
|
2016-03-12 17:16:41 +00:00
|
|
|
|
return res;
|
|
|
|
|
}
|
2017-03-26 15:20:55 +00:00
|
|
|
|
private CheckResult[] parseMoves(int[] moves, List<int>[] learn, int[] relearn, List<int>[] tmhm, List<int>[] tutor, int[] special, int[] baseegg, int[] egg, int[] eventegg)
|
2017-02-13 07:08:39 +00:00
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
2017-03-25 15:41:45 +00:00
|
|
|
|
var Gen1MovesLearned = new List<int>();
|
|
|
|
|
var EggMovesLearned = new List<int>();
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
var BaseEggMovesLearned = new List<int>();
|
2017-03-25 15:41:45 +00:00
|
|
|
|
var EventEggMovesLearned = new List<int>();
|
2017-03-25 17:19:38 +00:00
|
|
|
|
var IsGen2Pkm = pkm.Format == 2 || pkm.VC2;
|
2017-03-25 15:41:45 +00:00
|
|
|
|
// Check none moves and relearn moves before generation moves
|
|
|
|
|
for (int m = 0; m < 4; m++)
|
2017-02-13 07:08:39 +00:00
|
|
|
|
{
|
2017-03-25 15:41:45 +00:00
|
|
|
|
if (moves[m] == 0)
|
|
|
|
|
res[m] = new CheckResult(Severity.Valid, V167, CheckIdentifier.Move);
|
|
|
|
|
else if (relearn.Contains(moves[m]))
|
|
|
|
|
res[m] = new CheckResult(Severity.Valid, V172, CheckIdentifier.Move) { Flag = true };
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-25 17:19:38 +00:00
|
|
|
|
if (res.All(r => r != null))
|
2017-03-25 15:41:45 +00:00
|
|
|
|
return res;
|
|
|
|
|
|
2017-03-25 20:53:33 +00:00
|
|
|
|
bool MixedGen1NonTradebackGen2 = false;
|
2017-03-25 15:41:45 +00:00
|
|
|
|
// Check moves going backwards, marking the move valid in the most current generation when it can be learned
|
|
|
|
|
int[] generations = getGenMovesCheckOrder(pkm);
|
2017-03-25 20:53:33 +00:00
|
|
|
|
foreach (var gen in generations)
|
2017-03-25 15:41:45 +00:00
|
|
|
|
{
|
|
|
|
|
if (!pkm.InhabitedGeneration(gen))
|
|
|
|
|
continue;
|
|
|
|
|
|
2017-03-25 17:19:38 +00:00
|
|
|
|
var HMLearned = new int[0];
|
2017-03-25 15:41:45 +00:00
|
|
|
|
// Check if pokemon knows HM moves from generation 3 and 4 but are not valid yet, that means it cant learn the HMs in future generations
|
|
|
|
|
bool KnowDefogWhirlpool = false;
|
|
|
|
|
if (gen == 4 && pkm.Format > 4)
|
|
|
|
|
{
|
2017-03-25 17:19:38 +00:00
|
|
|
|
// Copy to array the hm found or else the list will be emptied when the legal status of moves changes in the current generation
|
|
|
|
|
HMLearned = moves.Where((m,i) => !(res[i]?.Valid ?? false) && Legal.HM_4_RemovePokeTransfer.Any(l => l == m)).Select((m, i) => i).ToArray();
|
2017-03-25 15:41:45 +00:00
|
|
|
|
// Defog and Whirlpool at the same time, also both can't be learned in future generations or else they will be valid
|
2017-03-25 17:19:38 +00:00
|
|
|
|
KnowDefogWhirlpool = moves.Where((m, i) => (m == 250 || m == 432) && !(res[i]?.Valid ?? false)).Count() == 2;
|
2017-03-25 15:41:45 +00:00
|
|
|
|
}
|
|
|
|
|
else if (gen == 3 && pkm.Format > 3)
|
2017-03-25 17:19:38 +00:00
|
|
|
|
HMLearned = moves.Select((m, i) => i).Where(i => !(res[i]?.Valid ?? false) && Legal.HM_3.Any(l => l == moves[i])).ToArray();
|
2017-03-25 15:41:45 +00:00
|
|
|
|
|
2017-03-25 20:53:33 +00:00
|
|
|
|
bool native = gen == pkm.Format;
|
2017-03-25 15:41:45 +00:00
|
|
|
|
for (int m = 0; m < 4; m++)
|
|
|
|
|
{
|
|
|
|
|
if (res[m]?.Valid ?? false)
|
|
|
|
|
continue;
|
|
|
|
|
|
2017-03-25 17:19:38 +00:00
|
|
|
|
if (learn[gen].Contains(moves[m]))
|
2017-03-25 20:53:33 +00:00
|
|
|
|
res[m] = new CheckResult(Severity.Valid, native ? V177 : string.Format(V330, gen), CheckIdentifier.Move);
|
2017-03-25 17:19:38 +00:00
|
|
|
|
else if (tmhm[gen].Contains(moves[m]))
|
2017-03-25 20:53:33 +00:00
|
|
|
|
res[m] = new CheckResult(Severity.Valid, native ? V173 : string.Format(V331, gen), CheckIdentifier.Move);
|
2017-03-25 17:19:38 +00:00
|
|
|
|
else if (tutor[gen].Contains(moves[m]))
|
2017-03-25 20:53:33 +00:00
|
|
|
|
res[m] = new CheckResult(Severity.Valid, native ? V173 : string.Format(V332, gen), CheckIdentifier.Move);
|
2017-03-25 15:41:45 +00:00
|
|
|
|
else if (gen == pkm.GenNumber && special.Contains(moves[m]))
|
|
|
|
|
res[m] = new CheckResult(Severity.Valid, V175, CheckIdentifier.Move);
|
2017-03-25 20:53:33 +00:00
|
|
|
|
|
|
|
|
|
if (res[m] == null)
|
|
|
|
|
continue;
|
|
|
|
|
if (res[m].Valid && gen == 1)
|
|
|
|
|
Gen1MovesLearned.Add(m);
|
2017-03-25 15:41:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-25 18:02:33 +00:00
|
|
|
|
if (gen == generations.Last())
|
2017-03-25 15:41:45 +00:00
|
|
|
|
{
|
2017-03-26 15:20:55 +00:00
|
|
|
|
// Check base egg moves after all the moves but just before egg moves to different it from normal level up moves
|
|
|
|
|
// Also check if the base egg moves is a non tradeback move
|
|
|
|
|
for (int m = 0; m < 4; m++)
|
|
|
|
|
{
|
2017-04-01 01:35:43 +00:00
|
|
|
|
if (!baseegg.Contains(moves[m]))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (IsGen2Pkm && Gen1MovesLearned.Any() && moves[m] > Legal.MaxMoveID_1)
|
2017-03-26 15:20:55 +00:00
|
|
|
|
{
|
2017-04-01 01:35:43 +00:00
|
|
|
|
res[m] = new CheckResult(Severity.Invalid, V334, CheckIdentifier.Move);
|
|
|
|
|
MixedGen1NonTradebackGen2 = true;
|
2017-03-26 15:20:55 +00:00
|
|
|
|
}
|
2017-04-01 01:35:43 +00:00
|
|
|
|
else
|
|
|
|
|
res[m] = new CheckResult(Severity.Valid, V345, CheckIdentifier.Move);
|
|
|
|
|
BaseEggMovesLearned.Add(m);
|
2017-03-26 15:20:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
// Check egg moves after all the generations and all the moves, every move that can't be learned in another source should have preference
|
2017-03-25 15:41:45 +00:00
|
|
|
|
// the moves that can only be learned from egg moves should in the future check if the move combinations can be breed in gens 2 to 5
|
|
|
|
|
for (int m = 0; m < 4; m++)
|
|
|
|
|
{
|
|
|
|
|
if (res[m]?.Valid ?? false)
|
|
|
|
|
continue;
|
|
|
|
|
if (egg.Contains(moves[m]))
|
|
|
|
|
{
|
2017-03-25 17:19:38 +00:00
|
|
|
|
if (IsGen2Pkm && Gen1MovesLearned.Any() && moves[m] > Legal.MaxMoveID_1)
|
2017-03-25 15:41:45 +00:00
|
|
|
|
{
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
// To learn exclusive generation 1 moves the pokemon was tradeback, but it can't be trade to generation 1
|
2017-03-25 15:41:45 +00:00
|
|
|
|
// without removing moves above MaxMoveID_1, egg moves above MaxMoveID_1 and gen 1 moves are incompatible
|
|
|
|
|
res[m] = new CheckResult(Severity.Invalid, V334, CheckIdentifier.Move) { Flag = true };
|
|
|
|
|
MixedGen1NonTradebackGen2 = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
res[m] = new CheckResult(Severity.Valid, V171, CheckIdentifier.Move) { Flag = true };
|
|
|
|
|
EggMovesLearned.Add(m);
|
|
|
|
|
}
|
2017-03-25 20:53:33 +00:00
|
|
|
|
if (!eventegg.Contains(moves[m]))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (!egg.Contains(moves[m]))
|
2017-03-25 15:41:45 +00:00
|
|
|
|
{
|
2017-03-25 20:53:33 +00:00
|
|
|
|
if (IsGen2Pkm && Gen1MovesLearned.Any() && moves[m] > Legal.MaxMoveID_1)
|
2017-03-25 15:41:45 +00:00
|
|
|
|
{
|
2017-03-25 20:53:33 +00:00
|
|
|
|
res[m] = new CheckResult(Severity.Invalid, V334, CheckIdentifier.Move) { Flag = true };
|
|
|
|
|
MixedGen1NonTradebackGen2 = true;
|
2017-03-25 15:41:45 +00:00
|
|
|
|
}
|
2017-03-25 20:53:33 +00:00
|
|
|
|
else
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
res[m] = new CheckResult(Severity.Valid, V333, CheckIdentifier.Move) { Flag = true };
|
2017-03-25 15:41:45 +00:00
|
|
|
|
}
|
2017-03-25 20:53:33 +00:00
|
|
|
|
EventEggMovesLearned.Add(m);
|
2017-03-25 15:41:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-25 17:19:38 +00:00
|
|
|
|
// A pokemon could have normal egg moves and regular egg moves
|
|
|
|
|
// Only if all regular egg moves are event egg moves or all event egg moves are regular egg moves
|
2017-04-01 01:35:43 +00:00
|
|
|
|
var RegularEggMovesLearned = EggMovesLearned.Union(BaseEggMovesLearned).ToList();
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
if (RegularEggMovesLearned.Any() && EventEggMovesLearned.Any())
|
2017-03-25 15:41:45 +00:00
|
|
|
|
{
|
2017-03-25 17:19:38 +00:00
|
|
|
|
// Moves that are egg moves or event egg moves but not both
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
var IncompatibleEggMoves = RegularEggMovesLearned.Except(EventEggMovesLearned).Union(EventEggMovesLearned.Except(RegularEggMovesLearned)).ToList();
|
2017-03-25 17:19:38 +00:00
|
|
|
|
if (IncompatibleEggMoves.Any())
|
2017-03-25 15:41:45 +00:00
|
|
|
|
{
|
2017-03-25 17:19:38 +00:00
|
|
|
|
foreach(int m in IncompatibleEggMoves)
|
|
|
|
|
{
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
if (EventEggMovesLearned.Contains(m) && !EggMovesLearned.Contains(m))
|
2017-03-25 17:19:38 +00:00
|
|
|
|
res[m] = new CheckResult(Severity.Invalid, V337, CheckIdentifier.Move);
|
|
|
|
|
else if (!EventEggMovesLearned.Contains(m) && EggMovesLearned.Contains(m))
|
|
|
|
|
res[m] = new CheckResult(Severity.Invalid, V336, CheckIdentifier.Move);
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
else if (!EventEggMovesLearned.Contains(m) && BaseEggMovesLearned.Contains(m))
|
|
|
|
|
res[m] = new CheckResult(Severity.Invalid, V358, CheckIdentifier.Move);
|
2017-03-25 17:19:38 +00:00
|
|
|
|
}
|
2017-03-25 15:41:45 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-25 17:19:38 +00:00
|
|
|
|
if (3 <= gen && gen <= 4 && pkm.Format > gen)
|
2017-03-25 15:41:45 +00:00
|
|
|
|
{
|
|
|
|
|
// After all the moves from the generations 3 and 4,
|
|
|
|
|
// including egg moves if is the origin generation because some hidden moves are also special egg moves in gen 3
|
|
|
|
|
// Check if the marked hidden moves that were invalid at the start are now marked as valid, that means
|
|
|
|
|
// the hidden move was learned in gen 3 or 4 but was not removed when transfer to 4 or 5
|
|
|
|
|
if (KnowDefogWhirlpool)
|
2017-04-01 01:35:43 +00:00
|
|
|
|
{
|
|
|
|
|
int invalidCount = moves.Where((m, i) => (m == 250 || m == 432) && (res[i]?.Valid ?? false)).Count();
|
|
|
|
|
if (invalidCount == 2) // can't know both at the same time
|
|
|
|
|
for (int i = 0; i < 4; i++) // flag both moves
|
|
|
|
|
if (moves[i] == 250 || moves[i] == 432)
|
|
|
|
|
res[i] = new CheckResult(Severity.Invalid, V338, CheckIdentifier.Move);
|
|
|
|
|
}
|
2017-03-25 15:41:45 +00:00
|
|
|
|
|
2017-04-01 01:35:43 +00:00
|
|
|
|
for (int i = 0; i < HMLearned.Length; i++)
|
|
|
|
|
if (res[i]?.Valid ?? false)
|
|
|
|
|
res[i] = new CheckResult(Severity.Invalid, string.Format(V339, gen, gen + 1), CheckIdentifier.Move);
|
2017-03-25 15:41:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mark the gen 1 exclusive moves as illegal because the pokemon also have Non tradeback egg moves.
|
|
|
|
|
if (MixedGen1NonTradebackGen2)
|
|
|
|
|
foreach (int m in Gen1MovesLearned)
|
|
|
|
|
res[m] = new CheckResult(Severity.Invalid, V335, CheckIdentifier.Move);
|
|
|
|
|
|
2017-03-25 17:19:38 +00:00
|
|
|
|
if (res.All(r => r != null))
|
2017-03-25 15:41:45 +00:00
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
if (pkm.Species == 292)
|
|
|
|
|
{
|
|
|
|
|
// Check Shedinja evolved moves from Ninjask after egg moves
|
|
|
|
|
// Those moves could also be inherited egg moves
|
|
|
|
|
ParseShedinjaEvolveMoves(moves, ref res);
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-25 15:41:45 +00:00
|
|
|
|
for (int m = 0; m < 4; m++)
|
|
|
|
|
{
|
|
|
|
|
if (res[m] == null)
|
|
|
|
|
res[m] = new CheckResult(Severity.Invalid, V176, CheckIdentifier.Move);
|
2017-02-13 07:08:39 +00:00
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
private void ParseShedinjaEvolveMoves(int[] moves, ref CheckResult[] res)
|
|
|
|
|
{
|
|
|
|
|
List<int>[] ShedinjaEvoMoves = Legal.getShedinjaEvolveMoves(pkm);
|
|
|
|
|
var ShedinjaEvoMovesLearned = new List<int>();
|
|
|
|
|
for (int gen = 4; gen >= 3; gen--)
|
|
|
|
|
{
|
|
|
|
|
bool native = gen == pkm.Format;
|
|
|
|
|
for (int m = 0; m < 4; m++)
|
|
|
|
|
{
|
|
|
|
|
if (res[m]?.Valid ?? false)
|
|
|
|
|
continue;
|
|
|
|
|
|
2017-04-01 01:35:43 +00:00
|
|
|
|
if (!ShedinjaEvoMoves[gen].Contains(moves[m]))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
res[m] = new CheckResult(Severity.Valid, native ? V355 : string.Format(V356, gen), CheckIdentifier.Move);
|
|
|
|
|
ShedinjaEvoMovesLearned.Add(m);
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-01 01:35:43 +00:00
|
|
|
|
if (ShedinjaEvoMovesLearned.Count <= 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
foreach (int m in ShedinjaEvoMovesLearned)
|
|
|
|
|
res[m] = new CheckResult(Severity.Invalid, V357, CheckIdentifier.Move);
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-25 17:24:56 +00:00
|
|
|
|
private void verifyPreRelearn()
|
|
|
|
|
{
|
|
|
|
|
// For origins prior to relearn moves, need to try to match a mystery gift if applicable.
|
|
|
|
|
|
|
|
|
|
if (pkm.WasEvent || pkm.WasEventEgg)
|
|
|
|
|
{
|
|
|
|
|
EventGiftMatch = new List<MysteryGift>(Legal.getValidGifts(pkm));
|
|
|
|
|
EncounterMatch = EventGiftMatch.FirstOrDefault();
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-23 19:48:49 +00:00
|
|
|
|
private CheckResult[] verifyRelearn()
|
2016-03-12 17:16:41 +00:00
|
|
|
|
{
|
2016-03-29 05:30:23 +00:00
|
|
|
|
RelearnBase = null;
|
2017-03-23 06:34:35 +00:00
|
|
|
|
|
2017-01-27 05:35:26 +00:00
|
|
|
|
if (pkm.GenNumber < 6 || pkm.VC1)
|
2017-03-23 06:34:35 +00:00
|
|
|
|
return verifyRelearnNone();
|
2016-10-24 05:03:19 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.WasLink)
|
2017-03-23 06:34:35 +00:00
|
|
|
|
return verifyRelearnLink();
|
|
|
|
|
|
|
|
|
|
if (pkm.WasEvent || pkm.WasEventEgg)
|
|
|
|
|
return verifyRelearnMysteryGift();
|
2016-03-23 02:47:13 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
if (pkm.WasEgg && !Legal.NoHatchFromEgg.Contains(pkm.Species))
|
|
|
|
|
return verifyRelearnEgg();
|
|
|
|
|
|
|
|
|
|
if (pkm.RelearnMove1 != 0 && Legal.getDexNavValid(pkm))
|
|
|
|
|
return verifyRelearnDexNav();
|
|
|
|
|
|
|
|
|
|
return verifyRelearnNone();
|
|
|
|
|
}
|
|
|
|
|
private CheckResult[] verifyRelearnMysteryGift()
|
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
|
|
|
|
int[] RelearnMoves = pkm.RelearnMoves;
|
|
|
|
|
// Get gifts that match
|
|
|
|
|
|
|
|
|
|
EventGiftMatch = new List<MysteryGift>(Legal.getValidGifts(pkm));
|
|
|
|
|
foreach (MysteryGift mg in EventGiftMatch.ToArray())
|
|
|
|
|
{
|
|
|
|
|
int[] moves = mg.RelearnMoves;
|
2016-03-12 17:16:41 +00:00
|
|
|
|
for (int i = 0; i < 4; i++)
|
2017-03-23 06:34:35 +00:00
|
|
|
|
res[i] = moves[i] != RelearnMoves[i]
|
2017-03-21 07:18:38 +00:00
|
|
|
|
? new CheckResult(Severity.Invalid, string.Format(V178, movelist[moves[i]]), CheckIdentifier.RelearnMove)
|
2016-10-23 19:48:49 +00:00
|
|
|
|
: new CheckResult(CheckIdentifier.RelearnMove);
|
2017-03-23 06:34:35 +00:00
|
|
|
|
if (res.Any(r => !r.Valid))
|
|
|
|
|
EventGiftMatch.Remove(mg);
|
2016-03-12 17:16:41 +00:00
|
|
|
|
}
|
2017-03-23 06:34:35 +00:00
|
|
|
|
if (EventGiftMatch.Count > 1)
|
|
|
|
|
return res;
|
|
|
|
|
|
|
|
|
|
if (EventGiftMatch.Count == 1)
|
2016-03-12 17:16:41 +00:00
|
|
|
|
{
|
2017-03-23 06:34:35 +00:00
|
|
|
|
EncounterMatch = EventGiftMatch[0];
|
|
|
|
|
RelearnBase = EventGiftMatch[0].RelearnMoves;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// No gift match, thus no relearn moves
|
|
|
|
|
EncounterMatch = EncounterType = null;
|
|
|
|
|
return verifyRelearnNone();
|
|
|
|
|
}
|
|
|
|
|
private CheckResult[] verifyRelearnDexNav()
|
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
|
|
|
|
int[] RelearnMoves = pkm.RelearnMoves;
|
2016-04-16 18:35:16 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
// DexNav Pokémon can have 1 random egg move as a relearn move.
|
|
|
|
|
res[0] = !Legal.getValidRelearn(pkm, 0).Contains(RelearnMoves[0])
|
|
|
|
|
? new CheckResult(Severity.Invalid, V183, CheckIdentifier.RelearnMove)
|
|
|
|
|
: new CheckResult(CheckIdentifier.RelearnMove);
|
|
|
|
|
|
|
|
|
|
// All other relearn moves must be empty.
|
|
|
|
|
for (int i = 1; i < 4; i++)
|
|
|
|
|
res[i] = RelearnMoves[i] != 0
|
|
|
|
|
? new CheckResult(Severity.Invalid, V184, CheckIdentifier.RelearnMove)
|
|
|
|
|
: new CheckResult(CheckIdentifier.RelearnMove);
|
|
|
|
|
|
|
|
|
|
// Update the relearn base moves if the first relearn move is okay.
|
|
|
|
|
if (res[0].Valid)
|
|
|
|
|
RelearnBase = new[] { RelearnMoves[0], 0, 0, 0 };
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
private CheckResult[] verifyRelearnNone()
|
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
|
|
|
|
int[] RelearnMoves = pkm.RelearnMoves;
|
|
|
|
|
|
|
|
|
|
// No relearn moves should be present.
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
res[i] = RelearnMoves[i] != 0
|
|
|
|
|
? new CheckResult(Severity.Invalid, V184, CheckIdentifier.RelearnMove)
|
|
|
|
|
: new CheckResult(CheckIdentifier.RelearnMove);
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
private CheckResult[] verifyRelearnLink()
|
|
|
|
|
{
|
|
|
|
|
// The WasLink check indicated that it was from the Pokémon Link
|
|
|
|
|
var Link = Legal.getValidLinkGifts(pkm);
|
|
|
|
|
|
|
|
|
|
// But no encounter was able to be matched. Abort!
|
|
|
|
|
if (Link == null)
|
|
|
|
|
return verifyRelearnNone();
|
|
|
|
|
|
|
|
|
|
EncounterMatch = Link;
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
|
|
|
|
int[] RelearnMoves = pkm.RelearnMoves;
|
|
|
|
|
int[] LinkRelearn = ((EncounterLink)EncounterMatch).RelearnMoves;
|
|
|
|
|
|
|
|
|
|
// Pokémon Link encounters should have their relearn moves match exactly.
|
|
|
|
|
RelearnBase = LinkRelearn;
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
res[i] = LinkRelearn[i] != RelearnMoves[i]
|
|
|
|
|
? new CheckResult(Severity.Invalid, string.Format(V178, movelist[LinkRelearn[i]]), CheckIdentifier.RelearnMove)
|
|
|
|
|
: new CheckResult(CheckIdentifier.RelearnMove);
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
private CheckResult[] verifyRelearnEgg()
|
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
|
|
|
|
int[] RelearnMoves = pkm.RelearnMoves;
|
|
|
|
|
|
|
|
|
|
// Some games can have different egg movepools. Have to check all situations.
|
|
|
|
|
GameVersion[] Games = { };
|
|
|
|
|
switch (pkm.GenNumber)
|
|
|
|
|
{
|
|
|
|
|
case 6:
|
|
|
|
|
Games = new[] { GameVersion.XY, GameVersion.ORAS };
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
Games = new[] { GameVersion.SM };
|
|
|
|
|
break;
|
2016-03-12 17:16:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
bool checkAllGames = pkm.WasTradedEgg;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
bool splitBreed = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species);
|
2017-03-23 06:34:35 +00:00
|
|
|
|
int iterate = (checkAllGames ? Games.Length : 1) * (splitBreed ? 2 : 1);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < iterate; i++)
|
2016-03-12 17:16:41 +00:00
|
|
|
|
{
|
2017-03-23 06:34:35 +00:00
|
|
|
|
// Obtain parameters for the Egg's Base Moves
|
|
|
|
|
int gameSource = !checkAllGames ? -1 : i % iterate / (splitBreed ? 2 : 1);
|
|
|
|
|
int skipOption = splitBreed && iterate / 2 <= i ? 1 : 0;
|
|
|
|
|
GameVersion ver = gameSource == -1 ? GameVersion.Any : Games[gameSource];
|
2016-10-24 05:03:19 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
// Generate & Analyze compatibility
|
|
|
|
|
res = verifyRelearnEggBase(RelearnMoves, skipOption, ver);
|
|
|
|
|
if (res.All(r => r.Valid)) // egg is satisfactory
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-03-12 17:16:41 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
verifyNoEmptyDuplicates(RelearnMoves, res);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
private CheckResult[] verifyRelearnEggBase(int[] RelearnMoves, int skipOption, GameVersion ver)
|
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
2016-03-12 17:16:41 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
// Obtain level1 moves
|
2017-03-25 17:24:56 +00:00
|
|
|
|
List<int> baseMoves = new List<int>(Legal.getBaseEggMoves(pkm, skipOption, ver, 1));
|
2017-03-23 06:34:35 +00:00
|
|
|
|
int baseCt = baseMoves.Count;
|
|
|
|
|
if (baseCt > 4) baseCt = 4;
|
|
|
|
|
|
|
|
|
|
// Obtain Inherited moves
|
|
|
|
|
var inheritMoves = Legal.getValidRelearn(pkm, skipOption).ToList();
|
|
|
|
|
var inherited = RelearnMoves.Where(m => m != 0 && (!baseMoves.Contains(m) || inheritMoves.Contains(m))).ToList();
|
|
|
|
|
int inheritCt = inherited.Count;
|
|
|
|
|
|
|
|
|
|
// Get required amount of base moves
|
|
|
|
|
int unique = baseMoves.Concat(inherited).Distinct().Count();
|
|
|
|
|
int reqBase = inheritCt == 4 || baseCt + inheritCt > 4 ? 4 - inheritCt : baseCt;
|
|
|
|
|
if (RelearnMoves.Where(m => m != 0).Count() < Math.Min(4, baseMoves.Count))
|
|
|
|
|
reqBase = Math.Min(4, unique);
|
2017-01-10 06:51:11 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
// Check if the required amount of Base Egg Moves are present.
|
|
|
|
|
for (int i = 0; i < reqBase; i++)
|
2016-03-12 17:16:41 +00:00
|
|
|
|
{
|
2017-03-23 06:34:35 +00:00
|
|
|
|
if (baseMoves.Contains(RelearnMoves[i]))
|
|
|
|
|
res[i] = new CheckResult(Severity.Valid, V179, CheckIdentifier.RelearnMove);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// mark remaining base egg moves missing
|
|
|
|
|
for (int z = i; z < reqBase; z++)
|
|
|
|
|
res[z] = new CheckResult(Severity.Invalid, V180, CheckIdentifier.RelearnMove);
|
2016-03-12 17:16:41 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
// provide the list of suggested base moves for the last required slot
|
2017-03-25 17:24:56 +00:00
|
|
|
|
string em = string.Join(", ", baseMoves.Select(m => m >= movelist.Length ? V190 : movelist[m]));
|
2017-03-23 06:34:35 +00:00
|
|
|
|
res[reqBase - 1].Comment += string.Format(Environment.NewLine + V181, em);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-03-12 17:16:41 +00:00
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
// Non-Base moves that can magically appear in the regular movepool
|
|
|
|
|
if (Legal.LightBall.Contains(pkm.Species))
|
|
|
|
|
inheritMoves.Add(344);
|
|
|
|
|
|
|
|
|
|
// Inherited moves appear after the required base moves.
|
|
|
|
|
for (int i = reqBase; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
if (RelearnMoves[i] == 0) // empty
|
|
|
|
|
res[i] = new CheckResult(Severity.Valid, V167, CheckIdentifier.RelearnMove);
|
|
|
|
|
else if (inheritMoves.Contains(RelearnMoves[i])) // inherited
|
|
|
|
|
res[i] = new CheckResult(Severity.Valid, V172, CheckIdentifier.RelearnMove);
|
|
|
|
|
else // not inheritable, flag
|
|
|
|
|
res[i] = new CheckResult(Severity.Invalid, V182, CheckIdentifier.RelearnMove);
|
2016-03-12 17:16:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-25 17:24:56 +00:00
|
|
|
|
RelearnBase = baseMoves.ToArray();
|
2016-03-12 17:16:41 +00:00
|
|
|
|
return res;
|
|
|
|
|
}
|
2017-03-23 06:34:35 +00:00
|
|
|
|
|
2017-03-26 13:39:09 +00:00
|
|
|
|
/* Similar to verifyRelearnEgg but in pre relearn generation is the moves what should match the expected order
|
|
|
|
|
but only if the pokemon is inside an egg */
|
2017-03-27 02:10:31 +00:00
|
|
|
|
private CheckResult[] verifyPreRelearnEggBase(int[] Moves, List<int> baseMoves, List<int> eggmoves, List<int> lvlmoves, List<int> tmhmmoves, List<int> tutormoves, List<int> specialmoves, bool AllowInherited, GameVersion ver)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
|
|
|
|
CheckResult[] res = new CheckResult[4];
|
|
|
|
|
|
|
|
|
|
// Obtain level1 moves
|
2017-03-26 15:07:36 +00:00
|
|
|
|
int baseCt = baseMoves.Count;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
if (baseCt > 4) baseCt = 4;
|
|
|
|
|
|
|
|
|
|
// Obtain Inherited moves
|
2017-03-26 15:07:36 +00:00
|
|
|
|
var inherited = Moves.Where(m => m != 0 && (!baseMoves.Contains(m) || specialmoves.Contains(m) || eggmoves.Contains(m) || lvlmoves.Contains(m) || tmhmmoves.Contains(m) || tutormoves.Contains(m))).ToList();
|
|
|
|
|
int inheritCt = inherited.Count;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
|
|
|
|
|
// Get required amount of base moves
|
|
|
|
|
int unique = baseMoves.Concat(inherited).Distinct().Count();
|
|
|
|
|
int reqBase = inheritCt == 4 || baseCt + inheritCt > 4 ? 4 - inheritCt : baseCt;
|
2017-03-26 15:07:36 +00:00
|
|
|
|
if (Moves.Where(m => m != 0).Count() < Math.Min(4, baseMoves.Count))
|
2017-03-26 13:39:09 +00:00
|
|
|
|
reqBase = Math.Min(4, unique);
|
|
|
|
|
|
|
|
|
|
var em = string.Empty;
|
2017-03-26 15:07:36 +00:00
|
|
|
|
var moveoffset = 0;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
// Check if the required amount of Base Egg Moves are present.
|
2017-03-26 15:07:36 +00:00
|
|
|
|
for (int i = moveoffset; i < reqBase; i++)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
|
|
|
|
if (baseMoves.Contains(Moves[i]))
|
|
|
|
|
res[i] = new CheckResult(Severity.Valid, V179, CheckIdentifier.Move);
|
2017-03-26 16:05:58 +00:00
|
|
|
|
else
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
|
|
|
|
// mark remaining base egg moves missing
|
|
|
|
|
for (int z = i; z < reqBase; z++)
|
|
|
|
|
res[z] = new CheckResult(Severity.Invalid, V180, CheckIdentifier.Move);
|
|
|
|
|
|
|
|
|
|
// provide the list of suggested base moves for the last required slot
|
|
|
|
|
em = string.Join(", ", baseMoves.Select(m => m >= movelist.Length ? V190 : movelist[m]));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-26 15:07:36 +00:00
|
|
|
|
|
|
|
|
|
moveoffset += reqBase;
|
|
|
|
|
|
2017-03-26 13:39:09 +00:00
|
|
|
|
// Check also if the required amount of Special Egg Moves are present, ir are after base moves
|
2017-03-27 02:10:31 +00:00
|
|
|
|
for (int i = moveoffset; i < moveoffset + specialmoves.Count; i++)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
|
|
|
|
if (specialmoves.Contains(Moves[i]))
|
|
|
|
|
res[i] = new CheckResult(Severity.Valid, V333, CheckIdentifier.Move);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// mark remaining special egg moves missing
|
2017-03-27 02:10:31 +00:00
|
|
|
|
for (int z = i; z < moveoffset + specialmoves.Count; z++)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
res[z] = new CheckResult(Severity.Invalid, V342, CheckIdentifier.Move);
|
|
|
|
|
|
2017-03-26 16:05:58 +00:00
|
|
|
|
// provide the list of suggested base moves and specia moves for the last required slot
|
|
|
|
|
if (!string.IsNullOrEmpty(em)) em += ",";
|
|
|
|
|
else
|
|
|
|
|
em = string.Join(", ", baseMoves.Select(m => m >= movelist.Length ? V190 : movelist[m])) + ",";
|
|
|
|
|
em += string.Join(", ", specialmoves.Select(m => m >= movelist.Length ? V190 : movelist[m]));
|
2017-03-26 13:39:09 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!string.IsNullOrEmpty(em))
|
2017-03-26 16:05:58 +00:00
|
|
|
|
res[reqBase > 0 ? reqBase - 1 : 0].Comment = string.Format(Environment.NewLine + V343, em);
|
2017-03-26 13:39:09 +00:00
|
|
|
|
// Non-Base moves that can magically appear in the regular movepool
|
2017-03-26 15:07:36 +00:00
|
|
|
|
if (pkm.GenNumber >=3 && Legal.LightBall.Contains(pkm.Species))
|
2017-03-26 13:39:09 +00:00
|
|
|
|
eggmoves.Add(344);
|
|
|
|
|
|
|
|
|
|
// Inherited moves appear after the required base moves.
|
2017-03-26 15:07:36 +00:00
|
|
|
|
var AllowInheritedSeverity = AllowInherited ? Severity.Valid : Severity.Invalid;
|
2017-03-27 02:10:31 +00:00
|
|
|
|
for (int i = reqBase + specialmoves.Count; i < 4; i++)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
|
|
|
|
if (Moves[i] == 0) // empty
|
|
|
|
|
res[i] = new CheckResult(Severity.Valid, V167, CheckIdentifier.Move);
|
2017-03-26 15:07:36 +00:00
|
|
|
|
else if (eggmoves.Contains(Moves[i])) // inherited egg move
|
|
|
|
|
res[i] = new CheckResult(AllowInheritedSeverity, AllowInherited ? V344 : V341, CheckIdentifier.Move);
|
|
|
|
|
else if (lvlmoves.Contains(Moves[i])) // inherited lvl moves
|
|
|
|
|
res[i] = new CheckResult(AllowInheritedSeverity, AllowInherited ? V345 : V347, CheckIdentifier.Move);
|
|
|
|
|
else if (tmhmmoves.Contains(Moves[i])) // inherited TMHM moves
|
|
|
|
|
res[i] = new CheckResult(AllowInheritedSeverity, AllowInherited ? V349 : V350, CheckIdentifier.Move);
|
|
|
|
|
else if (tutormoves.Contains(Moves[i])) // inherited tutor moves
|
|
|
|
|
res[i] = new CheckResult(AllowInheritedSeverity, AllowInherited ? V346 : V348, CheckIdentifier.Move);
|
2017-03-26 13:39:09 +00:00
|
|
|
|
else // not inheritable, flag
|
|
|
|
|
res[i] = new CheckResult(Severity.Invalid, V340, CheckIdentifier.Move);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-23 06:34:35 +00:00
|
|
|
|
private void verifyNoEmptyDuplicates(int[] Moves, CheckResult[] res)
|
|
|
|
|
{
|
|
|
|
|
bool emptySlot = false;
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
if (Moves[i] == 0)
|
|
|
|
|
emptySlot = true;
|
|
|
|
|
else if (emptySlot)
|
|
|
|
|
res[i] = new CheckResult(Severity.Invalid, V167, res[i].Identifier);
|
|
|
|
|
else if (Moves.Count(m => m == Moves[i]) > 1)
|
|
|
|
|
res[i] = new CheckResult(Severity.Invalid, V168, res[i].Identifier);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-28 04:57:24 +00:00
|
|
|
|
private CheckResult verifyEggMoves()
|
|
|
|
|
{
|
|
|
|
|
if (!pkm.WasEgg || vMoves.All(m => m.Valid))
|
|
|
|
|
return new CheckResult(CheckIdentifier.Egg);
|
|
|
|
|
|
|
|
|
|
// todo: egg move breeding legality
|
|
|
|
|
switch (pkm.GenNumber)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
case 2:
|
|
|
|
|
// Check Both Egg Moves -- egg moves are initially checked with no game as the base.
|
|
|
|
|
foreach (var game in new[] {GameVersion.GS, GameVersion.C})
|
|
|
|
|
{
|
|
|
|
|
vMoves = verifyMoves(game);
|
|
|
|
|
if (vMoves.Any(m => !m.Valid))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// todo: check compatibility of parents (chain wise)
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.Valid, string.Format(V185, game), CheckIdentifier.Egg);
|
2017-02-28 04:57:24 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 3:
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.NotImplemented, V186, CheckIdentifier.Egg);
|
2017-02-28 04:57:24 +00:00
|
|
|
|
|
|
|
|
|
case 4:
|
2017-03-21 07:18:38 +00:00
|
|
|
|
return new CheckResult(Severity.NotImplemented, V186, CheckIdentifier.Egg);
|
2017-02-28 04:57:24 +00:00
|
|
|
|
}
|
|
|
|
|
return new CheckResult(CheckIdentifier.Egg);
|
|
|
|
|
}
|
2016-03-23 02:47:13 +00:00
|
|
|
|
|
2017-01-08 07:54:09 +00:00
|
|
|
|
public static string[] movelist = Util.getMovesList("en");
|
2016-03-26 03:39:31 +00:00
|
|
|
|
private static readonly string[] EventRibName =
|
2016-03-23 02:47:13 +00:00
|
|
|
|
{
|
|
|
|
|
"Country", "National", "Earth", "World", "Classic",
|
|
|
|
|
"Premier", "Event", "Birthday", "Special", "Souvenir",
|
|
|
|
|
"Wishing", "Battle Champ", "Regional Champ", "National Champ", "World Champ"
|
|
|
|
|
};
|
2017-03-25 23:38:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Converts a Check result Severity determination (Valid/Invalid/etc) to the localized string.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="s"><see cref="Severity"/> value to convert to string.</param>
|
|
|
|
|
/// <returns>Localized <see cref="string"/>.</returns>
|
|
|
|
|
private static string getString(Severity s)
|
|
|
|
|
{
|
|
|
|
|
switch (s)
|
|
|
|
|
{
|
|
|
|
|
case Severity.Indeterminate: return V500;
|
|
|
|
|
case Severity.Invalid: return V501;
|
|
|
|
|
case Severity.Fishy: return V502;
|
|
|
|
|
case Severity.Valid: return V503;
|
|
|
|
|
default: return V504;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-03-11 04:36:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|