mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-05-06 05:27:14 -05: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
|
|
@ -2837,7 +2837,9 @@ private void showLegality(PKM pk, bool tabs, bool verbose, bool skipMoveRepop =
|
|||
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 @@ private void showLegality(PKM pk, bool tabs, bool verbose, bool skipMoveRepop =
|
|||
}
|
||||
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 @@ public LegalityAnalysis(PKM pk)
|
|||
|
||||
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 @@ public LegalityAnalysis(PKM pk)
|
|||
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 @@ private void AddLine(CheckResult chk)
|
|||
{
|
||||
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 @@ private void updateEncounterChain()
|
|||
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 @@ private string getLegalityReport()
|
|||
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 @@ private string getVerboseLegalityReport()
|
|||
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 @@ public int[] getSuggestedRelearn()
|
|||
}
|
||||
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 @@ private void verifyNickname()
|
|||
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 @@ private void verifyNickname()
|
|||
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 @@ private void verifyIVs()
|
|||
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 @@ private void verifyOT()
|
|||
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 @@ private void verifyHyperTraining()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ private CheckResult[] verifyMoves()
|
|||
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 @@ public static partial class Legal
|
|||
|
||||
// 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 @@ internal static EncounterStatic getValidStaticEncounter(PKM pkm)
|
|||
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 @@ internal static string getEncounterTypeName(PKM pkm, object Encounter)
|
|||
}
|
||||
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 @@ private static IEnumerable<int> getLVLMoves(PKM pkm, int species, int lvl, int f
|
|||
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 @@ private static IEnumerable<EncounterArea> getEncounterSlots(PKM pkm, int lvl = -
|
|||
{
|
||||
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 @@ private static IEnumerable<EncounterStatic> getStaticEncounters(PKM pkm, int lvl
|
|||
{
|
||||
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 @@ private static IEnumerable<EncounterSlot> getValidEncounterSlots(PKM pkm, Encoun
|
|||
|
||||
// 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 @@ private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, IEnu
|
|||
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 @@ private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form
|
|||
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 @@ public static partial class Legal
|
|||
|
||||
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 @@ public override bool CanHoldItem(ushort[] ValidArray)
|
|||
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 @@ public override int HPType
|
|||
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 @@ public byte[] Write()
|
|||
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 @@ public int GenNumber
|
|||
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 @@ public virtual int HPType
|
|||
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 @@ public bool InhabitedGeneration(int Generation)
|
|||
/// 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 @@ public override int[] Types
|
|||
}
|
||||
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 @@ public override int[] Types
|
|||
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 New Issue
Block a user