mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-26 22:10:21 +00:00
Refactor Legality engine
Beginnings of multi-generational support; removed all references to PK6 (child) and changed to PKM (abstract parent). The core portion still needs revision to not be hard-coded for XY/ORAS info tables.
This commit is contained in:
parent
e3d7a7ebce
commit
0fec576831
17 changed files with 1241 additions and 869 deletions
|
@ -6,77 +6,115 @@ namespace PKHeX
|
|||
{
|
||||
public partial class LegalityAnalysis
|
||||
{
|
||||
private readonly PK6 pk6;
|
||||
private object EncounterMatch;
|
||||
private List<WC6> CardMatch;
|
||||
private Type EncounterType;
|
||||
private LegalityCheck ECPID, Nickname, IDs, IVs, EVs, Encounter, Level, Ribbons, Ability, Ball, History, OTMemory, HTMemory, Region, Form, Misc, Gender;
|
||||
private LegalityCheck[] Checks => new[] { Encounter, Level, Form, Ball, Ability, Ribbons, ECPID, Nickname, IVs, EVs, IDs, History, OTMemory, HTMemory, Region, Misc, Gender };
|
||||
private PKM pkm;
|
||||
private readonly List<CheckResult> Parse = new List<CheckResult>();
|
||||
|
||||
public bool Valid = true;
|
||||
public bool SecondaryChecked;
|
||||
public int[] RelearnBase;
|
||||
public LegalityCheck[] vMoves = new LegalityCheck[4];
|
||||
public LegalityCheck[] vRelearn = new LegalityCheck[4];
|
||||
private object EncounterMatch;
|
||||
private Type EncounterType;
|
||||
private List<MysteryGift> EventGiftMatch;
|
||||
private CheckResult Encounter, History;
|
||||
private int[] RelearnBase;
|
||||
// private bool SecondaryChecked;
|
||||
|
||||
public readonly bool Parsed;
|
||||
public readonly bool Valid;
|
||||
public CheckResult[] vMoves = new CheckResult[4];
|
||||
public CheckResult[] vRelearn = new CheckResult[4];
|
||||
public string Report => getLegalityReport();
|
||||
public string VerboseReport => getVerboseLegalityReport();
|
||||
public bool Native => pkm.GenNumber == pkm.Format;
|
||||
|
||||
public LegalityAnalysis(PKM pk)
|
||||
{
|
||||
if (!(pk is PK6))
|
||||
return;
|
||||
pk6 = (PK6) pk;
|
||||
try
|
||||
{
|
||||
switch (pk.Format)
|
||||
{
|
||||
case 6: parsePK6(pk); break;
|
||||
case 7: parsePK7(pk); break;
|
||||
default: return;
|
||||
}
|
||||
Valid = Parse.Any() && Parse.All(chk => chk.Valid);
|
||||
if (vMoves.Any(m => m.Valid != true))
|
||||
Valid = false;
|
||||
else if (vRelearn.Any(m => m.Valid != true))
|
||||
Valid = false;
|
||||
}
|
||||
catch { Valid = false; }
|
||||
Parsed = true;
|
||||
}
|
||||
|
||||
private void AddLine(Severity s, string c, CheckIdentifier i)
|
||||
{
|
||||
AddLine(new CheckResult(s, c, i));
|
||||
}
|
||||
private void AddLine(CheckResult chk)
|
||||
{
|
||||
Parse.Add(chk);
|
||||
}
|
||||
private void parsePK6(PKM pk)
|
||||
{
|
||||
if (!(pk is PK6))
|
||||
return;
|
||||
pkm = pk;
|
||||
|
||||
updateRelearnLegality();
|
||||
updateMoveLegality();
|
||||
updateChecks();
|
||||
getLegalityReport();
|
||||
}
|
||||
catch { Valid = false; }
|
||||
private void parsePK7(PKM pk)
|
||||
{
|
||||
if (!(pk is PK7))
|
||||
return;
|
||||
pkm = pk;
|
||||
|
||||
updateRelearnLegality();
|
||||
updateMoveLegality();
|
||||
updateChecks();
|
||||
getLegalityReport();
|
||||
}
|
||||
|
||||
public void updateRelearnLegality()
|
||||
private void updateRelearnLegality()
|
||||
{
|
||||
try { vRelearn = verifyRelearn(); }
|
||||
catch { for (int i = 0; i < 4; i++) vRelearn[i] = new LegalityCheck(Severity.Invalid, "Internal error."); }
|
||||
SecondaryChecked = false;
|
||||
catch { for (int i = 0; i < 4; i++) vRelearn[i] = new CheckResult(Severity.Invalid, "Internal error.", CheckIdentifier.RelearnMove); }
|
||||
// SecondaryChecked = false;
|
||||
}
|
||||
public void updateMoveLegality()
|
||||
private void updateMoveLegality()
|
||||
{
|
||||
try { vMoves = verifyMoves(); }
|
||||
catch { for (int i = 0; i < 4; i++) vMoves[i] = new LegalityCheck(Severity.Invalid, "Internal error."); }
|
||||
SecondaryChecked = false;
|
||||
catch { for (int i = 0; i < 4; i++) vMoves[i] = new CheckResult(Severity.Invalid, "Internal error.", CheckIdentifier.Move); }
|
||||
// SecondaryChecked = false;
|
||||
}
|
||||
|
||||
private void updateChecks()
|
||||
{
|
||||
Encounter = verifyEncounter();
|
||||
EncounterType = EncounterMatch?.GetType();
|
||||
ECPID = verifyECPID();
|
||||
Nickname = verifyNickname();
|
||||
IDs = verifyID();
|
||||
IVs = verifyIVs();
|
||||
EVs = verifyEVs();
|
||||
Level = verifyLevel();
|
||||
Ribbons = verifyRibbons();
|
||||
Ability = verifyAbility();
|
||||
Ball = verifyBall();
|
||||
History = verifyHistory();
|
||||
OTMemory = verifyOTMemory();
|
||||
HTMemory = verifyHTMemory();
|
||||
Region = verifyRegion();
|
||||
Form = verifyForm();
|
||||
Misc = verifyMisc();
|
||||
Gender = verifyGender();
|
||||
SecondaryChecked = true;
|
||||
|
||||
verifyECPID();
|
||||
verifyNickname();
|
||||
verifyID();
|
||||
verifyIVs();
|
||||
verifyEVs();
|
||||
verifyLevel();
|
||||
verifyRibbons();
|
||||
verifyAbility();
|
||||
verifyBall();
|
||||
verifyOTMemory();
|
||||
verifyHTMemory();
|
||||
verifyRegion();
|
||||
verifyForm();
|
||||
verifyMisc();
|
||||
verifyGender();
|
||||
// SecondaryChecked = true;
|
||||
}
|
||||
private string getLegalityReport()
|
||||
{
|
||||
if (pk6 == null || !pk6.Gen6)
|
||||
return "Analysis only available for Pokémon that originate from X/Y & OR/AS.";
|
||||
|
||||
var chks = Checks;
|
||||
if (!Parsed)
|
||||
return "Analysis not available for this Pokémon.";
|
||||
|
||||
string r = "";
|
||||
for (int i = 0; i < 4; i++)
|
||||
|
@ -86,19 +124,18 @@ namespace PKHeX
|
|||
if (!vRelearn[i].Valid)
|
||||
r += $"{vRelearn[i].Judgement} Relearn Move {i + 1}: {vRelearn[i].Comment}" + Environment.NewLine;
|
||||
|
||||
if (r.Length == 0 && chks.All(chk => chk.Valid))
|
||||
if (r.Length == 0 && Parse.All(chk => chk.Valid))
|
||||
return "Legal!";
|
||||
|
||||
Valid = false;
|
||||
// Build result string...
|
||||
r += chks.Where(chk => !chk.Valid).Aggregate("", (current, chk) => current + $"{chk.Judgement}: {chk.Comment}{Environment.NewLine}");
|
||||
r += Parse.Where(chk => !chk.Valid).Aggregate("", (current, chk) => current + $"{chk.Judgement}: {chk.Comment}{Environment.NewLine}");
|
||||
|
||||
return r.TrimEnd();
|
||||
}
|
||||
private string getVerboseLegalityReport()
|
||||
{
|
||||
string r = getLegalityReport() + Environment.NewLine;
|
||||
if (pk6 == null)
|
||||
if (pkm == null)
|
||||
return r;
|
||||
r += "===" + Environment.NewLine + Environment.NewLine;
|
||||
int rl = r.Length;
|
||||
|
@ -113,8 +150,7 @@ namespace PKHeX
|
|||
if (rl != r.Length) // move info added, break for next section
|
||||
r += Environment.NewLine;
|
||||
|
||||
var chks = Checks;
|
||||
r += chks.Where(chk => chk != null && chk.Valid && chk.Comment != "Valid").OrderBy(chk => chk.Judgement) // Fishy sorted to top
|
||||
r += Parse.Where(chk => chk != null && chk.Valid && chk.Comment != "Valid").OrderBy(chk => chk.Judgement) // Fishy sorted to top
|
||||
.Aggregate("", (current, chk) => current + $"{chk.Judgement}: {chk.Comment}{Environment.NewLine}");
|
||||
return r.TrimEnd();
|
||||
}
|
||||
|
@ -123,15 +159,17 @@ namespace PKHeX
|
|||
{
|
||||
if (RelearnBase == null)
|
||||
return new int[4];
|
||||
if (pkm.GenNumber < 6)
|
||||
return new int[4];
|
||||
|
||||
if (!pk6.WasEgg)
|
||||
if (!pkm.WasEgg)
|
||||
return RelearnBase;
|
||||
|
||||
List<int> window = new List<int>(RelearnBase);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (!vMoves[i].Valid || vMoves[i].Flag)
|
||||
window.Add(pk6.Moves[i]);
|
||||
window.Add(pkm.Moves[i]);
|
||||
|
||||
if (window.Count < 4)
|
||||
window.AddRange(new int[4 - window.Count]);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,10 +24,23 @@ namespace PKHeX
|
|||
private static readonly EncounterStatic[] StaticO;
|
||||
private static EncounterStatic[] getSpecial(GameVersion Game)
|
||||
{
|
||||
if (Game == GameVersion.X || Game == GameVersion.Y)
|
||||
return Encounter_XY.Where(s => s.Version == GameVersion.Any || s.Version == Game).ToArray();
|
||||
// else if (Game == GameVersion.AS || Game == GameVersion.OR)
|
||||
return Encounter_AO.Where(s => s.Version == GameVersion.Any || s.Version == Game).ToArray();
|
||||
EncounterStatic[] table = null;
|
||||
switch (Game)
|
||||
{
|
||||
case GameVersion.X:
|
||||
case GameVersion.Y:
|
||||
table = Encounter_XY;
|
||||
break;
|
||||
case GameVersion.AS:
|
||||
case GameVersion.OR:
|
||||
table = Encounter_AO;
|
||||
break;
|
||||
case GameVersion.SN:
|
||||
case GameVersion.MN:
|
||||
table = Encounter_SM;
|
||||
break;
|
||||
}
|
||||
return table?.Where(s => s.Version == GameVersion.Any || s.Version == Game).ToArray();
|
||||
}
|
||||
private static EncounterArea[] addXYAltTiles(EncounterArea[] GameSlots, EncounterArea[] SpecialSlots)
|
||||
{
|
||||
|
@ -42,6 +55,7 @@ namespace PKHeX
|
|||
|
||||
static Legal() // Setup
|
||||
{
|
||||
#region Gen6: XY & ORAS
|
||||
StaticX = getSpecial(GameVersion.X);
|
||||
StaticY = getSpecial(GameVersion.Y);
|
||||
StaticA = getSpecial(GameVersion.AS);
|
||||
|
@ -92,28 +106,30 @@ namespace PKHeX
|
|||
for (int i = 0; i < slotct; i++)
|
||||
area.Slots[i].AllowDexNav = area.Slots[i].Type != SlotType.Rock_Smash;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
internal static IEnumerable<int> getValidMoves(PK6 pk6)
|
||||
{ return getValidMoves(pk6, -1, LVL: true, Relearn: false, Tutor: true, Machine: true); }
|
||||
internal static IEnumerable<int> getValidRelearn(PK6 pk6, int skipOption)
|
||||
internal static IEnumerable<int> getValidMoves(PKM pkm)
|
||||
{ return getValidMoves(pkm, -1, LVL: true, Relearn: false, Tutor: true, Machine: true); }
|
||||
internal static IEnumerable<int> getValidRelearn(PKM pkm, int skipOption)
|
||||
{
|
||||
List<int> r = new List<int> { 0 };
|
||||
int species = getBaseSpecies(pk6, skipOption);
|
||||
r.AddRange(getLVLMoves(species, 1, pk6.AltForm));
|
||||
r.AddRange(getEggMoves(species, pk6.Species == 678 ? pk6.AltForm : 0));
|
||||
r.AddRange(getLVLMoves(species, 100, pk6.AltForm));
|
||||
int species = getBaseSpecies(pkm, skipOption);
|
||||
r.AddRange(getLVLMoves(species, 1, pkm.AltForm));
|
||||
r.AddRange(getEggMoves(species, pkm.Species == 678 ? pkm.AltForm : 0));
|
||||
r.AddRange(getLVLMoves(species, 100, pkm.AltForm));
|
||||
return r.Distinct();
|
||||
}
|
||||
internal static IEnumerable<int> getBaseEggMoves(PK6 pk6, int skipOption, int gameSource)
|
||||
internal static IEnumerable<int> getBaseEggMoves(PKM pkm, int skipOption, int gameSource)
|
||||
{
|
||||
int species = getBaseSpecies(pk6, skipOption);
|
||||
int species = getBaseSpecies(pkm, skipOption);
|
||||
if (gameSource == -1)
|
||||
{
|
||||
if (pk6.XY)
|
||||
if (pkm.XY)
|
||||
return LevelUpXY[species].getMoves(1);
|
||||
// if (pk6.Version == 26 || pk6.Version == 27)
|
||||
if (pkm.AO)
|
||||
return LevelUpAO[species].getMoves(1);
|
||||
return null;
|
||||
}
|
||||
if (gameSource == 0) // XY
|
||||
return LevelUpXY[species].getMoves(1);
|
||||
|
@ -121,89 +137,89 @@ namespace PKHeX
|
|||
return LevelUpAO[species].getMoves(1);
|
||||
}
|
||||
|
||||
internal static IEnumerable<WC6> getValidWC6s(PK6 pk6)
|
||||
internal static IEnumerable<MysteryGift> getValidWC6s(PKM pkm)
|
||||
{
|
||||
var vs = getValidPreEvolutions(pk6).ToArray();
|
||||
List<WC6> validWC6 = new List<WC6>();
|
||||
var vs = getValidPreEvolutions(pkm).ToArray();
|
||||
List<MysteryGift> validWC6 = new List<MysteryGift>();
|
||||
|
||||
foreach (WC6 wc in WC6DB.Where(wc => vs.Any(dl => dl.Species == wc.Species)))
|
||||
{
|
||||
if (pk6.Egg_Location == 0) // Not Egg
|
||||
if (pkm.Egg_Location == 0) // Not Egg
|
||||
{
|
||||
if (wc.CardID != pk6.SID) continue;
|
||||
if (wc.TID != pk6.TID) continue;
|
||||
if (wc.OT != pk6.OT_Name) continue;
|
||||
if (wc.OTGender != pk6.OT_Gender) continue;
|
||||
if (wc.PIDType == 0 && pk6.PID != wc.PID) continue;
|
||||
if (wc.PIDType == 2 && !pk6.IsShiny) continue;
|
||||
if (wc.PIDType == 3 && pk6.IsShiny) continue;
|
||||
if (wc.OriginGame != 0 && wc.OriginGame != pk6.Version) continue;
|
||||
if (wc.EncryptionConstant != 0 && wc.EncryptionConstant != pk6.EncryptionConstant) continue;
|
||||
if (wc.Language != 0 && wc.Language != pk6.Language) continue;
|
||||
if (wc.CardID != pkm.SID) continue;
|
||||
if (wc.TID != pkm.TID) continue;
|
||||
if (wc.OT != pkm.OT_Name) continue;
|
||||
if (wc.OTGender != pkm.OT_Gender) continue;
|
||||
if (wc.PIDType == 0 && pkm.PID != wc.PID) continue;
|
||||
if (wc.PIDType == 2 && !pkm.IsShiny) continue;
|
||||
if (wc.PIDType == 3 && pkm.IsShiny) continue;
|
||||
if (wc.OriginGame != 0 && wc.OriginGame != pkm.Version) continue;
|
||||
if (wc.EncryptionConstant != 0 && wc.EncryptionConstant != pkm.EncryptionConstant) continue;
|
||||
if (wc.Language != 0 && wc.Language != pkm.Language) continue;
|
||||
}
|
||||
if (wc.Form != pk6.AltForm && vs.All(dl => !FormChange.Contains(dl.Species))) continue;
|
||||
if (wc.MetLocation != pk6.Met_Location) continue;
|
||||
if (wc.EggLocation != pk6.Egg_Location) continue;
|
||||
if (wc.Level != pk6.Met_Level) continue;
|
||||
if (wc.Pokéball != pk6.Ball) continue;
|
||||
if (wc.OTGender < 3 && wc.OTGender != pk6.OT_Gender) continue;
|
||||
if (wc.Nature != 0xFF && wc.Nature != pk6.Nature) continue;
|
||||
if (wc.Gender != 3 && wc.Gender != pk6.Gender) continue;
|
||||
if (wc.Form != pkm.AltForm && vs.All(dl => !FormChange.Contains(dl.Species))) continue;
|
||||
if (wc.MetLocation != pkm.Met_Location) continue;
|
||||
if (wc.EggLocation != pkm.Egg_Location) continue;
|
||||
if (wc.Level != pkm.Met_Level) continue;
|
||||
if (wc.Ball != pkm.Ball) continue;
|
||||
if (wc.OTGender < 3 && wc.OTGender != pkm.OT_Gender) continue;
|
||||
if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) continue;
|
||||
if (wc.Gender != 3 && wc.Gender != pkm.Gender) continue;
|
||||
|
||||
if (wc.CNT_Cool > pk6.CNT_Cool) continue;
|
||||
if (wc.CNT_Beauty > pk6.CNT_Beauty) continue;
|
||||
if (wc.CNT_Cute > pk6.CNT_Cute) continue;
|
||||
if (wc.CNT_Smart > pk6.CNT_Smart) continue;
|
||||
if (wc.CNT_Tough > pk6.CNT_Tough) continue;
|
||||
if (wc.CNT_Sheen > pk6.CNT_Sheen) continue;
|
||||
if (wc.CNT_Cool > pkm.CNT_Cool) continue;
|
||||
if (wc.CNT_Beauty > pkm.CNT_Beauty) continue;
|
||||
if (wc.CNT_Cute > pkm.CNT_Cute) continue;
|
||||
if (wc.CNT_Smart > pkm.CNT_Smart) continue;
|
||||
if (wc.CNT_Tough > pkm.CNT_Tough) continue;
|
||||
if (wc.CNT_Sheen > pkm.CNT_Sheen) continue;
|
||||
|
||||
// Some checks are best performed separately as they are caused by users screwing up valid data.
|
||||
// if (!wc.RelearnMoves.SequenceEqual(pk6.RelearnMoves)) continue; // Defer to relearn legality
|
||||
// if (wc.OT.Length > 0 && pk6.CurrentHandler != 1) continue; // Defer to ownership legality
|
||||
// if (wc.OT.Length > 0 && pk6.OT_Friendship != PKX.getBaseFriendship(pk6.Species)) continue; // Friendship
|
||||
// if (wc.Level > pk6.CurrentLevel) continue; // Defer to level legality
|
||||
// if (!wc.RelearnMoves.SequenceEqual(pkm.RelearnMoves)) continue; // Defer to relearn legality
|
||||
// if (wc.OT.Length > 0 && pkm.CurrentHandler != 1) continue; // Defer to ownership legality
|
||||
// if (wc.OT.Length > 0 && pkm.OT_Friendship != PKX.getBaseFriendship(pkm.Species)) continue; // Friendship
|
||||
// if (wc.Level > pkm.CurrentLevel) continue; // Defer to level legality
|
||||
// RIBBONS: Defer to ribbon legality
|
||||
|
||||
validWC6.Add(wc);
|
||||
}
|
||||
return validWC6;
|
||||
}
|
||||
internal static EncounterLink getValidLinkGifts(PK6 pk6)
|
||||
internal static EncounterLink getValidLinkGifts(PKM pkm)
|
||||
{
|
||||
return LinkGifts.FirstOrDefault(g => g.Species == pk6.Species && g.Level == pk6.Met_Level);
|
||||
return LinkGifts.FirstOrDefault(g => g.Species == pkm.Species && g.Level == pkm.Met_Level);
|
||||
}
|
||||
internal static EncounterSlot[] getValidWildEncounters(PK6 pk6)
|
||||
internal static EncounterSlot[] getValidWildEncounters(PKM pkm)
|
||||
{
|
||||
List<EncounterSlot> s = new List<EncounterSlot>();
|
||||
|
||||
foreach (var area in getEncounterAreas(pk6))
|
||||
s.AddRange(getValidEncounterSlots(pk6, area, DexNav: pk6.AO));
|
||||
foreach (var area in getEncounterAreas(pkm))
|
||||
s.AddRange(getValidEncounterSlots(pkm, area, DexNav: pkm.AO));
|
||||
return s.Any() ? s.ToArray() : null;
|
||||
}
|
||||
internal static EncounterStatic getValidStaticEncounter(PK6 pk6)
|
||||
internal static EncounterStatic getValidStaticEncounter(PKM pkm)
|
||||
{
|
||||
// Get possible encounters
|
||||
IEnumerable<EncounterStatic> poss = getStaticEncounters(pk6);
|
||||
// Back Check against pk6
|
||||
IEnumerable<EncounterStatic> poss = getStaticEncounters(pkm);
|
||||
// Back Check against pkm
|
||||
foreach (EncounterStatic e in poss)
|
||||
{
|
||||
if (e.Nature != Nature.Random && pk6.Nature != (int)e.Nature)
|
||||
if (e.Nature != Nature.Random && pkm.Nature != (int)e.Nature)
|
||||
continue;
|
||||
if (e.EggLocation != pk6.Egg_Location)
|
||||
if (e.EggLocation != pkm.Egg_Location)
|
||||
continue;
|
||||
if (e.Location != 0 && e.Location != pk6.Met_Location)
|
||||
if (e.Location != 0 && e.Location != pkm.Met_Location)
|
||||
continue;
|
||||
if (e.Gender != -1 && e.Gender != pk6.Gender)
|
||||
if (e.Gender != -1 && e.Gender != pkm.Gender)
|
||||
continue;
|
||||
if (e.Level != pk6.Met_Level)
|
||||
if (e.Level != pkm.Met_Level)
|
||||
continue;
|
||||
|
||||
// Defer to EC/PID check
|
||||
// if (e.Shiny != null && e.Shiny != pk6.IsShiny)
|
||||
// if (e.Shiny != null && e.Shiny != pkm.IsShiny)
|
||||
// continue;
|
||||
|
||||
// Defer ball check to later
|
||||
// if (e.Gift && pk6.Ball != 4) // PokéBall
|
||||
// if (e.Gift && pkm.Ball != 4) // PokéBall
|
||||
// continue;
|
||||
|
||||
// Passes all checks, valid encounter
|
||||
|
@ -211,119 +227,118 @@ namespace PKHeX
|
|||
}
|
||||
return null;
|
||||
}
|
||||
internal static EncounterTrade getValidIngameTrade(PK6 pk6)
|
||||
internal static EncounterTrade getValidIngameTrade(PKM pkm)
|
||||
{
|
||||
if (!pk6.WasIngameTrade)
|
||||
if (!pkm.WasIngameTrade)
|
||||
return null;
|
||||
int lang = pk6.Language;
|
||||
int lang = pkm.Language;
|
||||
if (lang == 0)
|
||||
return null;
|
||||
|
||||
// Get valid pre-evolutions
|
||||
IEnumerable<DexLevel> p = getValidPreEvolutions(pk6);
|
||||
IEnumerable<DexLevel> p = getValidPreEvolutions(pkm);
|
||||
EncounterTrade z = null;
|
||||
if (pk6.XY)
|
||||
if (pkm.XY)
|
||||
z = lang == 6 ? null : TradeGift_XY.FirstOrDefault(f => p.Any(r => r.Species == f.Species));
|
||||
if (pk6.AO)
|
||||
if (pkm.AO)
|
||||
z = lang == 6 ? null : TradeGift_AO.FirstOrDefault(f => p.Any(r => r.Species == f.Species));
|
||||
|
||||
if (z == null)
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
if (z.IVs[i] != -1 && z.IVs[i] != pk6.IVs[i])
|
||||
if (z.IVs[i] != -1 && z.IVs[i] != pkm.IVs[i])
|
||||
return null;
|
||||
|
||||
if (z.Shiny ^ pk6.IsShiny) // Are PIDs static?
|
||||
if (z.Shiny ^ pkm.IsShiny) // Are PIDs static?
|
||||
return null;
|
||||
if (z.TID != pk6.TID)
|
||||
if (z.TID != pkm.TID)
|
||||
return null;
|
||||
if (z.SID != pk6.SID)
|
||||
if (z.SID != pkm.SID)
|
||||
return null;
|
||||
if (z.Location != pk6.Met_Location)
|
||||
if (z.Location != pkm.Met_Location)
|
||||
return null;
|
||||
if (z.Level != pk6.Met_Level)
|
||||
if (z.Level != pkm.Met_Level)
|
||||
return null;
|
||||
if (z.Nature != Nature.Random && (int)z.Nature != pk6.Nature)
|
||||
if (z.Nature != Nature.Random && (int)z.Nature != pkm.Nature)
|
||||
return null;
|
||||
if (z.Gender != pk6.Gender)
|
||||
if (z.Gender != pkm.Gender)
|
||||
return null;
|
||||
// if (z.Ability == 4 ^ pk6.AbilityNumber == 4) // defer to Ability
|
||||
// if (z.Ability == 4 ^ pkm.AbilityNumber == 4) // defer to Ability
|
||||
// return null;
|
||||
|
||||
return z;
|
||||
}
|
||||
internal static EncounterSlot[] getValidFriendSafari(PK6 pk6)
|
||||
internal static EncounterSlot[] getValidFriendSafari(PKM pkm)
|
||||
{
|
||||
if (!pk6.XY)
|
||||
if (!pkm.XY)
|
||||
return null;
|
||||
if (pk6.Met_Location != 148) // Friend Safari
|
||||
if (pkm.Met_Location != 148) // Friend Safari
|
||||
return null;
|
||||
if (pk6.Met_Level != 30)
|
||||
if (pkm.Met_Level != 30)
|
||||
return null;
|
||||
|
||||
IEnumerable<DexLevel> vs = getValidPreEvolutions(pk6);
|
||||
IEnumerable<DexLevel> vs = getValidPreEvolutions(pkm);
|
||||
List<EncounterSlot> slots = new List<EncounterSlot>();
|
||||
foreach (DexLevel d in vs.Where(d => FriendSafari.Contains(d.Species) && d.Level >= 30))
|
||||
{
|
||||
var slot = new EncounterSlot
|
||||
slots.Add(new EncounterSlot
|
||||
{
|
||||
Species = d.Species,
|
||||
LevelMin = 30,
|
||||
LevelMax = 30,
|
||||
Form = 0,
|
||||
Type = SlotType.FriendSafari,
|
||||
};
|
||||
slots.Add(slot);
|
||||
});
|
||||
}
|
||||
|
||||
return slots.Any() ? slots.ToArray() : null;
|
||||
}
|
||||
|
||||
internal static bool getDexNavValid(PK6 pk6)
|
||||
internal static bool getDexNavValid(PKM pkm)
|
||||
{
|
||||
IEnumerable<EncounterArea> locs = getDexNavAreas(pk6);
|
||||
return locs.Select(loc => getValidEncounterSlots(pk6, loc, DexNav: true)).Any(slots => slots.Any(slot => slot.AllowDexNav && slot.DexNav));
|
||||
IEnumerable<EncounterArea> locs = getDexNavAreas(pkm);
|
||||
return locs.Select(loc => getValidEncounterSlots(pkm, loc, DexNav: true)).Any(slots => slots.Any(slot => slot.AllowDexNav && slot.DexNav));
|
||||
}
|
||||
internal static bool getHasEvolved(PK6 pk6)
|
||||
internal static bool getHasEvolved(PKM pkm)
|
||||
{
|
||||
return getValidPreEvolutions(pk6).Count() > 1;
|
||||
return getValidPreEvolutions(pkm).Count() > 1;
|
||||
}
|
||||
internal static bool getHasTradeEvolved(PK6 pk6)
|
||||
internal static bool getHasTradeEvolved(PKM pkm)
|
||||
{
|
||||
return Evolves[pk6.Species].Evos.Any(evo => evo.Level == 1); // 1: Trade, 0: Item, >=2: Levelup
|
||||
return Evolves[pkm.Species].Evos.Any(evo => evo.Level == 1); // 1: Trade, 0: Item, >=2: Levelup
|
||||
}
|
||||
internal static bool getIsFossil(PK6 pk6)
|
||||
internal static bool getIsFossil(PKM pkm)
|
||||
{
|
||||
if (pk6.Met_Level != 20)
|
||||
if (pkm.Met_Level != 20)
|
||||
return false;
|
||||
if (pk6.Egg_Location != 0)
|
||||
if (pkm.Egg_Location != 0)
|
||||
return false;
|
||||
if (pk6.XY && pk6.Met_Location == 44)
|
||||
return Fossils.Contains(getBaseSpecies(pk6));
|
||||
if (pk6.AO && pk6.Met_Location == 190)
|
||||
return Fossils.Contains(getBaseSpecies(pk6));
|
||||
if (pkm.XY && pkm.Met_Location == 44)
|
||||
return Fossils.Contains(getBaseSpecies(pkm));
|
||||
if (pkm.AO && pkm.Met_Location == 190)
|
||||
return Fossils.Contains(getBaseSpecies(pkm));
|
||||
|
||||
return false;
|
||||
}
|
||||
internal static bool getEvolutionValid(PK6 pk6)
|
||||
internal static bool getEvolutionValid(PKM pkm)
|
||||
{
|
||||
var curr = getValidPreEvolutions(pk6);
|
||||
var poss = getValidPreEvolutions(pk6, 100);
|
||||
var curr = getValidPreEvolutions(pkm);
|
||||
var poss = getValidPreEvolutions(pkm, 100);
|
||||
|
||||
if (SplitBreed.Contains(getBaseSpecies(pk6, 1)))
|
||||
if (SplitBreed.Contains(getBaseSpecies(pkm, 1)))
|
||||
return curr.Count() >= poss.Count() - 1;
|
||||
return curr.Count() >= poss.Count();
|
||||
}
|
||||
internal static IEnumerable<int> getLineage(PK6 pk6)
|
||||
internal static IEnumerable<int> getLineage(PKM pkm)
|
||||
{
|
||||
int species = pk6.Species;
|
||||
int species = pkm.Species;
|
||||
List<int> res = new List<int>{species};
|
||||
for (int i = 0; i < Evolves.Length; i++)
|
||||
if (Evolves[i].Evos.Any(pk => pk.Species == species))
|
||||
res.Add(i);
|
||||
for (int i = -1; i < 2; i++)
|
||||
res.Add(getBaseSpecies(pk6, i));
|
||||
res.Add(getBaseSpecies(pkm, i));
|
||||
return res.Distinct();
|
||||
}
|
||||
|
||||
|
@ -363,45 +378,45 @@ namespace PKHeX
|
|||
}
|
||||
return false;
|
||||
}
|
||||
internal static bool getCanLearnMachineMove(PK6 pk6, int move, int version = -1)
|
||||
internal static bool getCanLearnMachineMove(PKM pkm, int move, int version = -1)
|
||||
{
|
||||
return getValidMoves(pk6, version, Machine: true).Contains(move);
|
||||
return getValidMoves(pkm, version, Machine: true).Contains(move);
|
||||
}
|
||||
internal static bool getCanRelearnMove(PK6 pk6, int move, int version = -1)
|
||||
internal static bool getCanRelearnMove(PKM pkm, int move, int version = -1)
|
||||
{
|
||||
return getValidMoves(pk6, version, LVL: true, Relearn: true).Contains(move);
|
||||
return getValidMoves(pkm, version, LVL: true, Relearn: true).Contains(move);
|
||||
}
|
||||
internal static bool getCanLearnMove(PK6 pk6, int move, int version = -1)
|
||||
internal static bool getCanLearnMove(PKM pkm, int move, int version = -1)
|
||||
{
|
||||
return getValidMoves(pk6, version, Tutor: true, Machine: true).Contains(move);
|
||||
return getValidMoves(pkm, version, Tutor: true, Machine: true).Contains(move);
|
||||
}
|
||||
internal static bool getCanKnowMove(PK6 pk6, int move, int version = -1)
|
||||
internal static bool getCanKnowMove(PKM pkm, int move, int version = -1)
|
||||
{
|
||||
if (pk6.Species == 235 && !InvalidSketch.Contains(move))
|
||||
if (pkm.Species == 235 && !InvalidSketch.Contains(move))
|
||||
return true;
|
||||
return getValidMoves(pk6, Version: version, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
|
||||
return getValidMoves(pkm, Version: version, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
|
||||
}
|
||||
|
||||
private static int getBaseSpecies(PK6 pk6, int skipOption = 0)
|
||||
private static int getBaseSpecies(PKM pkm, int skipOption = 0)
|
||||
{
|
||||
if (pk6.Species == 292)
|
||||
if (pkm.Species == 292)
|
||||
return 290;
|
||||
if (pk6.Species == 242 && pk6.CurrentLevel < 3) // Never Cleffa
|
||||
if (pkm.Species == 242 && pkm.CurrentLevel < 3) // Never Cleffa
|
||||
return 113;
|
||||
DexLevel[] evos = Evolves[pk6.Species].Evos;
|
||||
DexLevel[] evos = Evolves[pkm.Species].Evos;
|
||||
switch (skipOption)
|
||||
{
|
||||
case -1: return pk6.Species;
|
||||
case 1: return evos.Length <= 1 ? pk6.Species : evos[evos.Length - 2].Species;
|
||||
default: return evos.Length <= 0 ? pk6.Species : evos.Last().Species;
|
||||
case -1: return pkm.Species;
|
||||
case 1: return evos.Length <= 1 ? pkm.Species : evos[evos.Length - 2].Species;
|
||||
default: return evos.Length <= 0 ? pkm.Species : evos.Last().Species;
|
||||
}
|
||||
}
|
||||
private static IEnumerable<EncounterArea> getDexNavAreas(PK6 pk6)
|
||||
private static IEnumerable<EncounterArea> getDexNavAreas(PKM pkm)
|
||||
{
|
||||
bool alpha = pk6.Version == 26;
|
||||
if (!alpha && pk6.Version != 27)
|
||||
bool alpha = pkm.Version == 26;
|
||||
if (!alpha && pkm.Version != 27)
|
||||
return new EncounterArea[0];
|
||||
return (alpha ? SlotsA : SlotsO).Where(l => l.Location == pk6.Met_Location);
|
||||
return (alpha ? SlotsA : SlotsO).Where(l => l.Location == pkm.Met_Location);
|
||||
}
|
||||
private static IEnumerable<int> getLVLMoves(int species, int lvl, int formnum)
|
||||
{
|
||||
|
@ -409,41 +424,41 @@ namespace PKHeX
|
|||
int ind_AO = PersonalTable.AO.getFormeIndex(species, formnum);
|
||||
return LevelUpXY[ind_XY].getMoves(lvl).Concat(LevelUpAO[ind_AO].getMoves(lvl));
|
||||
}
|
||||
private static IEnumerable<EncounterArea> getEncounterSlots(PK6 pk6)
|
||||
private static IEnumerable<EncounterArea> getEncounterSlots(PKM pkm)
|
||||
{
|
||||
switch (pk6.Version)
|
||||
switch (pkm.Version)
|
||||
{
|
||||
case 24: // X
|
||||
return getSlots(pk6, SlotsX);
|
||||
return getSlots(pkm, SlotsX);
|
||||
case 25: // Y
|
||||
return getSlots(pk6, SlotsY);
|
||||
return getSlots(pkm, SlotsY);
|
||||
case 26: // AS
|
||||
return getSlots(pk6, SlotsA);
|
||||
return getSlots(pkm, SlotsA);
|
||||
case 27: // OR
|
||||
return getSlots(pk6, SlotsO);
|
||||
return getSlots(pkm, SlotsO);
|
||||
default: return new List<EncounterArea>();
|
||||
}
|
||||
}
|
||||
private static IEnumerable<EncounterStatic> getStaticEncounters(PK6 pk6)
|
||||
private static IEnumerable<EncounterStatic> getStaticEncounters(PKM pkm)
|
||||
{
|
||||
switch (pk6.Version)
|
||||
switch (pkm.Version)
|
||||
{
|
||||
case 24: // X
|
||||
return getStatic(pk6, StaticX);
|
||||
return getStatic(pkm, StaticX);
|
||||
case 25: // Y
|
||||
return getStatic(pk6, StaticY);
|
||||
return getStatic(pkm, StaticY);
|
||||
case 26: // AS
|
||||
return getStatic(pk6, StaticA);
|
||||
return getStatic(pkm, StaticA);
|
||||
case 27: // OR
|
||||
return getStatic(pk6, StaticO);
|
||||
return getStatic(pkm, StaticO);
|
||||
default: return new List<EncounterStatic>();
|
||||
}
|
||||
}
|
||||
private static IEnumerable<EncounterArea> getEncounterAreas(PK6 pk6)
|
||||
private static IEnumerable<EncounterArea> getEncounterAreas(PKM pkm)
|
||||
{
|
||||
return getEncounterSlots(pk6).Where(l => l.Location == pk6.Met_Location);
|
||||
return getEncounterSlots(pkm).Where(l => l.Location == pkm.Met_Location);
|
||||
}
|
||||
private static IEnumerable<EncounterSlot> getValidEncounterSlots(PK6 pk6, EncounterArea loc, bool DexNav)
|
||||
private static IEnumerable<EncounterSlot> getValidEncounterSlots(PKM pkm, EncounterArea loc, bool DexNav)
|
||||
{
|
||||
const int fluteBoost = 4;
|
||||
const int dexnavBoost = 30;
|
||||
|
@ -452,36 +467,36 @@ namespace PKHeX
|
|||
List<EncounterSlot> slotdata = new List<EncounterSlot>();
|
||||
|
||||
// Get Valid levels
|
||||
IEnumerable<DexLevel> vs = getValidPreEvolutions(pk6);
|
||||
IEnumerable<DexLevel> vs = getValidPreEvolutions(pkm);
|
||||
// Get slots where pokemon can exist
|
||||
IEnumerable<EncounterSlot> slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin - df));
|
||||
|
||||
// Filter for Met Level
|
||||
int lvl = pk6.Met_Level;
|
||||
int lvl = pkm.Met_Level;
|
||||
var encounterSlots = slots.Where(slot => slot.LevelMin - df <= lvl && lvl <= slot.LevelMax + (slot.AllowDexNav ? dn : df)).ToList();
|
||||
|
||||
// Pressure Slot
|
||||
EncounterSlot slotMax = encounterSlots.OrderByDescending(slot => slot.LevelMax).FirstOrDefault();
|
||||
if (slotMax != null)
|
||||
slotMax = new EncounterSlot(slotMax) { Pressure = true, Form = pk6.AltForm };
|
||||
slotMax = new EncounterSlot(slotMax) { Pressure = true, Form = pkm.AltForm };
|
||||
|
||||
if (!DexNav)
|
||||
{
|
||||
// Filter for Form Specific
|
||||
slotdata.AddRange(WildForms.Contains(pk6.Species)
|
||||
? encounterSlots.Where(slot => slot.Form == pk6.AltForm)
|
||||
slotdata.AddRange(WildForms.Contains(pkm.Species)
|
||||
? encounterSlots.Where(slot => slot.Form == pkm.AltForm)
|
||||
: encounterSlots);
|
||||
if (slotMax != null)
|
||||
slotdata.Add(slotMax);
|
||||
return slotdata;
|
||||
}
|
||||
|
||||
List<EncounterSlot> eslots = encounterSlots.Where(slot => !WildForms.Contains(pk6.Species) || slot.Form == pk6.AltForm).ToList();
|
||||
List<EncounterSlot> eslots = encounterSlots.Where(slot => !WildForms.Contains(pkm.Species) || slot.Form == pkm.AltForm).ToList();
|
||||
if (slotMax != null)
|
||||
eslots.Add(slotMax);
|
||||
foreach (EncounterSlot s in eslots)
|
||||
{
|
||||
bool nav = s.AllowDexNav && (pk6.RelearnMove1 != 0 || pk6.AbilityNumber == 4);
|
||||
bool nav = s.AllowDexNav && (pkm.RelearnMove1 != 0 || pkm.AbilityNumber == 4);
|
||||
EncounterSlot slot = new EncounterSlot(s) { DexNav = nav };
|
||||
|
||||
if (slot.LevelMin > lvl)
|
||||
|
@ -494,9 +509,9 @@ namespace PKHeX
|
|||
}
|
||||
return slotdata;
|
||||
}
|
||||
private static IEnumerable<EncounterArea> getSlots(PK6 pk6, IEnumerable<EncounterArea> tables)
|
||||
private static IEnumerable<EncounterArea> getSlots(PKM pkm, IEnumerable<EncounterArea> tables)
|
||||
{
|
||||
IEnumerable<DexLevel> vs = getValidPreEvolutions(pk6);
|
||||
IEnumerable<DexLevel> vs = getValidPreEvolutions(pkm);
|
||||
List<EncounterArea> slotLocations = new List<EncounterArea>();
|
||||
foreach (var loc in tables)
|
||||
{
|
||||
|
@ -508,21 +523,21 @@ namespace PKHeX
|
|||
}
|
||||
return slotLocations;
|
||||
}
|
||||
private static IEnumerable<DexLevel> getValidPreEvolutions(PK6 pk6, int lvl = -1)
|
||||
private static IEnumerable<DexLevel> getValidPreEvolutions(PKM pkm, int lvl = -1)
|
||||
{
|
||||
if (lvl < 0)
|
||||
lvl = pk6.CurrentLevel;
|
||||
if (pk6.Species == 292 && pk6.Met_Level + 1 <= lvl && lvl >= 20)
|
||||
lvl = pkm.CurrentLevel;
|
||||
if (pkm.Species == 292 && pkm.Met_Level + 1 <= lvl && lvl >= 20)
|
||||
return new List<DexLevel>
|
||||
{
|
||||
new DexLevel { Species = 292, Level = lvl },
|
||||
new DexLevel { Species = 290, Level = lvl-1 }
|
||||
};
|
||||
var evos = Evolves[pk6.Species].Evos;
|
||||
List<DexLevel> dl = new List<DexLevel> { new DexLevel { Species = pk6.Species, Level = lvl } };
|
||||
var evos = Evolves[pkm.Species].Evos;
|
||||
List<DexLevel> dl = new List<DexLevel> { new DexLevel { Species = pkm.Species, Level = lvl } };
|
||||
foreach (DexLevel evo in evos)
|
||||
{
|
||||
if (lvl >= pk6.Met_Level && lvl >= evo.Level)
|
||||
if (lvl >= pkm.Met_Level && lvl >= evo.Level)
|
||||
dl.Add(new DexLevel {Species = evo.Species, Level = lvl});
|
||||
else break;
|
||||
if (evo.Level > 2) // Level Up (from previous level)
|
||||
|
@ -530,37 +545,37 @@ namespace PKHeX
|
|||
}
|
||||
return dl;
|
||||
}
|
||||
private static IEnumerable<EncounterStatic> getStatic(PK6 pk6, IEnumerable<EncounterStatic> table)
|
||||
private static IEnumerable<EncounterStatic> getStatic(PKM pkm, IEnumerable<EncounterStatic> table)
|
||||
{
|
||||
IEnumerable<DexLevel> dl = getValidPreEvolutions(pk6);
|
||||
IEnumerable<DexLevel> dl = getValidPreEvolutions(pkm);
|
||||
return table.Where(e => dl.Any(d => d.Species == e.Species));
|
||||
}
|
||||
private static IEnumerable<int> getValidMoves(PK6 pk6, int Version, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false)
|
||||
private static IEnumerable<int> getValidMoves(PKM pkm, int Version, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false)
|
||||
{
|
||||
List<int> r = new List<int> { 0 };
|
||||
int species = pk6.Species;
|
||||
int lvl = pk6.CurrentLevel;
|
||||
bool ORASTutors = Version == -1 || pk6.AO || !pk6.IsUntraded;
|
||||
int species = pkm.Species;
|
||||
int lvl = pkm.CurrentLevel;
|
||||
bool ORASTutors = Version == -1 || pkm.AO || !pkm.IsUntraded;
|
||||
if (FormChangeMoves.Contains(species)) // Deoxys & Shaymin & Giratina (others don't have extra but whatever)
|
||||
{
|
||||
int formcount = PersonalTable.AO[species].FormeCount;
|
||||
for (int i = 0; i < formcount; i++)
|
||||
r.AddRange(getMoves(species, lvl, i, ORASTutors, Version, LVL, Tutor, Machine));
|
||||
if (Relearn) r.AddRange(pk6.RelearnMoves);
|
||||
if (Relearn) r.AddRange(pkm.RelearnMoves);
|
||||
return r.Distinct().ToArray();
|
||||
}
|
||||
|
||||
r.AddRange(getMoves(species, lvl, pk6.AltForm, ORASTutors, Version, LVL, Tutor, Machine));
|
||||
IEnumerable<DexLevel> vs = getValidPreEvolutions(pk6);
|
||||
r.AddRange(getMoves(species, lvl, pkm.AltForm, ORASTutors, Version, LVL, Tutor, Machine));
|
||||
IEnumerable<DexLevel> vs = getValidPreEvolutions(pkm);
|
||||
|
||||
foreach (DexLevel evo in vs)
|
||||
r.AddRange(getMoves(evo.Species, evo.Level, pk6.AltForm, ORASTutors, Version, LVL, Tutor, Machine));
|
||||
r.AddRange(getMoves(evo.Species, evo.Level, pkm.AltForm, ORASTutors, Version, LVL, Tutor, Machine));
|
||||
if (species == 479) // Rotom
|
||||
r.Add(RotomMoves[pk6.AltForm]);
|
||||
r.Add(RotomMoves[pkm.AltForm]);
|
||||
if (species == 25) // Pikachu
|
||||
r.Add(PikachuMoves[pk6.AltForm]);
|
||||
r.Add(PikachuMoves[pkm.AltForm]);
|
||||
|
||||
if (Relearn) r.AddRange(pk6.RelearnMoves);
|
||||
if (Relearn) r.AddRange(pkm.RelearnMoves);
|
||||
return r.Distinct().ToArray();
|
||||
}
|
||||
private static IEnumerable<int> getMoves(int species, int lvl, int form, bool ORASTutors, int Version, bool LVL, bool Tutor, bool Machine)
|
||||
|
|
|
@ -312,7 +312,13 @@ namespace PKHeX
|
|||
internal static readonly int[] Gen4EncounterTypes = { 1, 2, 4, 5, 7, 9, 10, 12, 23, 24 };
|
||||
internal const int Struggle = 165;
|
||||
internal const int Chatter = 448;
|
||||
internal static readonly int[] InvalidSketch = {Struggle, Chatter};
|
||||
internal static readonly int[] InvalidSketch =
|
||||
{
|
||||
// Regular Moves
|
||||
Struggle, Chatter
|
||||
// Z-Moves
|
||||
|
||||
};
|
||||
internal static readonly int[] EggLocations = {60002, 30002};
|
||||
internal static readonly int[] LightBall = {25, 26, 172};
|
||||
internal static readonly int[] Fossils = {138, 140, 142, 345, 347, 408, 410, 564, 566, 696, 698};
|
||||
|
@ -861,7 +867,7 @@ namespace PKHeX
|
|||
497, 500, 503, //3
|
||||
566, 567, 696, 697, 698, 699 // Fossil Only obtain
|
||||
};
|
||||
internal static readonly int[] WurmpleFamily =
|
||||
internal static readonly int[] WurmpleEvolutions =
|
||||
{
|
||||
266, 267, // Silcoon Beautifly
|
||||
268, 269, // Cascoon Dustox
|
||||
|
|
|
@ -37,5 +37,10 @@ namespace PKHeX
|
|||
776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 798, 799, 800, 801, 802, 803, 804, 805, 806, 836
|
||||
};
|
||||
internal static readonly ushort[] HeldItems_SM = new ushort[1].Concat(Pouch_Items_SM).Concat(Pouch_Berries_SM).Concat(Pouch_Medicine_SM).Concat(Pouch_ZCrystal_SM).ToArray();
|
||||
|
||||
private static readonly EncounterStatic[] Encounter_SM =
|
||||
{
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2113,7 +2113,7 @@ namespace PKHeX
|
|||
Util.Alert("EC should match PID.");
|
||||
}
|
||||
|
||||
int wIndex = Array.IndexOf(Legal.WurmpleFamily, Util.getIndex(CB_Species));
|
||||
int wIndex = Array.IndexOf(Legal.WurmpleEvolutions, Util.getIndex(CB_Species));
|
||||
if (wIndex < 0)
|
||||
{
|
||||
TB_EC.Text = Util.rnd32().ToString("X8");
|
||||
|
@ -2774,6 +2774,11 @@ namespace PKHeX
|
|||
private void showLegality(PKM pk, bool tabs, bool verbose)
|
||||
{
|
||||
LegalityAnalysis la = new LegalityAnalysis(pk);
|
||||
if (!la.Native)
|
||||
{
|
||||
Util.Alert($"Checking legality of PK{pk.Format} files that originated from Gen{pk.GenNumber} is not supported.");
|
||||
return;
|
||||
}
|
||||
if (tabs)
|
||||
updateLegality(la);
|
||||
Util.Alert(verbose ? la.VerboseReport : la.Report);
|
||||
|
@ -2782,11 +2787,15 @@ namespace PKHeX
|
|||
{
|
||||
if (!fieldsLoaded)
|
||||
return;
|
||||
if (!(pkm is PK6))
|
||||
Legality = la ?? new LegalityAnalysis(pkm);
|
||||
if (!Legality.Parsed || !Legality.Native || HaX)
|
||||
{
|
||||
PB_Legal.Visible = false;
|
||||
return;
|
||||
Legality = la ?? new LegalityAnalysis((PK6) pkm);
|
||||
}
|
||||
PB_Legal.Visible = true;
|
||||
|
||||
PB_Legal.Image = Legality.Valid ? Properties.Resources.valid : Properties.Resources.warn;
|
||||
PB_Legal.Visible = pkm.Gen6 /*&& pkm is PK6*/ && !HaX;
|
||||
|
||||
// Refresh Move Legality
|
||||
for (int i = 0; i < 4; i++)
|
||||
|
@ -3378,12 +3387,7 @@ namespace PKHeX
|
|||
|
||||
if (pk.Species == 0 || !pk.ChecksumValid)
|
||||
{ SystemSounds.Asterisk.Play(); return; }
|
||||
if (typeof (PK6) != pk.GetType())
|
||||
{
|
||||
Util.Alert($"Checking legality of {pk.GetType().Name} files is not supported.");
|
||||
return;
|
||||
}
|
||||
showLegality(pk as PK6, slot < 0, ModifierKeys == Keys.Control);
|
||||
showLegality(pk, slot < 0, ModifierKeys == Keys.Control);
|
||||
}
|
||||
private void updateSaveSlot(object sender, EventArgs e)
|
||||
{
|
||||
|
@ -3715,7 +3719,7 @@ namespace PKHeX
|
|||
}
|
||||
private void switchDaycare(object sender, EventArgs e)
|
||||
{
|
||||
if (!SAV.ORAS) return;
|
||||
if (!SAV.HasTwoDaycares) return;
|
||||
if (DialogResult.Yes == Util.Prompt(MessageBoxButtons.YesNo, "Would you like to switch the view to the other Daycare?",
|
||||
$"Currently viewing daycare {SAV.DaycareIndex + 1}."))
|
||||
// If ORAS, alter the daycare offset via toggle.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX
|
||||
{
|
||||
|
@ -90,10 +89,15 @@ namespace PKHeX
|
|||
|
||||
// Search Properties
|
||||
public virtual int Species { get { return -1; } set { } }
|
||||
public virtual int[] Moves => new int[0];
|
||||
public virtual int[] Moves => new int[4];
|
||||
public virtual int[] RelearnMoves { get { return new int[4]; } set { } }
|
||||
public virtual bool IsShiny => false;
|
||||
public virtual bool IsEgg { get { return false; } set { } }
|
||||
public virtual int HeldItem { get { return -1; } set { } }
|
||||
public virtual object Content => this;
|
||||
|
||||
public abstract int Level { get; set; }
|
||||
public abstract int Ball { get; set; }
|
||||
public bool Gen7 => Format == 7;
|
||||
public bool Gen6 => Format == 6;
|
||||
public bool Gen5 => Format == 5;
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace PKHeX
|
|||
public bool RibbonChampionWorld { get { return (RIB1 & (1 << 6)) == 1 << 6; } set { RIB1 = (byte)(RIB1 & ~(1 << 6) | (value ? 1 << 6 : 0)); } } // World Champ Ribbon
|
||||
public bool RIB1_7 { get { return (RIB1 & (1 << 7)) == 1 << 7; } set { RIB1 = (byte)(RIB1 & ~(1 << 7) | (value ? 1 << 7 : 0)); } } // Empty
|
||||
|
||||
public int Pokéball { get { return Data[0x0E]; } set { Data[0x0E] = (byte)value; } }
|
||||
public override int Ball { get { return Data[0x0E]; } set { Data[0x0E] = (byte)value; } }
|
||||
public override int HeldItem { get { return BitConverter.ToUInt16(Data, 0x10); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x10); } }
|
||||
public int Move1 { get { return BitConverter.ToUInt16(Data, 0x12); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x12); } }
|
||||
public int Move2 { get { return BitConverter.ToUInt16(Data, 0x14); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x14); } }
|
||||
|
@ -79,7 +79,7 @@ namespace PKHeX
|
|||
get { return PKX.TrimFromFFFF(Encoding.Unicode.GetString(Data, 0x4A, 0x10)); }
|
||||
set { Encoding.Unicode.GetBytes(value.PadRight(0x08, (char)0xFFFF)).CopyTo(Data, 0x4A); } }
|
||||
public int OTGender { get { return Data[0x5A]; } set { Data[0x5A] = (byte)value; } }
|
||||
public int Level { get { return Data[0x5B]; } set { Data[0x5C] = (byte)value; } }
|
||||
public override int Level { get { return Data[0x5B]; } set { Data[0x5C] = (byte)value; } }
|
||||
public override bool IsEgg { get { return Data[0x5C] == 1; } set { Data[0x5C] = (byte)(value ? 1 : 0); } }
|
||||
// Unused 0x5D 0x5E 0x5F
|
||||
public override string CardTitle
|
||||
|
@ -174,7 +174,7 @@ namespace PKHeX
|
|||
AltForm = Form,
|
||||
Version = OriginGame == 0 ? new[] {20, 21, 22, 23}[Util.rnd32() & 0x3] : OriginGame,
|
||||
Language = Language == 0 ? SAV.Language : Language,
|
||||
Ball = Pokéball,
|
||||
Ball = Ball,
|
||||
Move1 = Move1,
|
||||
Move2 = Move2,
|
||||
Move3 = Move3,
|
||||
|
|
|
@ -12,6 +12,16 @@ namespace PKHeX
|
|||
{
|
||||
internal const int Size = 0x358; // 856
|
||||
public override int Format => 4;
|
||||
public override int Level
|
||||
{
|
||||
get { return Gift.Level; }
|
||||
set { Gift.Level = value; }
|
||||
}
|
||||
public override int Ball
|
||||
{
|
||||
get { return Gift.Ball; }
|
||||
set { Gift.Ball = value; }
|
||||
}
|
||||
|
||||
public PCD(byte[] data = null)
|
||||
{
|
||||
|
@ -25,6 +35,7 @@ namespace PKHeX
|
|||
Array.Copy(Data, PGT.Size, Information, 0, Information.Length);
|
||||
}
|
||||
public readonly PGT Gift;
|
||||
public override object Content => Gift.PK;
|
||||
|
||||
public readonly byte[] Information;
|
||||
public override bool GiftUsed { get { return Gift.GiftUsed; } set { Gift.GiftUsed = value; } }
|
||||
|
@ -65,6 +76,16 @@ namespace PKHeX
|
|||
{
|
||||
internal const int Size = 0x104; // 260
|
||||
public override int Format => 4;
|
||||
public override int Level
|
||||
{
|
||||
get { return IsPokémon ? PK.Met_Level : 0; }
|
||||
set { if (IsPokémon) PK.Met_Level = value; }
|
||||
}
|
||||
public override int Ball
|
||||
{
|
||||
get { return IsPokémon ? PK.Ball : 0; }
|
||||
set { if (IsPokémon) PK.Ball = value; }
|
||||
}
|
||||
|
||||
private enum GiftType
|
||||
{
|
||||
|
@ -86,6 +107,7 @@ namespace PKHeX
|
|||
public override string CardTitle { get { return "Raw Gift (PGT)"; } set { } }
|
||||
public override int CardID { get { return -1; } set { } }
|
||||
public override bool GiftUsed { get { return false; } set { } }
|
||||
public override object Content => PK;
|
||||
|
||||
public PGT(byte[] data = null)
|
||||
{
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace PKHeX
|
|||
public uint EncryptionConstant {
|
||||
get { return BitConverter.ToUInt32(Data, 0x70); }
|
||||
set { BitConverter.GetBytes(value).CopyTo(Data, 0x70); } }
|
||||
public int Pokéball {
|
||||
public override int Ball {
|
||||
get { return Data[0x76]; }
|
||||
set { Data[0x76] = (byte)value; } }
|
||||
public override int HeldItem {
|
||||
|
@ -174,7 +174,7 @@ namespace PKHeX
|
|||
public string OT {
|
||||
get { return Util.TrimFromZero(Encoding.Unicode.GetString(Data, 0xB6, 0x1A)); }
|
||||
set { Encoding.Unicode.GetBytes(value.PadRight(value.Length + 1, '\0')).CopyTo(Data, 0xB6); } }
|
||||
public int Level { get { return Data[0xD0]; } set { Data[0xD0] = (byte)value; } }
|
||||
public override int Level { get { return Data[0xD0]; } set { Data[0xD0] = (byte)value; } }
|
||||
public override bool IsEgg { get { return Data[0xD1] == 1; } set { Data[0xD1] = (byte)(value ? 1 : 0); } }
|
||||
public uint PID {
|
||||
get { return BitConverter.ToUInt32(Data, 0xD4); }
|
||||
|
@ -223,7 +223,7 @@ namespace PKHeX
|
|||
{
|
||||
get { return new[] {Move1, Move2, Move3, Move4}; }
|
||||
}
|
||||
public int[] RelearnMoves
|
||||
public override int[] RelearnMoves
|
||||
{
|
||||
get { return new[] { RelearnMove1, RelearnMove2, RelearnMove3, RelearnMove4 }; }
|
||||
set
|
||||
|
@ -254,7 +254,7 @@ namespace PKHeX
|
|||
EncryptionConstant = EncryptionConstant == 0 ? Util.rnd32() : EncryptionConstant,
|
||||
Version = OriginGame == 0 ? SAV.Game : OriginGame,
|
||||
Language = Language == 0 ? SAV.Language : Language,
|
||||
Ball = Pokéball,
|
||||
Ball = Ball,
|
||||
Country = SAV.Country,
|
||||
Region = SAV.SubRegion,
|
||||
ConsoleRegion = SAV.ConsoleRegion,
|
||||
|
|
|
@ -166,7 +166,7 @@ namespace PKHeX
|
|||
|
||||
public override int PKRS_Strain { get { return Data[0xCA] & 0xF; } set { Data[0xCA] = (byte)(value & 0xF); } }
|
||||
public override bool IsEgg { get { return Data[0xCB] == 1; } set { Data[0xCB] = (byte)(value ? 1 : 0); } }
|
||||
public int AbilityNumber { get { return Data[0xCC]; } set { Data[0xCC] = (byte)(value & 1); } }
|
||||
public override int AbilityNumber { get { return Data[0xCC]; } set { Data[0xCC] = (byte)(value & 1); } }
|
||||
public override bool Valid { get { return Data[0xCD] == 0; } set { if (value) Data[0xCD] = 0; } }
|
||||
// 0xCE unknown
|
||||
public override byte MarkByte { get { return Data[0xCF]; } protected set { Data[0xCF] = value; } }
|
||||
|
|
|
@ -118,7 +118,7 @@ namespace PKHeX
|
|||
public override int IV_SPA { get { return (int)(IV32 >> 20) & 0x1F; } set { IV32 = (uint)((IV32 & ~(0x1F << 20)) | (uint)((value > 31 ? 31 : value) << 20)); } }
|
||||
public override int IV_SPD { get { return (int)(IV32 >> 25) & 0x1F; } set { IV32 = (uint)((IV32 & ~(0x1F << 25)) | (uint)((value > 31 ? 31 : value) << 25)); } }
|
||||
public override bool IsEgg { get { return ((IV32 >> 30) & 1) == 1; } set { IV32 = (uint)((IV32 & ~0x40000000) | (uint)(value ? 0x40000000 : 0)); } }
|
||||
public int AbilityNumber { get { return (int)((IV32 >> 31) & 1); } set { IV32 = (IV32 & 0x7FFFFFFF) | (value == 1 ? 0x80000000 : 0); } }
|
||||
public override int AbilityNumber { get { return (int)((IV32 >> 31) & 1); } set { IV32 = (IV32 & 0x7FFFFFFF) | (value == 1 ? 0x80000000 : 0); } }
|
||||
|
||||
private uint RIB0 { get { return BitConverter.ToUInt32(Data, 0x4C); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x4C); } }
|
||||
public int RibbonCountG3Cool { get { return (int)(RIB0 >> 00) & 7; } set { RIB0 = (uint)((RIB0 & ~(7 << 00)) | (uint)(value & 7) << 00); } }
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace PKHeX
|
|||
set { BitConverter.GetBytes(value).CopyTo(Data, 0x10); }
|
||||
}
|
||||
public override int Ability { get { return Data[0x14]; } set { Data[0x14] = (byte)value; } }
|
||||
public int AbilityNumber { get { return Data[0x15]; } set { Data[0x15] = (byte)value; } }
|
||||
public override int AbilityNumber { get { return Data[0x15]; } set { Data[0x15] = (byte)value; } }
|
||||
public int TrainingBagHits { get { return Data[0x16]; } set { Data[0x16] = (byte)value; } }
|
||||
public int TrainingBag { get { return Data[0x17]; } set { Data[0x17] = (byte)value; } }
|
||||
public override uint PID
|
||||
|
@ -274,8 +274,8 @@ namespace PKHeX
|
|||
get { return BitConverter.ToUInt16(Data, 0x70); }
|
||||
set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x70); }
|
||||
}
|
||||
public bool SecretSuperTrainingUnlocked { get { return (Data[0x72] & 1) == 1; } set { Data[0x72] = (byte)((Data[0x72] & ~1) | (value ? 1 : 0)); } }
|
||||
public bool SecretSuperTrainingComplete { get { return (Data[0x72] & 2) == 2; } set { Data[0x72] = (byte)((Data[0x72] & ~2) | (value ? 2 : 0)); } }
|
||||
public override bool SecretSuperTrainingUnlocked { get { return (Data[0x72] & 1) == 1; } set { Data[0x72] = (byte)((Data[0x72] & ~1) | (value ? 1 : 0)); } }
|
||||
public override bool SecretSuperTrainingComplete { get { return (Data[0x72] & 2) == 2; } set { Data[0x72] = (byte)((Data[0x72] & ~2) | (value ? 2 : 0)); } }
|
||||
public byte _0x73 { get { return Data[0x73]; } set { Data[0x73] = value; } }
|
||||
private uint IV32 { get { return BitConverter.ToUInt32(Data, 0x74); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x74); } }
|
||||
public override int IV_HP { get { return (int)(IV32 >> 00) & 0x1F; } set { IV32 = (uint)((IV32 & ~(0x1F << 00)) | (uint)((value > 31 ? 31 : value) << 00)); } }
|
||||
|
@ -381,9 +381,9 @@ namespace PKHeX
|
|||
public override int OT_Gender { get { return Data[0xDD] >> 7; } set { Data[0xDD] = (byte)((Data[0xDD] & ~0x80) | (value << 7)); } }
|
||||
public override int EncounterType { get { return Data[0xDE]; } set { Data[0xDE] = (byte)value; } }
|
||||
public override int Version { get { return Data[0xDF]; } set { Data[0xDF] = (byte)value; } }
|
||||
public int Country { get { return Data[0xE0]; } set { Data[0xE0] = (byte)value; } }
|
||||
public int Region { get { return Data[0xE1]; } set { Data[0xE1] = (byte)value; } }
|
||||
public int ConsoleRegion { get { return Data[0xE2]; } set { Data[0xE2] = (byte)value; } }
|
||||
public override int Country { get { return Data[0xE0]; } set { Data[0xE0] = (byte)value; } }
|
||||
public override int Region { get { return Data[0xE1]; } set { Data[0xE1] = (byte)value; } }
|
||||
public override int ConsoleRegion { get { return Data[0xE2]; } set { Data[0xE2] = (byte)value; } }
|
||||
public override int Language { get { return Data[0xE3]; } set { Data[0xE3] = (byte)value; } }
|
||||
#endregion
|
||||
#region Battle Stats
|
||||
|
@ -410,7 +410,6 @@ namespace PKHeX
|
|||
|
||||
public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 4);
|
||||
public override int TSV => (TID ^ SID) >> 4;
|
||||
public bool IsUntraded => string.IsNullOrWhiteSpace(HT_Name);
|
||||
public bool IsUntradedEvent6 => Geo1_Country == 0 && Geo1_Region == 0 && Met_Location / 10000 == 4 && Gen6;
|
||||
|
||||
// Complex Generated Attributes
|
||||
|
@ -624,11 +623,11 @@ namespace PKHeX
|
|||
}
|
||||
|
||||
// Legality Properties
|
||||
public bool WasLink => Met_Location == 30011;
|
||||
public bool WasEgg => Legal.EggLocations.Contains(Egg_Location);
|
||||
public bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter && Species != 386;
|
||||
public bool WasEventEgg => ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1;
|
||||
public bool WasTradedEgg => Egg_Location == 30002;
|
||||
public bool WasIngameTrade => Met_Location == 30001;
|
||||
public override bool WasLink => Met_Location == 30011;
|
||||
public override bool WasEgg => Legal.EggLocations.Contains(Egg_Location);
|
||||
public override bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter && Species != 386;
|
||||
public override bool WasEventEgg => ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1;
|
||||
public override bool WasTradedEgg => Egg_Location == 30002;
|
||||
public override bool WasIngameTrade => Met_Location == 30001;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace PKHeX
|
|||
set { BitConverter.GetBytes(value).CopyTo(Data, 0x10); }
|
||||
}
|
||||
public override int Ability { get { return Data[0x14]; } set { Data[0x14] = (byte)value; } }
|
||||
public int AbilityNumber { get { return Data[0x15]; } set { Data[0x15] = (byte)value; } }
|
||||
public override int AbilityNumber { get { return Data[0x15]; } set { Data[0x15] = (byte)value; } }
|
||||
public int TrainingBagHits { get { return Data[0x16]; } set { Data[0x16] = (byte)value; } }
|
||||
public int TrainingBag { get { return Data[0x17]; } set { Data[0x17] = (byte)value; } }
|
||||
public override uint PID
|
||||
|
@ -282,8 +282,8 @@ namespace PKHeX
|
|||
get { return BitConverter.ToUInt16(Data, 0x70); }
|
||||
set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x70); }
|
||||
}
|
||||
public bool SecretSuperTrainingUnlocked { get { return (Data[0x72] & 1) == 1; } set { Data[0x72] = (byte)((Data[0x72] & ~1) | (value ? 1 : 0)); } }
|
||||
public bool SecretSuperTrainingComplete { get { return (Data[0x72] & 2) == 2; } set { Data[0x72] = (byte)((Data[0x72] & ~2) | (value ? 2 : 0)); } }
|
||||
public override bool SecretSuperTrainingUnlocked { get { return (Data[0x72] & 1) == 1; } set { Data[0x72] = (byte)((Data[0x72] & ~1) | (value ? 1 : 0)); } }
|
||||
public override bool SecretSuperTrainingComplete { get { return (Data[0x72] & 2) == 2; } set { Data[0x72] = (byte)((Data[0x72] & ~2) | (value ? 2 : 0)); } }
|
||||
public byte _0x73 { get { return Data[0x73]; } set { Data[0x73] = value; } }
|
||||
private uint IV32 { get { return BitConverter.ToUInt32(Data, 0x74); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x74); } }
|
||||
public override int IV_HP { get { return (int)(IV32 >> 00) & 0x1F; } set { IV32 = (uint)((IV32 & ~(0x1F << 00)) | (uint)((value > 31 ? 31 : value) << 00)); } }
|
||||
|
@ -389,9 +389,9 @@ namespace PKHeX
|
|||
public override int OT_Gender { get { return Data[0xDD] >> 7; } set { Data[0xDD] = (byte)((Data[0xDD] & ~0x80) | (value << 7)); } }
|
||||
public override int EncounterType { get { return Data[0xDE]; } set { Data[0xDE] = (byte)value; } }
|
||||
public override int Version { get { return Data[0xDF]; } set { Data[0xDF] = (byte)value; } }
|
||||
public int Country { get { return Data[0xE0]; } set { Data[0xE0] = (byte)value; } }
|
||||
public int Region { get { return Data[0xE1]; } set { Data[0xE1] = (byte)value; } }
|
||||
public int ConsoleRegion { get { return Data[0xE2]; } set { Data[0xE2] = (byte)value; } }
|
||||
public override int Country { get { return Data[0xE0]; } set { Data[0xE0] = (byte)value; } }
|
||||
public override int Region { get { return Data[0xE1]; } set { Data[0xE1] = (byte)value; } }
|
||||
public override int ConsoleRegion { get { return Data[0xE2]; } set { Data[0xE2] = (byte)value; } }
|
||||
public override int Language { get { return Data[0xE3]; } set { Data[0xE3] = (byte)value; } }
|
||||
#endregion
|
||||
#region Battle Stats
|
||||
|
@ -418,7 +418,6 @@ namespace PKHeX
|
|||
|
||||
public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 4);
|
||||
public override int TSV => (TID ^ SID) >> 4;
|
||||
public bool IsUntraded => string.IsNullOrWhiteSpace(HT_Name);
|
||||
public bool IsUntradedEvent6 => Geo1_Country == 0 && Geo1_Region == 0 && Met_Location / 10000 == 4 && Gen6;
|
||||
|
||||
// Complex Generated Attributes
|
||||
|
@ -632,11 +631,11 @@ namespace PKHeX
|
|||
}
|
||||
|
||||
// Legality Properties
|
||||
public bool WasLink => Met_Location == 30011;
|
||||
public bool WasEgg => Legal.EggLocations.Contains(Egg_Location);
|
||||
public bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter && Species != 386;
|
||||
public bool WasEventEgg => ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1;
|
||||
public bool WasTradedEgg => Egg_Location == 30002;
|
||||
public bool WasIngameTrade => Met_Location == 30001;
|
||||
public override bool WasLink => Met_Location == 30011;
|
||||
public override bool WasEgg => Legal.EggLocations.Contains(Egg_Location);
|
||||
public override bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter && Species != 386;
|
||||
public override bool WasEventEgg => ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location == 30002)) && Met_Level == 1;
|
||||
public override bool WasTradedEgg => Egg_Location == 30002;
|
||||
public override bool WasIngameTrade => Met_Location == 30001;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,6 +152,10 @@ namespace PKHeX
|
|||
public virtual int Geo5_Country { get; set; }
|
||||
public virtual byte Enjoyment { get; set; }
|
||||
public virtual byte Fullness { get; set; }
|
||||
public virtual int AbilityNumber { get; set; }
|
||||
public virtual int Country { get; set; }
|
||||
public virtual int Region { get; set; }
|
||||
public virtual int ConsoleRegion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The date the Pokémon was met.
|
||||
|
@ -377,6 +381,17 @@ namespace PKHeX
|
|||
}
|
||||
}
|
||||
|
||||
// Legality Extensions
|
||||
public virtual bool WasLink => false;
|
||||
public virtual bool WasEgg => Egg_Location > 0;
|
||||
public virtual bool WasEvent => Met_Location > 40000 && Met_Location < 50000 || FatefulEncounter;
|
||||
public virtual bool WasEventEgg => ((Egg_Location > 40000 && Egg_Location < 50000) || (FatefulEncounter && Egg_Location > 0)) && Met_Level == 1;
|
||||
public virtual bool WasTradedEgg => Egg_Location == 30002;
|
||||
public virtual bool WasIngameTrade => Met_Location == 30001;
|
||||
public virtual bool IsUntraded => string.IsNullOrWhiteSpace(HT_Name);
|
||||
public virtual bool SecretSuperTrainingUnlocked { get { return false; } set { } }
|
||||
public virtual bool SecretSuperTrainingComplete { get { return false; } set { } }
|
||||
|
||||
// Methods
|
||||
public abstract bool getGenderIsValid();
|
||||
public void RefreshChecksum() { Checksum = CalculateChecksum(); }
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace PKHeX
|
|||
public bool UnusedFlag3 { get { return (XDPKMFLAGS & (1 << 3)) == 1 << 3; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 3) | (value ? 1 << 3 : 0); } }
|
||||
public bool BlockTrades { get { return (XDPKMFLAGS & (1 << 4)) == 1 << 4; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 4) | (value ? 1 << 4 : 0); } }
|
||||
public override bool Valid { get { return (XDPKMFLAGS & (1 << 5)) == 0; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 5) | (value ? 0 : 1 << 5); } } // invalid flag
|
||||
public int AbilityNumber { get { return (XDPKMFLAGS >> 6) & 1; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 6) | (value << 6); } }
|
||||
public override int AbilityNumber { get { return (XDPKMFLAGS >> 6) & 1; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 6) | (value << 6); } }
|
||||
public override bool IsEgg { get { return (XDPKMFLAGS & (1 << 7)) == 1 << 7; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 7) | (value ? 1 << 7 : 0); } }
|
||||
// 0x1E-0x1F Unknown
|
||||
public override uint EXP { get { return BigEndian.ToUInt32(Data, 0x20); } set { BigEndian.GetBytes(value).CopyTo(Data, 0x20); } }
|
||||
|
|
|
@ -57,5 +57,9 @@ namespace PKHeX
|
|||
// Convert.ChangeType is suitable for most things
|
||||
return Convert.ChangeType(value, type);
|
||||
}
|
||||
internal static bool? getBooleanState(object obj, string prop)
|
||||
{
|
||||
return obj.GetType().HasProperty(prop) ? GetValue(obj, prop) as bool? : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue