mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-23 12:33:06 +00:00
Initial Gen1 legality checks (WIP)
Have only tested pk1 format so far; there's still a few cases that are unhandled (move discrepancies between games, trade gifts, event mew, tmhm). pls no report bugs unless you are very detailed (include WHY it is wrong).
This commit is contained in:
parent
22e49928c5
commit
578f05cd2e
9 changed files with 369 additions and 202 deletions
|
@ -2837,7 +2837,9 @@ namespace PKHeX.WinForms
|
|||
LegalityAnalysis la = new LegalityAnalysis(pk);
|
||||
if (!la.Parsed)
|
||||
{
|
||||
WinFormsUtil.Alert($"Checking legality of PK{pk.Format} files that originated from Gen{pk.GenNumber} is not supported.");
|
||||
WinFormsUtil.Alert(pk.Format < 3
|
||||
? $"Checking legality of PK{pk.Format} files is not supported."
|
||||
: $"Checking legality of PK{pk.Format} files that originated from Gen{pk.GenNumber} is not supported.");
|
||||
return;
|
||||
}
|
||||
if (tabs)
|
||||
|
@ -2846,48 +2848,43 @@ namespace PKHeX.WinForms
|
|||
}
|
||||
private void updateLegality(LegalityAnalysis la = null, bool skipMoveRepop = false)
|
||||
{
|
||||
if (pkm.GenNumber >= 6)
|
||||
if (!fieldsLoaded)
|
||||
return;
|
||||
|
||||
Legality = la ?? new LegalityAnalysis(pkm);
|
||||
if (!Legality.Parsed || HaX)
|
||||
{
|
||||
if (!fieldsLoaded)
|
||||
return;
|
||||
Legality = la ?? new LegalityAnalysis(pkm);
|
||||
if (!Legality.Parsed || HaX)
|
||||
{
|
||||
PB_Legal.Visible = false;
|
||||
return;
|
||||
}
|
||||
PB_Legal.Visible = true;
|
||||
|
||||
PB_Legal.Image = Legality.Valid ? Resources.valid : Resources.warn;
|
||||
|
||||
// Refresh Move Legality
|
||||
for (int i = 0; i < 4; i++)
|
||||
movePB[i].Visible = !Legality.vMoves[i].Valid && !HaX;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
relearnPB[i].Visible = !Legality.vRelearn[i].Valid && !HaX;
|
||||
|
||||
if (skipMoveRepop)
|
||||
return;
|
||||
// Resort moves
|
||||
bool tmp = fieldsLoaded;
|
||||
fieldsLoaded = false;
|
||||
var cb = new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 };
|
||||
var moves = Legality.AllSuggestedMovesAndRelearn;
|
||||
var moveList = GameInfo.MoveDataSource.OrderByDescending(m => moves.Contains(m.Value)).ToList();
|
||||
foreach (ComboBox c in cb)
|
||||
{
|
||||
var index = WinFormsUtil.getIndex(c);
|
||||
c.DataSource = new BindingSource(moveList, null);
|
||||
c.SelectedValue = index;
|
||||
}
|
||||
fieldsLoaded |= tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
PB_Legal.Visible = PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible =
|
||||
PB_Legal.Visible =
|
||||
PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible =
|
||||
PB_WarnRelearn1.Visible = PB_WarnRelearn2.Visible = PB_WarnRelearn3.Visible = PB_WarnRelearn4.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
PB_Legal.Visible = true;
|
||||
PB_Legal.Image = Legality.Valid ? Resources.valid : Resources.warn;
|
||||
|
||||
// Refresh Move Legality
|
||||
for (int i = 0; i < 4; i++)
|
||||
movePB[i].Visible = !Legality.vMoves[i].Valid && !HaX;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
relearnPB[i].Visible = !Legality.vRelearn[i].Valid && !HaX && pkm.Format >= 6;
|
||||
|
||||
if (skipMoveRepop)
|
||||
return;
|
||||
// Resort moves
|
||||
bool tmp = fieldsLoaded;
|
||||
fieldsLoaded = false;
|
||||
var cb = new[] {CB_Move1, CB_Move2, CB_Move3, CB_Move4};
|
||||
var moves = Legality.AllSuggestedMovesAndRelearn;
|
||||
var moveList = GameInfo.MoveDataSource.OrderByDescending(m => moves.Contains(m.Value)).ToList();
|
||||
foreach (ComboBox c in cb)
|
||||
{
|
||||
var index = WinFormsUtil.getIndex(c);
|
||||
c.DataSource = new BindingSource(moveList, null);
|
||||
c.SelectedValue = index;
|
||||
}
|
||||
fieldsLoaded |= tmp;
|
||||
}
|
||||
|
||||
private void updateGender()
|
||||
|
|
|
@ -39,11 +39,14 @@ namespace PKHeX.Core
|
|||
|
||||
try
|
||||
{
|
||||
switch (pk.Format) // prior to storing GameVersion
|
||||
{
|
||||
case 1: parsePK1(pk); break;
|
||||
}
|
||||
switch (pk.GenNumber)
|
||||
{
|
||||
case 6: parsePK6(pk); break;
|
||||
case 7: parsePK7(pk); break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
Valid = Parsed = Parse.Any();
|
||||
|
@ -59,6 +62,8 @@ namespace PKHeX.Core
|
|||
if (pkm.FatefulEncounter && vRelearn.Any(chk => !chk.Valid) && EncounterMatch == null)
|
||||
AddLine(Severity.Indeterminate, "Fateful Encounter with no matching Encounter. Has the Mystery Gift data been contributed?", CheckIdentifier.Fateful);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
catch { Valid = false; }
|
||||
AllSuggestedMoves = !pkm.IsOriginValid() ? new int[4] : getSuggestedMoves(true, true, true);
|
||||
|
@ -74,6 +79,19 @@ namespace PKHeX.Core
|
|||
{
|
||||
Parse.Add(chk);
|
||||
}
|
||||
|
||||
private void parsePK1(PKM pk)
|
||||
{
|
||||
pkm = pk;
|
||||
if (!pkm.IsOriginValid())
|
||||
{ AddLine(Severity.Invalid, "Species does not exist in origin game.", CheckIdentifier.None); return; }
|
||||
|
||||
updateEncounterChain();
|
||||
updateMoveLegality();
|
||||
verifyNickname();
|
||||
verifyDVs();
|
||||
verifyG1OT();
|
||||
}
|
||||
private void parsePK6(PKM pk)
|
||||
{
|
||||
pkm = pk;
|
||||
|
@ -116,6 +134,7 @@ namespace PKHeX.Core
|
|||
EncounterMatch = EventGiftMatch.First(); // temporarily set one so that Encounter can be verified
|
||||
|
||||
Encounter = verifyEncounter();
|
||||
Parse.Add(Encounter);
|
||||
EvoChain = Legal.getEvolutionChain(pkm, EncounterMatch);
|
||||
}
|
||||
private void updateChecks()
|
||||
|
@ -160,6 +179,8 @@ namespace PKHeX.Core
|
|||
for (int i = 0; i < 4; i++)
|
||||
if (!vMoves[i].Valid)
|
||||
r += $"{vMoves[i].Judgement} Move {i + 1}: {vMoves[i].Comment}" + Environment.NewLine;
|
||||
|
||||
if (pkm.Format >= 6)
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (!vRelearn[i].Valid)
|
||||
r += $"{vRelearn[i].Judgement} Relearn Move {i + 1}: {vRelearn[i].Comment}" + Environment.NewLine;
|
||||
|
@ -186,7 +207,9 @@ namespace PKHeX.Core
|
|||
for (int i = 0; i < 4; i++)
|
||||
if (vMoves[i].Valid)
|
||||
r += $"{vMoves[i].Judgement} Move {i + 1}: {vMoves[i].Comment}" + Environment.NewLine;
|
||||
for (int i = 0; i < 4; i++)
|
||||
|
||||
if (pkm.Format >= 6)
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (vRelearn[i].Valid)
|
||||
r += $"{vRelearn[i].Judgement} Relearn Move {i + 1}: {vRelearn[i].Comment}" + Environment.NewLine;
|
||||
|
||||
|
@ -222,8 +245,10 @@ namespace PKHeX.Core
|
|||
}
|
||||
public int[] getSuggestedMoves(bool tm, bool tutor, bool reminder)
|
||||
{
|
||||
if (pkm == null || pkm.GenNumber < 6 || !pkm.IsOriginValid())
|
||||
if (pkm == null || !pkm.IsOriginValid())
|
||||
return null;
|
||||
if (pkm.GenNumber < 6 && pkm.Format != 1)
|
||||
return new int[4];
|
||||
return Legal.getValidMoves(pkm, EvoChain, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0
|
||||
}
|
||||
|
||||
|
|
|
@ -250,10 +250,13 @@ namespace PKHeX.Core
|
|||
return;
|
||||
}
|
||||
AddLine(Severity.Valid, "Nickname does not match another species name.", CheckIdentifier.EVs);
|
||||
return;
|
||||
}
|
||||
|
||||
// else
|
||||
else if (pkm.Format < 3)
|
||||
{
|
||||
// pk1/pk2 IsNicknamed getter checks for match, logic should only reach here if matches.
|
||||
AddLine(Severity.Valid, "Nickname matches species name.", CheckIdentifier.EVs);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can't have another language name if it hasn't evolved or wasn't a language-traded egg.
|
||||
bool match = (pkm.WasTradedEgg || Legal.getHasEvolved(pkm)) && PKX.SpeciesLang.Any(lang => lang[pkm.Species] == nickname)
|
||||
|
@ -263,8 +266,6 @@ namespace PKHeX.Core
|
|||
AddLine(Severity.Invalid, "Nickname does not match species name.", CheckIdentifier.EVs);
|
||||
else
|
||||
AddLine(Severity.Valid, "Nickname matches species name.", CheckIdentifier.EVs);
|
||||
|
||||
// return;
|
||||
}
|
||||
}
|
||||
private void verifyEVs()
|
||||
|
@ -328,6 +329,10 @@ namespace PKHeX.Core
|
|||
else if (pkm.IVs[0] < 30 && pkm.IVs.All(iv => pkm.IVs[0] == iv))
|
||||
AddLine(Severity.Fishy, "All IVs are equal.", CheckIdentifier.IVs);
|
||||
}
|
||||
private void verifyDVs()
|
||||
{
|
||||
// todo
|
||||
}
|
||||
private void verifyOT()
|
||||
{
|
||||
if (EncounterType == typeof(EncounterTrade))
|
||||
|
@ -348,19 +353,21 @@ namespace PKHeX.Core
|
|||
AddLine(Severity.Fishy, "SID is zero.", CheckIdentifier.Trainer);
|
||||
|
||||
if (pkm.VC)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
||||
if (tr.Length > (lang == 2 ? 7 : 5))
|
||||
AddLine(Severity.Invalid, "OT Name too long.", CheckIdentifier.Trainer);
|
||||
if (pkm.Species == 151)
|
||||
{
|
||||
if (tr != "GF" && tr != "ゲーフリ") // if there are more events with special OTs, may be worth refactoring
|
||||
AddLine(Severity.Invalid, "Incorrect event OT Name.", CheckIdentifier.Trainer);
|
||||
}
|
||||
if (tr.Length > (lang == 2 ? 7 : 5))
|
||||
AddLine(Severity.Invalid, "OT Name too long.", CheckIdentifier.Trainer);
|
||||
if (pkm.Species == 151)
|
||||
{
|
||||
if (tr != "GF" && tr != "ゲーフリ") // if there are more events with special OTs, may be worth refactoring
|
||||
AddLine(Severity.Invalid, "Incorrect event OT Name.", CheckIdentifier.Trainer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,151 +393,183 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CheckResult verifyEncounterLink()
|
||||
{
|
||||
// Should NOT be Fateful, and should be in Database
|
||||
EncounterLink enc = EncounterMatch as EncounterLink;
|
||||
if (enc == null)
|
||||
return new CheckResult(Severity.Invalid, "Invalid Link Gift: unable to find matching gift.", CheckIdentifier.Encounter);
|
||||
|
||||
if (pkm.XY && !enc.XY)
|
||||
return new CheckResult(Severity.Invalid, "Invalid Link Gift: can't obtain in XY.", CheckIdentifier.Encounter);
|
||||
if (pkm.AO && !enc.ORAS)
|
||||
return new CheckResult(Severity.Invalid, "Invalid Link Gift: can't obtain in ORAS.", CheckIdentifier.Encounter);
|
||||
if (pkm.SM && !enc.SM)
|
||||
return new CheckResult(Severity.Invalid, "Invalid Link Gift: can't obtain in SM.", CheckIdentifier.Encounter);
|
||||
|
||||
if (enc.Shiny != null && (bool)enc.Shiny ^ pkm.IsShiny)
|
||||
return new CheckResult(Severity.Invalid, "Shiny Link gift mismatch.", CheckIdentifier.Encounter);
|
||||
|
||||
return pkm.FatefulEncounter
|
||||
? new CheckResult(Severity.Invalid, "Invalid Link Gift: should not be Fateful Encounter.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Valid, "Valid Link gift.", CheckIdentifier.Encounter);
|
||||
}
|
||||
|
||||
private CheckResult verifyEncounterEvent()
|
||||
{
|
||||
MysteryGift MatchedGift = EncounterMatch as MysteryGift;
|
||||
if (MatchedGift != null)
|
||||
return new CheckResult(Severity.Valid, $"Matches #{MatchedGift.CardID:0000} ({MatchedGift.CardTitle})", CheckIdentifier.Encounter);
|
||||
return null;
|
||||
}
|
||||
private CheckResult verifyEncounterEgg()
|
||||
{
|
||||
// Check Hatch Locations
|
||||
if (pkm.Met_Level != 1)
|
||||
return new CheckResult(Severity.Invalid, "Invalid met level, expected 1.", CheckIdentifier.Encounter);
|
||||
// Check species
|
||||
if (Legal.NoHatchFromEgg.Contains(pkm.Species))
|
||||
return new CheckResult(Severity.Invalid, "Species cannot be hatched from an egg.", CheckIdentifier.Encounter);
|
||||
if (pkm.IsEgg)
|
||||
{
|
||||
if (pkm.Egg_Location == 30002)
|
||||
return new CheckResult(Severity.Invalid, "Egg location shouldn't be 'traded' for an un-hatched egg.", CheckIdentifier.Encounter);
|
||||
|
||||
if (pkm.Met_Location == 30002)
|
||||
return new CheckResult(Severity.Valid, "Valid traded un-hatched egg.", CheckIdentifier.Encounter);
|
||||
return pkm.Met_Location == 0
|
||||
? new CheckResult(Severity.Valid, "Valid un-hatched egg.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Invalid, "Invalid location for un-hatched egg (expected no met location).", CheckIdentifier.Encounter);
|
||||
}
|
||||
if (pkm.XY)
|
||||
{
|
||||
if (pkm.Egg_Location == 318)
|
||||
return new CheckResult(Severity.Invalid, "Invalid X/Y egg location.", CheckIdentifier.Encounter);
|
||||
return Legal.ValidMet_XY.Contains(pkm.Met_Location)
|
||||
? new CheckResult(Severity.Valid, "Valid X/Y hatched egg.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Invalid, "Invalid X/Y location for hatched egg.", CheckIdentifier.Encounter);
|
||||
}
|
||||
if (pkm.AO)
|
||||
{
|
||||
return Legal.ValidMet_AO.Contains(pkm.Met_Location)
|
||||
? new CheckResult(Severity.Valid, "Valid OR/AS hatched egg.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Invalid, "Invalid OR/AS location for hatched egg.", CheckIdentifier.Encounter);
|
||||
}
|
||||
if (pkm.SM)
|
||||
{
|
||||
return Legal.ValidMet_SM.Contains(pkm.Met_Location)
|
||||
? new CheckResult(Severity.Valid, "Valid S/M hatched egg.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Invalid, "Invalid S/M location for hatched egg.", CheckIdentifier.Encounter);
|
||||
}
|
||||
return new CheckResult(Severity.Invalid, "Invalid location for hatched egg.", CheckIdentifier.Encounter);
|
||||
}
|
||||
private CheckResult verifyEncounterSafari()
|
||||
{
|
||||
if (pkm.Species == 670 || pkm.Species == 671) // Floette
|
||||
if (!new[] {0, 1, 3}.Contains(pkm.AltForm)) // 0/1/3 - RBY
|
||||
return new CheckResult(Severity.Invalid, "Friend Safari: Not valid color.", CheckIdentifier.Encounter);
|
||||
else if (pkm.Species == 710 || pkm.Species == 711) // Pumpkaboo
|
||||
if (pkm.AltForm != 1) // Average
|
||||
return new CheckResult(Severity.Invalid, "Friend Safari: Not average sized.", CheckIdentifier.Encounter);
|
||||
else if (pkm.Species == 586) // Sawsbuck
|
||||
if (pkm.AltForm != 0)
|
||||
return new CheckResult(Severity.Invalid, "Friend Safari: Not Spring form.", CheckIdentifier.Encounter);
|
||||
|
||||
return new CheckResult(Severity.Valid, "Valid Friend Safari encounter.", CheckIdentifier.Encounter);
|
||||
}
|
||||
|
||||
private CheckResult verifyEncounterWild()
|
||||
{
|
||||
EncounterSlot[] enc = (EncounterSlot[])EncounterMatch;
|
||||
|
||||
if (enc.Any(slot => slot.Normal))
|
||||
return enc.All(slot => slot.Pressure)
|
||||
? new CheckResult(Severity.Valid, "Valid encounter at location (Pressure/Hustle/Vital Spirit).", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Valid, "Valid encounter at location.", CheckIdentifier.Encounter);
|
||||
|
||||
// Decreased Level Encounters
|
||||
if (enc.Any(slot => slot.WhiteFlute))
|
||||
return enc.All(slot => slot.Pressure)
|
||||
? new CheckResult(Severity.Valid, "Valid encounter at location (White Flute & Pressure/Hustle/Vital Spirit).", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Valid, "Valid encounter at location (White Flute).", CheckIdentifier.Encounter);
|
||||
|
||||
// Increased Level Encounters
|
||||
if (enc.Any(slot => slot.BlackFlute))
|
||||
return enc.All(slot => slot.Pressure)
|
||||
? new CheckResult(Severity.Valid, "Valid encounter at location (Black Flute & Pressure/Hustle/Vital Spirit).", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Valid, "Valid encounter at location (Black Flute).", CheckIdentifier.Encounter);
|
||||
|
||||
if (enc.Any(slot => slot.Pressure))
|
||||
return new CheckResult(Severity.Valid, "Valid encounter at location (Pressure/Hustle/Vital Spirit).", CheckIdentifier.Encounter);
|
||||
|
||||
return new CheckResult(Severity.Valid, "Valid encounter at location (DexNav).", CheckIdentifier.Encounter);
|
||||
}
|
||||
private CheckResult verifyEncounterStatic()
|
||||
{
|
||||
// Re-parse relearn moves
|
||||
var s = (EncounterStatic)EncounterMatch;
|
||||
if (s.EggLocation != 60002 || vRelearn.Any(rl => !rl.Valid))
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
vRelearn[i] = pkm.RelearnMoves[i] != s.Relearn[i]
|
||||
? new CheckResult(Severity.Invalid, "Static encounter relearn move mismatch.", CheckIdentifier.RelearnMove)
|
||||
: new CheckResult(CheckIdentifier.RelearnMove);
|
||||
return new CheckResult(Severity.Valid, "Valid gift/static encounter.", CheckIdentifier.Encounter);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private CheckResult verifyEncounter()
|
||||
{
|
||||
if (pkm.GenNumber < 6)
|
||||
return new CheckResult(Severity.NotImplemented, "Not Implemented.", CheckIdentifier.Encounter);
|
||||
|
||||
if (pkm.VC)
|
||||
if (pkm.VC || pkm.Format < 3)
|
||||
{
|
||||
int baseSpecies = Legal.getBaseSpecies(pkm);
|
||||
if ((pkm.VC1 && baseSpecies > Legal.MaxSpeciesID_1) ||
|
||||
(pkm.VC2 && baseSpecies > Legal.MaxSpeciesID_2))
|
||||
bool g1 = pkm.VC1 || pkm.Format == 1;
|
||||
|
||||
if ((g1 && baseSpecies > Legal.MaxSpeciesID_1) || (baseSpecies > Legal.MaxSpeciesID_2))
|
||||
return new CheckResult(Severity.Invalid, "VC: Unobtainable species.", CheckIdentifier.Encounter);
|
||||
|
||||
return verifyVCEncounter(baseSpecies);
|
||||
|
||||
if (pkm.Format > 2) // transported to 7+
|
||||
Parse.Add(verifyVCEncounter(baseSpecies));
|
||||
}
|
||||
|
||||
if (pkm.WasLink)
|
||||
else if (pkm.GenNumber == 4)
|
||||
{
|
||||
// Should NOT be Fateful, and should be in Database
|
||||
EncounterLink enc = EncounterMatch as EncounterLink;
|
||||
if (enc == null)
|
||||
return new CheckResult(Severity.Invalid, "Invalid Link Gift: unable to find matching gift.", CheckIdentifier.Encounter);
|
||||
|
||||
if (pkm.XY && !enc.XY)
|
||||
return new CheckResult(Severity.Invalid, "Invalid Link Gift: can't obtain in XY.", CheckIdentifier.Encounter);
|
||||
if (pkm.AO && !enc.ORAS)
|
||||
return new CheckResult(Severity.Invalid, "Invalid Link Gift: can't obtain in ORAS.", CheckIdentifier.Encounter);
|
||||
if (pkm.SM && !enc.SM)
|
||||
return new CheckResult(Severity.Invalid, "Invalid Link Gift: can't obtain in SM.", CheckIdentifier.Encounter);
|
||||
|
||||
if (enc.Shiny != null && (bool)enc.Shiny ^ pkm.IsShiny)
|
||||
return new CheckResult(Severity.Invalid, "Shiny Link gift mismatch.", CheckIdentifier.Encounter);
|
||||
|
||||
return pkm.FatefulEncounter
|
||||
? new CheckResult(Severity.Invalid, "Invalid Link Gift: should not be Fateful Encounter.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Valid, "Valid Link gift.", CheckIdentifier.Encounter);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pkm.WasLink)
|
||||
return verifyEncounterLink();
|
||||
}
|
||||
|
||||
if (pkm.WasEvent || pkm.WasEventEgg)
|
||||
{
|
||||
MysteryGift MatchedGift = EncounterMatch as MysteryGift;
|
||||
if (MatchedGift != null)
|
||||
return new CheckResult(Severity.Valid, $"Matches #{MatchedGift.CardID:0000} ({MatchedGift.CardTitle})", CheckIdentifier.Encounter);
|
||||
var result = verifyEncounterEvent();
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
|
||||
EncounterMatch = Legal.getValidStaticEncounter(pkm);
|
||||
if (EncounterMatch != null)
|
||||
{
|
||||
// Re-parse relearn moves
|
||||
var s = (EncounterStatic)EncounterMatch;
|
||||
if (s.EggLocation != 60002 || vRelearn.Any(rl => !rl.Valid))
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
vRelearn[i] = pkm.RelearnMoves[i] != s.Relearn[i]
|
||||
? new CheckResult(Severity.Invalid, "Static encounter relearn move mismatch.", CheckIdentifier.RelearnMove)
|
||||
: new CheckResult(CheckIdentifier.RelearnMove);
|
||||
return new CheckResult(Severity.Valid, "Valid gift/static encounter.", CheckIdentifier.Encounter);
|
||||
}
|
||||
var result = verifyEncounterStatic();
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
|
||||
EncounterMatch = null; // Reset object
|
||||
// Reset Encounter Object, test for remaining encounters
|
||||
EncounterMatch = null;
|
||||
if (pkm.WasEgg)
|
||||
{
|
||||
// Check Hatch Locations
|
||||
if (pkm.Met_Level != 1)
|
||||
return new CheckResult(Severity.Invalid, "Invalid met level, expected 1.", CheckIdentifier.Encounter);
|
||||
// Check species
|
||||
if (Legal.NoHatchFromEgg.Contains(pkm.Species))
|
||||
return new CheckResult(Severity.Invalid, "Species cannot be hatched from an egg.", CheckIdentifier.Encounter);
|
||||
if (pkm.IsEgg)
|
||||
{
|
||||
if (pkm.Egg_Location == 30002)
|
||||
return new CheckResult(Severity.Invalid, "Egg location shouldn't be 'traded' for an un-hatched egg.", CheckIdentifier.Encounter);
|
||||
|
||||
if (pkm.Met_Location == 30002)
|
||||
return new CheckResult(Severity.Valid, "Valid traded un-hatched egg.", CheckIdentifier.Encounter);
|
||||
return pkm.Met_Location == 0
|
||||
? new CheckResult(Severity.Valid, "Valid un-hatched egg.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Invalid, "Invalid location for un-hatched egg (expected no met location).", CheckIdentifier.Encounter);
|
||||
}
|
||||
if (pkm.XY)
|
||||
{
|
||||
if (pkm.Egg_Location == 318)
|
||||
return new CheckResult(Severity.Invalid, "Invalid X/Y egg location.", CheckIdentifier.Encounter);
|
||||
return Legal.ValidMet_XY.Contains(pkm.Met_Location)
|
||||
? new CheckResult(Severity.Valid, "Valid X/Y hatched egg.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Invalid, "Invalid X/Y location for hatched egg.", CheckIdentifier.Encounter);
|
||||
}
|
||||
if (pkm.AO)
|
||||
{
|
||||
return Legal.ValidMet_AO.Contains(pkm.Met_Location)
|
||||
? new CheckResult(Severity.Valid, "Valid OR/AS hatched egg.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Invalid, "Invalid OR/AS location for hatched egg.", CheckIdentifier.Encounter);
|
||||
}
|
||||
if (pkm.SM)
|
||||
{
|
||||
return Legal.ValidMet_SM.Contains(pkm.Met_Location)
|
||||
? new CheckResult(Severity.Valid, "Valid S/M hatched egg.", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Invalid, "Invalid S/M location for hatched egg.", CheckIdentifier.Encounter);
|
||||
}
|
||||
return new CheckResult(Severity.Invalid, "Invalid location for hatched egg.", CheckIdentifier.Encounter);
|
||||
}
|
||||
return verifyEncounterEgg();
|
||||
|
||||
EncounterMatch = Legal.getValidFriendSafari(pkm);
|
||||
if (EncounterMatch != null)
|
||||
{
|
||||
if (pkm.Species == 670 || pkm.Species == 671) // Floette
|
||||
if (!new[] {0, 1, 3}.Contains(pkm.AltForm)) // 0/1/3 - RBY
|
||||
return new CheckResult(Severity.Invalid, "Friend Safari: Not valid color.", CheckIdentifier.Encounter);
|
||||
else if (pkm.Species == 710 || pkm.Species == 711) // Pumpkaboo
|
||||
if (pkm.AltForm != 1) // Average
|
||||
return new CheckResult(Severity.Invalid, "Friend Safari: Not average sized.", CheckIdentifier.Encounter);
|
||||
else if (pkm.Species == 586) // Sawsbuck
|
||||
if (pkm.AltForm != 0)
|
||||
return new CheckResult(Severity.Invalid, "Friend Safari: Not Spring form.", CheckIdentifier.Encounter);
|
||||
|
||||
return new CheckResult(Severity.Valid, "Valid Friend Safari encounter.", CheckIdentifier.Encounter);
|
||||
}
|
||||
return verifyEncounterSafari();
|
||||
|
||||
EncounterMatch = Legal.getValidWildEncounters(pkm);
|
||||
if (EncounterMatch != null)
|
||||
{
|
||||
EncounterSlot[] enc = (EncounterSlot[])EncounterMatch;
|
||||
return verifyEncounterWild();
|
||||
|
||||
if (enc.Any(slot => slot.Normal))
|
||||
return enc.All(slot => slot.Pressure)
|
||||
? new CheckResult(Severity.Valid, "Valid encounter at location (Pressure/Hustle/Vital Spirit).", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Valid, "Valid encounter at location.", CheckIdentifier.Encounter);
|
||||
|
||||
// Decreased Level Encounters
|
||||
if (enc.Any(slot => slot.WhiteFlute))
|
||||
return enc.All(slot => slot.Pressure)
|
||||
? new CheckResult(Severity.Valid, "Valid encounter at location (White Flute & Pressure/Hustle/Vital Spirit).", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Valid, "Valid encounter at location (White Flute).", CheckIdentifier.Encounter);
|
||||
|
||||
// Increased Level Encounters
|
||||
if (enc.Any(slot => slot.BlackFlute))
|
||||
return enc.All(slot => slot.Pressure)
|
||||
? new CheckResult(Severity.Valid, "Valid encounter at location (Black Flute & Pressure/Hustle/Vital Spirit).", CheckIdentifier.Encounter)
|
||||
: new CheckResult(Severity.Valid, "Valid encounter at location (Black Flute).", CheckIdentifier.Encounter);
|
||||
|
||||
if (enc.Any(slot => slot.Pressure))
|
||||
return new CheckResult(Severity.Valid, "Valid encounter at location (Pressure/Hustle/Vital Spirit).", CheckIdentifier.Encounter);
|
||||
|
||||
return new CheckResult(Severity.Valid, "Valid encounter at location (DexNav).", CheckIdentifier.Encounter);
|
||||
}
|
||||
EncounterMatch = Legal.getValidIngameTrade(pkm);
|
||||
if (EncounterMatch != null)
|
||||
return new CheckResult(Severity.Valid, "Valid ingame trade.", CheckIdentifier.Encounter);
|
||||
|
@ -1777,9 +1816,7 @@ namespace PKHeX.Core
|
|||
CheckResult[] res = new CheckResult[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
res[i] = new CheckResult(CheckIdentifier.Move);
|
||||
if (pkm.GenNumber < 6 || pkm.VC1)
|
||||
return res;
|
||||
|
||||
|
||||
var validMoves = Legal.getValidMoves(pkm, EvoChain).ToArray();
|
||||
if (pkm.Species == 235) // Smeargle
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace PKHeX.Core
|
|||
|
||||
// Gen 1
|
||||
private static readonly Learnset[] LevelUpRB = Learnset1.getArray(Resources.lvlmove_rby);
|
||||
private static readonly Learnset[] LevelUpY = Learnset1.getArray(Resources.lvlmove_rby);
|
||||
private static readonly EvolutionTree Evolves1;
|
||||
private static readonly EncounterArea[] SlotsRBY;
|
||||
private static readonly EncounterStatic[] StaticRBY;
|
||||
|
@ -282,12 +283,15 @@ namespace PKHeX.Core
|
|||
continue;
|
||||
if (e.EggLocation != pkm.Egg_Location)
|
||||
continue;
|
||||
if (pkm.HasOriginalMetLocation && e.Location != 0 && e.Location != pkm.Met_Location)
|
||||
continue;
|
||||
if (pkm.HasOriginalMetLocation)
|
||||
{
|
||||
if (e.Location != 0 && e.Location != pkm.Met_Location)
|
||||
continue;
|
||||
if (e.Level != pkm.Met_Level)
|
||||
continue;
|
||||
}
|
||||
if (e.Gender != -1 && e.Gender != pkm.Gender)
|
||||
continue;
|
||||
if (e.Level != pkm.Met_Level)
|
||||
continue;
|
||||
if (e.Form != pkm.AltForm && !FormChange.Contains(pkm.Species) && !e.SkipFormCheck)
|
||||
continue;
|
||||
|
||||
|
@ -783,7 +787,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
if (t is int)
|
||||
return "Unknown";
|
||||
return t.GetType().Name;
|
||||
return t?.GetType().Name ?? "Unknown";
|
||||
}
|
||||
private static IEnumerable<EncounterArea> getDexNavAreas(PKM pkm)
|
||||
{
|
||||
|
@ -802,7 +806,8 @@ namespace PKHeX.Core
|
|||
List<int> moves = new List<int>();
|
||||
if (pkm.InhabitedGeneration(1))
|
||||
{
|
||||
moves.AddRange(LevelUpRB[species].getMoves(lvl));
|
||||
moves.AddRange(((PersonalInfoG1)PersonalTable.RBY[species]).Moves);
|
||||
moves.AddRange(LevelUpY[species].getMoves(lvl));
|
||||
}
|
||||
if (pkm.InhabitedGeneration(6))
|
||||
{
|
||||
|
@ -822,6 +827,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
switch ((GameVersion)pkm.Version)
|
||||
{
|
||||
case GameVersion.RBY:
|
||||
case GameVersion.RD: case GameVersion.BU:
|
||||
case GameVersion.GN: case GameVersion.YW:
|
||||
return getSlots(pkm, SlotsRBY, lvl);
|
||||
|
@ -846,6 +852,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
switch ((GameVersion)pkm.Version)
|
||||
{
|
||||
case GameVersion.RBY:
|
||||
case GameVersion.RD: case GameVersion.BU:
|
||||
case GameVersion.GN: case GameVersion.YW:
|
||||
return getStatic(pkm, StaticRBY, lvl);
|
||||
|
@ -884,18 +891,31 @@ namespace PKHeX.Core
|
|||
|
||||
// Get Valid levels
|
||||
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) || ignoreLevel);
|
||||
bool ignoreSlotLevel = ignoreLevel;
|
||||
IEnumerable<EncounterSlot> slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && (ignoreSlotLevel || evo.Level >= slot.LevelMin - df)));
|
||||
|
||||
if (pkm.Format < 3 || pkm.VC)
|
||||
return slots; // no met level or special encounter considerations
|
||||
|
||||
// Filter for Met Level
|
||||
int lvl = pkm.Met_Level;
|
||||
var encounterSlots = slots.Where(slot => slot.LevelMin - df <= lvl && lvl <= slot.LevelMax + (slot.AllowDexNav ? dn : df) || ignoreLevel).ToList();
|
||||
int gen = pkm.GenNumber;
|
||||
bool ignoreMetLevel = ignoreLevel || gen <= 4 && pkm.Format != gen;
|
||||
var encounterSlots = slots.Where(slot => ignoreMetLevel || 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 = pkm.AltForm };
|
||||
|
||||
if (gen < 4)
|
||||
{
|
||||
if (slotMax != null)
|
||||
slotdata.Add(slotMax);
|
||||
return slotdata;
|
||||
}
|
||||
if (!DexNav)
|
||||
{
|
||||
// Filter for Form Specific
|
||||
|
@ -1005,7 +1025,11 @@ namespace PKHeX.Core
|
|||
private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder)
|
||||
{
|
||||
List<int> r = new List<int> { 0 };
|
||||
for (int gen = pkm.GenNumber; gen <= pkm.Format; gen++)
|
||||
int gen = pkm.GenNumber;
|
||||
if (pkm.Format < 3)
|
||||
gen = 1;
|
||||
|
||||
for (; gen <= pkm.Format; gen++)
|
||||
r.AddRange(getMoves(pkm, species, lvl, form, moveTutor, Version, LVL, specialTutors, Machine, gen, MoveReminder));
|
||||
return r.Distinct();
|
||||
}
|
||||
|
@ -1016,6 +1040,17 @@ namespace PKHeX.Core
|
|||
var ver = Version;
|
||||
switch (Generation)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
PersonalInfo pi = PersonalTable.RBY[species];
|
||||
if (LVL)
|
||||
{
|
||||
r.AddRange(((PersonalInfoG1)PersonalTable.RBY[species]).Moves);
|
||||
r.AddRange(LevelUpRB[species].getMoves(lvl));
|
||||
}
|
||||
if (Machine) r.AddRange(TMHM_RBY.Where((t, m) => pi.TMHM[m]));
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
switch (ver)
|
||||
{
|
||||
|
|
|
@ -45,7 +45,67 @@ namespace PKHeX.Core
|
|||
|
||||
internal static readonly EncounterStatic[] Encounter_RBY =
|
||||
{
|
||||
// todo
|
||||
new EncounterStatic { Species = 001, Level = 05 }, // Bulbasaur
|
||||
new EncounterStatic { Species = 004, Level = 05 }, // Charmander
|
||||
new EncounterStatic { Species = 007, Level = 05 }, // Squirtle
|
||||
new EncounterStatic { Species = 025, Level = 05 }, // Pikachu
|
||||
|
||||
// Red Game Corner
|
||||
new EncounterStatic { Species = 063, Level = 09 }, // Abra
|
||||
new EncounterStatic { Species = 025, Level = 08 }, // Clefairy
|
||||
new EncounterStatic { Species = 025, Level = 17 }, // Nidorina
|
||||
new EncounterStatic { Species = 147, Level = 18 }, // Dratini
|
||||
new EncounterStatic { Species = 123, Level = 25 }, // Scyther
|
||||
new EncounterStatic { Species = 137, Level = 26 }, // Porygon
|
||||
|
||||
// Blue(EN) / Green(JP) Game Corner
|
||||
new EncounterStatic { Species = 063, Level = 06 }, // Abra
|
||||
new EncounterStatic { Species = 035, Level = 12 }, // Clefairy
|
||||
new EncounterStatic { Species = 030, Level = 17 }, // Nidorina
|
||||
new EncounterStatic { Species = 127, Level = 20 }, // Pinsir
|
||||
new EncounterStatic { Species = 147, Level = 24 }, // Dratini
|
||||
new EncounterStatic { Species = 137, Level = 18 }, // Porygon
|
||||
|
||||
// Blue(JP) Game Corner
|
||||
new EncounterStatic { Species = 063, Level = 08 }, // Abra
|
||||
new EncounterStatic { Species = 025, Level = 12 }, // Pikachu
|
||||
new EncounterStatic { Species = 116, Level = 18 }, // Horsea
|
||||
new EncounterStatic { Species = 036, Level = 24 }, // Clefable
|
||||
new EncounterStatic { Species = 148, Level = 30 }, // Dragonair
|
||||
new EncounterStatic { Species = 137, Level = 22 }, // Porygon
|
||||
|
||||
// Yellow Game Corner
|
||||
new EncounterStatic { Species = 063, Level = 15 }, // Abra
|
||||
new EncounterStatic { Species = 025, Level = 18 }, // Vulpix
|
||||
new EncounterStatic { Species = 025, Level = 22 }, // Wigglytuff
|
||||
new EncounterStatic { Species = 123, Level = 30 }, // Scyther
|
||||
new EncounterStatic { Species = 127, Level = 30 }, // Pinsir
|
||||
new EncounterStatic { Species = 137, Level = 26 }, // Porygon
|
||||
|
||||
new EncounterStatic { Species = 129, Level = 05 }, // Magikarp
|
||||
new EncounterStatic { Species = 143, Level = 30 }, // Snorlax
|
||||
new EncounterStatic { Species = 106, Level = 30 }, // Hitmonlee
|
||||
new EncounterStatic { Species = 107, Level = 30 }, // Hitmonchan
|
||||
|
||||
new EncounterStatic { Species = 131, Level = 15 }, // Lapras
|
||||
new EncounterStatic { Species = 138, Level = 30 }, // Omanyte
|
||||
new EncounterStatic { Species = 140, Level = 30 }, // Kabuto
|
||||
new EncounterStatic { Species = 142, Level = 30 }, // Aerodactyl
|
||||
|
||||
|
||||
new EncounterStatic { Species = 144, Level = 50 }, // Articuno
|
||||
new EncounterStatic { Species = 145, Level = 50 }, // Zapdos
|
||||
new EncounterStatic { Species = 146, Level = 50 }, // Moltres
|
||||
|
||||
new EncounterStatic { Species = 150, Level = 70 }, // Mewtwo
|
||||
|
||||
new EncounterStatic { Species = 133, Level = 25 }, // Eevee
|
||||
|
||||
// Yellow Only
|
||||
new EncounterStatic { Species = 133, Level = 25 }, // Eevee (Celadon City)
|
||||
new EncounterStatic { Species = 001, Level = 10 }, // Bulbasaur (Cerulean City)
|
||||
new EncounterStatic { Species = 004, Level = 10 }, // Charmander (Route 24)
|
||||
new EncounterStatic { Species = 007, Level = 10 }, // Squirtle (Vermillion City)
|
||||
};
|
||||
internal static readonly EncounterTrade[] TradeGift_RBY =
|
||||
{
|
||||
|
|
|
@ -259,7 +259,7 @@ namespace PKHeX.Core
|
|||
public override int OT_Friendship { get { return 0; } set { } }
|
||||
public override int OT_Gender { get { return 0; } set { } }
|
||||
public override int Ball { get { return 0; } set { } }
|
||||
public override int Version { get { return 0; } set { } }
|
||||
public override int Version { get { return (int)GameVersion.RBY; } set { } }
|
||||
public override int SID { get { return 0; } set { } }
|
||||
public override int PKRS_Strain { get { return 0; } set { } }
|
||||
public override int PKRS_Days { get { return 0; } set { } }
|
||||
|
|
|
@ -327,7 +327,7 @@ namespace PKHeX.Core
|
|||
public override int Egg_Location { get { return 0; } set { } }
|
||||
public override int OT_Friendship { get { return 0; } set { } }
|
||||
public override int Ball { get { return 0; } set { } }
|
||||
public override int Version { get { return 0; } set { } }
|
||||
public override int Version { get { return (int)GameVersion.GSC; } set { } }
|
||||
public override int SID { get { return 0; } set { } }
|
||||
public override int CNT_Cool { get { return 0; } set { } }
|
||||
public override int CNT_Beauty { get { return 0; } set { } }
|
||||
|
|
|
@ -275,7 +275,9 @@ namespace PKHeX.Core
|
|||
public bool Gen5 => Version >= 20 && Version <= 23;
|
||||
public bool Gen4 => Version >= 7 && Version <= 12 && Version != 9;
|
||||
public bool Gen3 => Version >= 1 && Version <= 5 || Version == 15;
|
||||
public bool GenU => !(Gen7 || Gen6 || Gen5 || Gen4 || Gen3);
|
||||
public bool Gen2 => Version == (int)GameVersion.GSC;
|
||||
public bool Gen1 => Version == (int)GameVersion.RBY;
|
||||
public bool GenU => !(Gen7 || Gen6 || Gen5 || Gen4 || Gen3 || Gen2 || Gen1);
|
||||
public int GenNumber
|
||||
{
|
||||
get
|
||||
|
@ -286,6 +288,8 @@ namespace PKHeX.Core
|
|||
if (Gen5) return 5;
|
||||
if (Gen4) return 4;
|
||||
if (Gen3) return 3;
|
||||
if (Gen2) return Format; // 2
|
||||
if (Gen1) return Format; // 1
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -405,14 +409,17 @@ namespace PKHeX.Core
|
|||
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) && GenNumber == Format;
|
||||
public virtual bool IsUntraded => Format >= 6 && string.IsNullOrWhiteSpace(HT_Name) && GenNumber == Format;
|
||||
public virtual bool IsNative => GenNumber == Format;
|
||||
public virtual bool IsOriginValid()
|
||||
{
|
||||
switch (GenNumber)
|
||||
switch (Format)
|
||||
{
|
||||
case 1: return Species <= Legal.MaxSpeciesID_1;
|
||||
case 2: return Species <= Legal.MaxSpeciesID_2;
|
||||
}
|
||||
switch (GenNumber)
|
||||
{
|
||||
case 3: return Species <= Legal.MaxSpeciesID_3;
|
||||
case 4: return Species <= Legal.MaxSpeciesID_4;
|
||||
case 5: return Species <= Legal.MaxSpeciesID_5;
|
||||
|
@ -482,7 +489,7 @@ namespace PKHeX.Core
|
|||
/// Checks if the PKM has its original met location.
|
||||
/// </summary>
|
||||
/// <returns>Returns false if the Met Location has been overwritten via generational transfer.</returns>
|
||||
public bool HasOriginalMetLocation => !(GenNumber <= 4 && Format > 4 || VC);
|
||||
public bool HasOriginalMetLocation => !(Format < 3 || VC || GenNumber <= 4 && Format != GenNumber);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current <see cref="Gender"/> is valid.
|
||||
|
|
|
@ -40,11 +40,11 @@ namespace PKHeX.Core
|
|||
}
|
||||
public override int CatchRate { get { return Data[0x08]; } set { Data[0x08] = (byte)value; } }
|
||||
public override int BaseEXP { get { return Data[0x09]; } set { Data[0x09] = (byte)value; } }
|
||||
public int Move1 { get { return Data[0x0A]; } set { Data[0x0A] = (byte)value; } }
|
||||
public int Move2 { get { return Data[0x0B]; } set { Data[0x0B] = (byte)value; } }
|
||||
public int Move3 { get { return Data[0x0C]; } set { Data[0x0C] = (byte)value; } }
|
||||
public int Move4 { get { return Data[0x0D]; } set { Data[0x0D] = (byte)value; } }
|
||||
public override int EXPGrowth { get { return Data[0x13]; } set { Data[0x13] = (byte)value; } }
|
||||
public int Move1 { get { return Data[0x0F]; } set { Data[0x0F] = (byte)value; } }
|
||||
public int Move2 { get { return Data[0x10]; } set { Data[0x10] = (byte)value; } }
|
||||
public int Move3 { get { return Data[0x12]; } set { Data[0x12] = (byte)value; } }
|
||||
public int Move4 { get { return Data[0x13]; } set { Data[0x13] = (byte)value; } }
|
||||
public override int EXPGrowth { get { return Data[0x14]; } set { Data[0x14] = (byte)value; } }
|
||||
|
||||
// EV Yields are just aliases for base stats in Gen I
|
||||
public override int EV_HP { get { return HP; } set { } }
|
||||
|
@ -64,5 +64,11 @@ namespace PKHeX.Core
|
|||
public override int BaseFriendship { get { return 0; } set { } }
|
||||
public override int EscapeRate { get { return 0; } set { } }
|
||||
public override int Color { get { return 0; } set { } }
|
||||
|
||||
public int[] Moves
|
||||
{
|
||||
get { return new[] { Move1, Move2, Move3, Move4 }; }
|
||||
set { if (value?.Length != 4) return; Move1 = value[0]; Move2 = value[1]; Move3 = value[2]; Move4 = value[3]; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue