Encounter Type fix and detection of pokemon that should have evolve on trade (#1105)

* Detect encounter trades that evolve on trade and have not been evolved
Detect generation 1 pokemon with special catch rates : krabby trade and Pokemon Stadium
Detect generation 1 pokemon that evolve on trade and have been traded but not evolved
Detect pokemon with tradeback status any but with only encounters from the other GB generation, that means they are WasTradeback
Detect pokemon with moves from the other GB generation, change tradebackstatus to WasTradeback

* Fix dppt surfing and fishing encounter type, is is surfing because the battle background is the same as other surfingfishing encounters

Fix headbutt encounter type, the encounter type depends on the battle background used when battle a pokemon, for headbutt it changes with the player tile, is the player is in a city it will be building encounter, in a grass tile tall grass, in water it is surfingfishing and cave inside a cave. Some locations have more than one possible encounter type, for example routes with trees near the grass, near the water and near non-combat tiles.

Also added slot type headbutt special for the special trees, those trees are all in routes and are only adjacent to non-combat tiles

* Fix encounter type for missing areas with multiple grass encounters types: Mt Coronet, Mt Silver Cave and Stark Mountain (Issue # 1095)

* Fixes and typos

* Check for non-japanese e-reader pokemon, is unreleased
This commit is contained in:
javierhimura
2017-05-01 17:07:20 +02:00
committed by Kurt
parent ad6a48b7f1
commit 758adf2cff
17 changed files with 451 additions and 79 deletions

View File

@@ -954,6 +954,18 @@ private static SAV3GCMemoryCard CheckGCMemoryCard(byte[] Data, string path)
return MC;
}
private void StoreLegalSaveGameData(SaveFile sav)
{
Legal.SavegameJapanese = sav.Japanese;
Legal.EReaderBerryIsEnigma = sav.eBerryIsEnigma;
Legal.EReaderBerryName = sav.eBerryName;
Legal.Savegame_Gender = sav.Gender;
Legal.Savegame_TID = sav.TID;
Legal.Savegame_SID = sav.SID;
Legal.Savegame_OT = sav.OT;
Legal.Savegame_Version = sav.Version;
}
private void openSAV(SaveFile sav, string path)
{
if (sav == null || sav.Version == GameVersion.Invalid)
@@ -1033,9 +1045,7 @@ private void openSAV(SaveFile sav, string path)
sav.Japanese = drJP == DialogResult.No;
}
Legal.SavegameJapanese = sav.Japanese;
Legal.EReaderBerryIsEnigma = sav.eBerryIsEnigma;
Legal.EReaderBerryName = sav.eBerryName;
StoreLegalSaveGameData(sav);
loadingSAV = true;
// clean fields

View File

@@ -236,8 +236,10 @@ private void updateTradebackG12()
// Dragonite's Catch Rate is different than Dragonair's in Yellow, but there is no Dragonite encounter.
var RGBCatchRate = Lineage.Any(s => catch_rate == PersonalTable.RB[s].CatchRate);
var YCatchRate = Lineage.Any(s => s != 149 && catch_rate == PersonalTable.Y[s].CatchRate);
bool matchAny = RGBCatchRate || YCatchRate;
// Krabby encounter trade special catch rate
var TradeCatchRate = ((pkm.Species == 098 || pkm.Species == 099) && catch_rate == 204);
var StadiumCatchRate = Legal.Stadium_GiftSpecies.Contains(pkm.Species) && Legal.Stadium_CatchRate.Contains(catch_rate);
bool matchAny = RGBCatchRate || YCatchRate || TradeCatchRate || StadiumCatchRate;
// If the catch rate value has been modified, the item has either been removed or swapped in Generation 2.
var HeldItemCatchRate = catch_rate == 0 || Legal.HeldItems_GSC.Any(h => h == catch_rate);
@@ -250,7 +252,7 @@ private void updateTradebackG12()
// Update the editing settings for the PKM to acknowledge the tradeback status if the species is changed.
((PK1)pkm).CatchRateIsItem = !pkm.Gen1_NotTradeback && HeldItemCatchRate && matchAny;
((PK1)pkm).CatchRateIsItem = !pkm.Gen1_NotTradeback && HeldItemCatchRate && !matchAny;
}
else if (pkm.Format == 2 || pkm.VC2)
{
@@ -276,7 +278,11 @@ private void updateTypeInfo()
if (pkm.VC && pkm.Format == 7)
EncounterMatch = Legal.getRBYStaticTransfer(pkm.Species);
MatchedType = Type = (EncounterOriginalGB ?? EncounterMatch ?? pkm.Species).GetType();
if (pkm.GenNumber <= 2 && pkm.TradebackStatus == TradebackType.Any && EncountersGBMatch.All(e => e.Generation != pkm.GenNumber))
// Example: GSC Pokemon with only possible encounters in RBY, like the legendary birds
pkm.TradebackStatus = TradebackType.WasTradeback;
MatchedType = Type = (EncounterOriginalGB ?? EncounterMatch ?? pkm.Species)?.GetType();
var bt = Type.BaseType;
if (bt != null && !(bt == typeof(Array) || bt == typeof(object) || bt.IsPrimitive)) // a parent exists
Type = bt; // use base type

View File

@@ -500,6 +500,15 @@ private void verifyG1OT()
if (tr != "GF" && tr != "ゲーフリ") // if there are more events with special OTs, may be worth refactoring
AddLine(Severity.Invalid, V39, CheckIdentifier.Trainer);
}
if((EncounterMatch as EncounterStatic)?.Version == GameVersion.Stadium)
{
if(tr == "STADIUM" && pkm.TID == 2000)
AddLine(Severity.Valid, V403, CheckIdentifier.Trainer);
else if (tr == "スタジアム" && pkm.TID == 1999)
AddLine(Severity.Valid, V404, CheckIdentifier.Trainer);
else
AddLine(Severity.Invalid, V402, CheckIdentifier.Trainer);
}
}
#endregion
private void verifyHyperTraining()
@@ -739,6 +748,8 @@ private CheckResult verifyEncounterStatic()
switch (pkm.GenNumber)
{
case 3:
if ((( EncounterMatch as EncounterStaticShadow)?.EReader ?? false) && pkm.Language != 1) // Non-JP E-reader Pokemon
return new CheckResult(Severity.Invalid, V406, CheckIdentifier.Encounter);
if (pkm.Species == 151 && s.Location == 201 && pkm.Language != 1) // Non-JP Mew (Old Sea Map)
return new CheckResult(Severity.Invalid, V353, CheckIdentifier.Encounter);
break;
@@ -769,6 +780,16 @@ private CheckResult verifyEncounterStatic()
}
private CheckResult verifyEncounterTrade()
{
var trade = (EncounterTrade)EncounterMatch;
if (trade.Species == pkm.Species && trade.EvolveOnTrade)
{
// Pokemon that evolve on trade can not be in the phase evolution after the trade
// If the trade holds an everstone EvolveOnTrade will be false for the encounter
var species = specieslist;
var unevolved = species[pkm.Species];
var evolved = species[pkm.Species + 1];
return new CheckResult(Severity.Invalid, string.Format(V401, unevolved, evolved), CheckIdentifier.Encounter);
}
return new CheckResult(Severity.Valid, V76, CheckIdentifier.Encounter);
}
private CheckResult verifyEncounterG12()
@@ -782,7 +803,7 @@ private CheckResult verifyEncounterG12()
pkm.WasEgg = true;
return verifyEncounterEgg();
}
EncounterMatch = EncounterOriginalGB = EncountersGBMatch.FirstOrDefault()?.Encounter;
EncounterMatch = EncounterOriginalGB = EncountersGBMatch?.FirstOrDefault()?.Encounter;
if (EncounterMatch is EncounterSlot)
return new CheckResult(Severity.Valid, V68, CheckIdentifier.Encounter);
if (EncounterMatch is EncounterStatic)
@@ -831,14 +852,8 @@ private void verifyEncounterType()
if (EncounterMatch is EncounterStaticTyped)
type = ((EncounterStaticTyped)EncounterMatch).TypeEncounter;
}
if (type == EncounterType.Any)
{
// Temp analysis until all generation 4 static encounters have defined their encounter type values
AddLine(Severity.NotImplemented, V382, CheckIdentifier.Encounter);
return;
}
if (type != (EncounterType)pkm.EncounterType)
if (!type.Contains(pkm.EncounterType))
AddLine(Severity.Invalid, V381, CheckIdentifier.Encounter);
else
AddLine(Severity.Valid, V380, CheckIdentifier.Encounter);
@@ -1126,6 +1141,20 @@ private void verifyLevel()
AddLine(Severity.Fishy, V87, CheckIdentifier.Level);
else
AddLine(Severity.Valid, V88, CheckIdentifier.Level);
// Machoke, Graveler, Haunter and Kadabra captured in the second phase evolution, exclude in-game trade, is already checked
if (Type != typeof(EncounterTrade) && pkm.Format <=2 && EncounterSpecies == pkm.Species && Legal.Trade_Evolution1.Contains(EncounterSpecies))
{
var mustevolve = pkm.TradebackStatus == TradebackType.WasTradeback || (pkm.Format == 1 && Legal.IsOutsider(pkm));
if (mustevolve)
{
// Pokemon have been traded but it is not evolved
var species = specieslist;
var unevolved = species[pkm.Species];
var evolved = species[pkm.Species + 1];
AddLine(Severity.Invalid, string.Format(V405, unevolved, evolved), CheckIdentifier.Level);
}
}
}
#region verifyMedals
private void verifyMedals()
@@ -2413,6 +2442,9 @@ private void verifyMiscG1()
goto case TradebackType.Gen1_NotTradeback;
break;
case TradebackType.Gen1_NotTradeback:
if ((EncounterMatch as EncounterStatic)?.Version == GameVersion.Stadium || EncounterMatch as EncounterTradeCatchRate != null)
// Encounters detected by the catch rate, cant be invalid if match this encounters
{ AddLine(Severity.Valid, V398, CheckIdentifier.Misc); }
if ( ((pkm.Species == 149) && (catch_rate == PersonalTable.Y[149].CatchRate)) ||
(Legal.Species_NotAvailable_CatchRate.Contains(pkm.Species) && (catch_rate == PersonalTable.RB[pkm.Species].CatchRate)))
{ AddLine(Severity.Invalid, V396, CheckIdentifier.Misc); }
@@ -2589,9 +2621,16 @@ private List<object> GetEncounterMovesGBEra()
if (pkm.WasEgg)
encounters.Add(null);
if (EncountersGBMatch != null)
// Add non egg encounters, start with generation 2
// generation 1 will change valid gen 1 lvl moves for every encounter
encounters.AddRange(EncountersGBMatch.Where(t => t.Type != GBEncounterType.EggEncounter).OrderByDescending(t => t.Generation).Select(e => e.Encounter));
{
if (EncountersGBMatch.First().Generation == 1)
// If the first encounter if from generation 1 that means encounter from generation 2 will not return any valid move that is not valid in gen1 encounter
// but it is needed to determine if pokemon could be from only one generation to check tradeback status
encounters.Add(EncountersGBMatch.First().Encounter);
else
// Add non egg encounters, start with generation 2
// generation 1 will change valid gen 1 lvl moves for every encounter
encounters.AddRange(EncountersGBMatch.Where(t => t.Type != GBEncounterType.EggEncounter).Select(e => e.Encounter));
}
return encounters;
}
private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any)
@@ -2694,6 +2733,7 @@ private CheckResult[] parseMovesForEncounters(GameVersion game, int[] Moves)
var EncounterMatchGen = EncounterMatch as IGeneration;
var defaultG1LevelMoves = EncounterMoves.validLevelUpMoves[1];
var defaultTradeback = pkm.TradebackStatus;
if (EncounterMatchGen != null)
// Generation 1 can have different minimum level in different encounter of the same species; update valid level moves
UptateGen1LevelUpMoves(EncounterMoves, EncounterMoves.minLvlG1, EncounterMatchGen.Generation);
@@ -2707,6 +2747,7 @@ private CheckResult[] parseMovesForEncounters(GameVersion game, int[] Moves)
if (EncounterMatchGen?.Generation == 1) // not valid, restore generation 1 moves
EncounterMoves.validLevelUpMoves[1] = defaultG1LevelMoves;
pkm.TradebackStatus = defaultTradeback;
}
return res;
}
@@ -3052,6 +3093,8 @@ private CheckResult[] parseMoves(int[] moves, List<int>[] learn, int[] relearn,
IncenseMovesLearned.Add(m);
if (res[m].Valid && gen == 1)
Gen1MovesLearned.Add(m);
if (res[m].Valid && gen <= 2 && pkm.TradebackStatus == TradebackType.Any && pkm.GenNumber != gen)
pkm.TradebackStatus = TradebackType.WasTradeback;
}
if (gen == generations.Last())
@@ -3075,6 +3118,8 @@ private CheckResult[] parseMoves(int[] moves, List<int>[] learn, int[] relearn,
else
res[m] = new CheckResult(Severity.Valid, V345, CheckIdentifier.Move);
LvlupEggMovesLearned.Add(m);
if (pkm.TradebackStatus == TradebackType.Any && pkm.GenNumber == 1)
pkm.TradebackStatus = TradebackType.WasTradeback;
if (issplitbreed)
{
// Only add to split breed lists learned moves that can be from one of the egg species, ignore common moves
@@ -3106,6 +3151,8 @@ private CheckResult[] parseMoves(int[] moves, List<int>[] learn, int[] relearn,
else
res[m] = new CheckResult(Severity.Valid, V171, CheckIdentifier.Move) { Flag = true };
EggMovesLearned.Add(m);
if (pkm.TradebackStatus == TradebackType.Any && pkm.GenNumber == 1)
pkm.TradebackStatus = TradebackType.WasTradeback;
if (issplitbreed)
{
// Only add to split breed lists egg moves that can be from one of the egg species, ignore common moves
@@ -3128,6 +3175,8 @@ private CheckResult[] parseMoves(int[] moves, List<int>[] learn, int[] relearn,
else
res[m] = new CheckResult(Severity.Valid, V333, CheckIdentifier.Move) { Flag = true };
}
if (pkm.TradebackStatus == TradebackType.Any && pkm.GenNumber == 1)
pkm.TradebackStatus = TradebackType.WasTradeback;
EventEggMovesLearned.Add(m);
}

View File

@@ -21,6 +21,11 @@ public static partial class Legal
public static string EReaderBerryName = string.Empty;
public static string EReaderBerryDisplayName => string.Format(V372, CultureInfo.CurrentCulture.TextInfo.ToTitleCase(EReaderBerryName.ToLower()));
public static bool SavegameJapanese = false;
public static string Savegame_OT = string.Empty;
public static int Savegame_TID = 0;
public static int Savegame_SID = 0;
public static int Savegame_Gender = 0;
public static GameVersion Savegame_Version = GameVersion.Any;
// Gen 1
private static readonly Learnset[] LevelUpRB = Learnset1.getArray(Resources.lvlmove_rb, MaxSpeciesID_1);
@@ -316,17 +321,17 @@ private static EncounterType GetEncounterTypeBySlotDPPt( SlotType Type, Encounte
case SlotType.Surf:
case SlotType.Old_Rod:
case SlotType.Good_Rod:
case SlotType.Super_Rod: return EncounterType.Surfing_Fishing;
case SlotType.Grass_Safari:
case SlotType.Super_Rod:
case SlotType.Surf_Safari:
case SlotType.Old_Rod_Safari:
case SlotType.Good_Rod_Safari:
case SlotType.Super_Rod_Safari: return EncounterType.MarshSafari;
case SlotType.Super_Rod_Safari: return EncounterType.Surfing_Fishing;
case SlotType.Grass_Safari: return EncounterType.MarshSafari;
case SlotType.HoneyTree: return EncounterType.None;
}
return EncounterType.None;
}
private static EncounterType GetEncounterTypeBySlotHGSS(SlotType Type, EncounterType GrassType)
private static EncounterType GetEncounterTypeBySlotHGSS(SlotType Type, EncounterType GrassType, EncounterType HeadbuttType)
{
switch (Type)
{
@@ -344,41 +349,66 @@ private static EncounterType GetEncounterTypeBySlotHGSS(SlotType Type, Encounter
case SlotType.Super_Rod_Safari: return EncounterType.Surfing_Fishing;
case SlotType.Rock_Smash:
case SlotType.Rock_Smash_Safari: return EncounterType.RockSmash;
case SlotType.Headbutt: return EncounterType.None;
case SlotType.Headbutt: return HeadbuttType;
case SlotType.Headbutt_Special: return EncounterType.None;
}
return EncounterType.None;
}
private static void MarkDPPtEncounterTypeSlots_Route209(ref EncounterArea[] Areas)
private static void MarkDPPtEncounterTypeSlots_MultipleTypes(ref EncounterArea[] Areas, int Location, int SpecialEncounterFile, EncounterType NormalEncounterType)
{
// Route 209 have two different encounter type for grass encounters
// The first area with location 24 is the proper Route 209 with tall grass encounters
// The other areas with the same location in the raw file is the lost tower, all encounters inside the tower are buildiing encounter
bool FirstArea = true;
foreach (EncounterArea Area in Areas.Where(x => x.Location == 24))
// Area with two different encounter type for grass encounters
// SpecialEncounterFile is tall grass encounter type, the other files have the normal encounter type for this location
var numfile = 0;
foreach (EncounterArea Area in Areas.Where(x => x.Location == Location))
{
var GrassType = FirstArea ? EncounterType.TallGrass : EncounterType.Building_EnigmaStone;
if (FirstArea)
FirstArea = false;
numfile++;
var GrassType = numfile == SpecialEncounterFile ? EncounterType.TallGrass : NormalEncounterType;
foreach (EncounterSlot Slot in Area.Slots)
{
Slot.TypeEncounter = GetEncounterTypeBySlotDPPt(Slot.Type, GrassType);
}
}
}
private static void MarkHGSSEncounterTypeSlots_RuinsofAlph(ref EncounterArea[] Areas)
private static void MarkDPPtEncounterTypeSlots_MultipleTypes(ref EncounterArea[] Areas, int Location, int[] SpecialEncounterFiles, EncounterType NormalEncounterType)
{
// Ruins of Alph have two different encounter type for grass encounters
// The first area with location 209 is the outside area of the ruins with tall grass encounters
// The other areas with the same location in the raw file is the inside of the ruins, all encounters inside are cave encounters
bool FirstArea = true;
foreach (EncounterArea Area in Areas.Where(x => x.Location == 209))
var numfile = 0;
foreach (EncounterArea Area in Areas.Where(x => x.Location == Location))
{
var GrassType = FirstArea ? EncounterType.TallGrass : EncounterType.Cave_HallOfOrigin;
if (FirstArea)
FirstArea = false;
numfile++;
var GrassType = SpecialEncounterFiles.Contains(numfile) ? EncounterType.TallGrass : NormalEncounterType;
foreach (EncounterSlot Slot in Area.Slots)
{
Slot.TypeEncounter = GetEncounterTypeBySlotHGSS(Slot.Type, GrassType);
Slot.TypeEncounter = GetEncounterTypeBySlotDPPt(Slot.Type, GrassType);
}
}
}
private static void MarkHGSSEncounterTypeSlots_MultipleTypes(ref EncounterArea[] Areas, int Location, int SpecialEncounterFile, EncounterType NormalEncounterType)
{
// Area with two different encounter type for grass encounters
// SpecialEncounterFile is taall grass encounter type, the other files have the normal encounter type for this location
var HeadbuttType = getHeadbuttEncounter(Location);
var numfile = 0;
foreach (EncounterArea Area in Areas.Where(x => x.Location == Location))
{
numfile++;
var GrassType = numfile == SpecialEncounterFile ? EncounterType.TallGrass : NormalEncounterType;
foreach (EncounterSlot Slot in Area.Slots)
{
Slot.TypeEncounter = GetEncounterTypeBySlotHGSS(Slot.Type, GrassType, HeadbuttType);
}
}
}
private static void MarkHGSSEncounterTypeSlots_MultipleTypes(ref EncounterArea[] Areas, int Location, int[] SpecialEncounterFiles, EncounterType NormalEncounterType)
{
var HeadbuttType = getHeadbuttEncounter(Location);
var numfile = 0;
foreach (EncounterArea Area in Areas.Where(x => x.Location == Location))
{
numfile++;
var GrassType = SpecialEncounterFiles.Contains(numfile) ? EncounterType.TallGrass : NormalEncounterType;
foreach (EncounterSlot Slot in Area.Slots)
{
Slot.TypeEncounter = GetEncounterTypeBySlotHGSS(Slot.Type, GrassType, HeadbuttType);
}
}
}
@@ -386,7 +416,7 @@ private static void MarkDPPtEncounterTypeSlots(ref EncounterArea[] Areas)
{
foreach(EncounterArea Area in Areas)
{
if (Area.Location == 24)
if (DPPt_MixInteriorExteriorLocations.Contains(Area.Location))
continue;
var GrassType = (Area.Location == 70) ? EncounterType.Building_EnigmaStone :// Old Chateau
DPPt_CaveLocations.Contains(Area.Location) ? EncounterType.Cave_HallOfOrigin :
@@ -397,16 +427,40 @@ private static void MarkDPPtEncounterTypeSlots(ref EncounterArea[] Areas)
}
}
}
private static EncounterType getHeadbuttEncounter(int Location)
{
// Routes with trees adjacent to water tiles
var allowsurf= HGSS_SurfingHeadbutt_Locations.Contains(Location);
// Cities
if (HGSS_CityLocations.Contains(Location))
{
return allowsurf ? EncounterType.Headbutt_CitySurf : EncounterType.Building_EnigmaStone;
}
// Caves with no exterior zones
if (!HGSS_MixInteriorExteriorLocations.Contains(Location) && HGSS_CaveLocations.Contains(Location))
{
return allowsurf ? EncounterType.Headbutt_CaveSurf : EncounterType.Cave_HallOfOrigin;
}
// Routes and exterior areas
// Routes with trees adjacent to grass tiles
var allowgrass = HGSS_GrassHeadbutt_Locations.Contains(Location);
return allowgrass && allowsurf ? EncounterType.Headbutt_GrassSurf :
allowgrass ? EncounterType.Headbutt_Grass :
allowsurf ? EncounterType.Headbutt_Surf :
EncounterType.None;
}
private static void MarkHGSSEncounterTypeSlots(ref EncounterArea[] Areas)
{
foreach (EncounterArea Area in Areas)
{
if (Area.Location == 209)
if (HGSS_MixInteriorExteriorLocations.Contains(Area.Location))
continue;
var GrassType = HGSS_CaveLocations.Contains(Area.Location) ? EncounterType.Cave_HallOfOrigin: EncounterType.TallGrass;
var HeadbuttType = getHeadbuttEncounter(Area.Location);
foreach (EncounterSlot Slot in Area.Slots)
{
Slot.TypeEncounter = GetEncounterTypeBySlotHGSS(Slot.Type, GrassType);
Slot.TypeEncounter = GetEncounterTypeBySlotHGSS(Slot.Type, GrassType, HeadbuttType);
}
}
}
@@ -655,11 +709,26 @@ private static EncounterArea[] getTables2(GameVersion Version)
MarkG4AltFormSlots(ref Pt_Slots, 422, 1, Shellos_EastSeaLocation_Pt);
MarkG4AltFormSlots(ref Pt_Slots, 423, 1, Gastrodon_EastSeaLocation_Pt);
MarkDPPtEncounterTypeSlots_Route209(ref D_Slots);
MarkDPPtEncounterTypeSlots_Route209(ref P_Slots);
MarkDPPtEncounterTypeSlots_Route209(ref Pt_Slots);
MarkHGSSEncounterTypeSlots_RuinsofAlph(ref HG_Slots);
MarkHGSSEncounterTypeSlots_RuinsofAlph(ref SS_Slots);
// Route 209
MarkDPPtEncounterTypeSlots_MultipleTypes(ref D_Slots, 24, 1, EncounterType.Building_EnigmaStone);
MarkDPPtEncounterTypeSlots_MultipleTypes(ref P_Slots, 24, 1, EncounterType.Building_EnigmaStone);
MarkDPPtEncounterTypeSlots_MultipleTypes(ref Pt_Slots, 24, 1, EncounterType.Building_EnigmaStone);
// Stark Mountain
MarkDPPtEncounterTypeSlots_MultipleTypes(ref D_Slots, 84, 1, EncounterType.Cave_HallOfOrigin);
MarkDPPtEncounterTypeSlots_MultipleTypes(ref P_Slots, 84, 1, EncounterType.Cave_HallOfOrigin);
MarkDPPtEncounterTypeSlots_MultipleTypes(ref Pt_Slots, 84, 1, EncounterType.Cave_HallOfOrigin);
// Mt Coronet
MarkDPPtEncounterTypeSlots_MultipleTypes(ref D_Slots, 50, DPPt_MtCoronetExteriorEncounters, EncounterType.Cave_HallOfOrigin);
MarkDPPtEncounterTypeSlots_MultipleTypes(ref P_Slots, 50, DPPt_MtCoronetExteriorEncounters, EncounterType.Cave_HallOfOrigin);
MarkDPPtEncounterTypeSlots_MultipleTypes(ref Pt_Slots, 50, DPPt_MtCoronetExteriorEncounters, EncounterType.Cave_HallOfOrigin);
// Ruins of Alph
MarkHGSSEncounterTypeSlots_MultipleTypes(ref HG_Slots, 209, 1, EncounterType.Cave_HallOfOrigin);
MarkHGSSEncounterTypeSlots_MultipleTypes(ref SS_Slots, 209, 1, EncounterType.Cave_HallOfOrigin);
// Mt Silver Cave
MarkHGSSEncounterTypeSlots_MultipleTypes(ref HG_Slots, 219, HGSS_MtSilverCaveExteriorEncounters, EncounterType.Cave_HallOfOrigin);
MarkHGSSEncounterTypeSlots_MultipleTypes(ref SS_Slots, 219, HGSS_MtSilverCaveExteriorEncounters, EncounterType.Cave_HallOfOrigin);
MarkG4Slots(ref D_Slots);
MarkG4Slots(ref P_Slots);
@@ -1338,7 +1407,7 @@ internal static EncounterSlot[] getValidWildEncounters(PKM pkm, GameVersion game
if (s.Count <= 1 || pkm.Format == 7)
return s.Any() ? s.ToArray() : null;
var s_EncounterTypes = s.Where(slot => slot.TypeEncounter == (EncounterType)pkm.EncounterType).ToList();
var s_EncounterTypes = s.Where(slot => slot.TypeEncounter.Contains(pkm.EncounterType)).ToList();
if (s_EncounterTypes.Any())
return s_EncounterTypes.ToArray();
@@ -1360,12 +1429,17 @@ internal static List<EncounterStatic> getValidStaticEncounter(PKM pkm, GameVersi
var enc = getMatchingStaticEncounters(pkm, poss, lvl);
// Filter for encounter types
if (pkm.Gen4 && pkm.Format < 7) // type is cleared on 6->7
if (pkm.Gen4 && pkm.Format < 7 && enc.Count() > 1) // type is cleared on 6->7
{
int type = pkm.EncounterType;
enc = type == 0
var enctype = type == 0
? enc.Where(z => !(z is EncounterStaticTyped)) // no typed encounters
: enc.Where(z => z is EncounterStaticTyped && (int) ((EncounterStaticTyped)z).TypeEncounter == type);
: enc.Where(z => z is EncounterStaticTyped && ((EncounterStaticTyped)z).TypeEncounter.Contains(type));
// Filter only if there are encounters that match types and encounters that do not match types, like wild encounters
// IF there is only one of the two possibilities encounter type check will detect encounter type does not match encounter
if (enctype.Any())
enc = enctype;
}
var result = enc.ToList();
return result.Count == 0 ? null : result;
@@ -1403,12 +1477,23 @@ private static IEnumerable<EncounterStatic> getMatchingStaticEncounters(PKM pkm,
if (pkm.Format == 1 && pkm.Gen1_NotTradeback)
{
var catch_rate = (pkm as PK1).Catch_Rate;
var japanese = (pkm as PK1).Japanese;
// Pure gen 1, trades can be filter by catch rate
if ((pkm.Species == 25 || pkm.Species == 26) && catch_rate == 190)
// Red Blue Pikachu, is not a static encounter
continue;
if (catch_rate != PersonalTable.RB[e.Species].CatchRate && catch_rate != PersonalTable.Y[e.Species].CatchRate)
if (e.Version == GameVersion.Stadium)
{
if (e.Species != 054 && !Stadium_CatchRate.Contains(catch_rate))
continue;
// Amnesia Psyduck have different catch rate in japanese stadium and international stadium
if (e.Species == 054 && japanese && catch_rate != 167)
continue;
if (e.Species == 054 && !japanese && catch_rate != 168)
continue;
}
else if (catch_rate != PersonalTable.RB[e.Species].CatchRate && catch_rate != PersonalTable.Y[e.Species].CatchRate)
continue;
}
@@ -1811,8 +1896,13 @@ private static EncounterTrade getValidEncounterTradeVC1(PKM pkm, DexLevel[] p, E
{
// Even if the in game trade use the tables with source pokemon allowing generaion 2 games, the traded pokemon could be a non-tradeback pokemon
var catch_rate = (pkm as PK1).Catch_Rate;
if (catch_rate != PersonalTable.RB[z.Species].CatchRate && catch_rate != PersonalTable.Y[z.Species].CatchRate)
return null;
if (z is EncounterTradeCatchRate)
{
if (catch_rate != ((EncounterTradeCatchRate)z).Catch_Rate)
return null;
}
else if (catch_rate != PersonalTable.RB[z.Species].CatchRate && catch_rate != PersonalTable.Y[z.Species].CatchRate)
return null;
}
return z;
}
@@ -1837,6 +1927,11 @@ private static GBEncounterData getEncounter12(PKM pkm, GameVersion game)
DexLevel[] vs = getValidPreEvolutions(pkm, maxspeciesorigin: maxspeciesorigin).ToArray();
var s = getValidStaticEncounter(pkm, game);
// Valid stadium and non-stadium encounters, return only non-stadium encounters, they are less restrictive
if (s != null && game == GameVersion.RBY && s.Any(st => st.Species != 54 && st.Version == GameVersion.Stadium) && s.Any(st => st.Species != 54 && st.Version != GameVersion.Stadium))
s = s.Where(st => st.Version != GameVersion.Stadium).ToList();
var e = getValidWildEncounters(pkm, game);
var t = getValidIngameTrade(pkm, game);
@@ -1884,7 +1979,8 @@ internal static List<GBEncounterData> getEncounter12(PKM pkm)
// Both generations can provide an encounter. Return highest preference
g1.MoveLevel = getMoveMinLevelGBEncounter(g1.Species, g1.Level, getGen1GameEncounter(pkm));
if (g1.Type > g2.Type)
return new List<GBEncounterData> { g1 };
// Return also generation 2 encounters, is only needed to determine that pokemon is not exclusive from generation 1
return new List<GBEncounterData> { g1, g2 };
if (g1.Type <= g2.Type ||
// Return lowest level encounter
g2.MoveLevel < g1.MoveLevel)
@@ -1892,7 +1988,7 @@ internal static List<GBEncounterData> getEncounter12(PKM pkm)
// Return also generation 1 moves, it could have different encounter moves
return new List<GBEncounterData> { g2, g1 };
}
return new List<GBEncounterData> { g1 };
return new List<GBEncounterData> { g1, g2 };
}
internal static bool getEncounterTrade1Valid(PKM pkm)
{
@@ -3695,5 +3791,17 @@ internal static List<int>[] GetEmptyEggMovesList()
emptyegg[0] = new List<int>();
return emptyegg;
}
internal static bool IsOutsider(PKM pkm)
{
var Outsider = Savegame_TID != pkm.TID || Savegame_OT != pkm.OT_Name;
if (pkm.Format <= 2)
return Outsider;
Outsider |= Savegame_SID != pkm.SID;
if (pkm.Format == 3) // Generation 3 does not check ot geneder nor pokemon version
return Outsider;
Outsider |= Savegame_Gender != pkm.OT_Gender || Savegame_Version != (GameVersion) pkm.Version;
return Outsider;
}
}
}

View File

@@ -72,6 +72,8 @@ public static class LegalityCheckStrings
public static string V393 { get; set; } = "Valid Type B, match species type.";
public static string V394 { get; set; } = "Catch rate match a valid held item from generation 2";
public static string V398 { get; set; } = "Catch Rate match a species from pokemon evolution chain.";
public static string V403 { get; set; } = "Valid International Stadium OT.";
public static string V404 { get; set; } = "Valid Japanese Stadium OT.";
#endregion
#region Legality Check Result Strings
@@ -392,9 +394,11 @@ public static class LegalityCheckStrings
public static string V396 {get; set;} = "Catch rate match species without encounters. Expected a preevolution catch rate.";
public static string V397 {get; set;} = "Catch rate does not match any species from pokemon evolution chain.";
public static string V399 {get; set;} = "Catch rate does not match any species from pokemon evolution chain or any generation 2 held items.";
public static string V400 {get; set;} = "Unable to match encounter conditions to a possible RNG frame.";
public static string V401 {get; set;} = "In-game trade {0} should have evolved into {1}.";
public static string V402 {get; set;} = "Incorrect Stadium OT.";
public static string V405 {get; set;} = "Outsider {0} should have evolved into {1}.";
public static string V406 {get; set;} = "Non japanese Shadow E-reader Pokémon. Unreleased encounter.";
#endregion
}

View File

@@ -586,7 +586,7 @@ private static EncounterArea getArea4HGSS_Headbutt(byte[] data)
Species = Species,
LevelMin = data[8 + i*4],
LevelMax = data[9 + i*4],
Type = SlotType.Headbutt
Type = i <= 11 ? SlotType.Headbutt : SlotType.Headbutt_Special
});
}

View File

@@ -125,7 +125,7 @@ public string Name
public class EncounterStaticTyped : EncounterStatic
{
public EncounterType TypeEncounter = EncounterType.Any;
public EncounterType TypeEncounter = EncounterType.None;
protected override EncounterStatic Clone(int location)
{
@@ -164,6 +164,7 @@ public class EncounterStaticShadow : EncounterStatic
{
public EncounterLock[] Locks = new EncounterLock[0];
public int Gauge;
public bool EReader = false;
protected override EncounterStatic Clone(int location)
{

View File

@@ -22,6 +22,7 @@ public class EncounterTrade : IEncounterable, IMoveset, IGeneration
public int Gender = -1;
public int OTGender = -1;
public bool EggEncounter => false;
public bool EvolveOnTrade = false;
public string Name => "In-game Trade";
@@ -35,4 +36,9 @@ public class EncounterTradePID : EncounterTrade
{
public uint PID;
}
public class EncounterTradeCatchRate : EncounterTrade
{
public uint Catch_Rate;
}
}

View File

@@ -2,7 +2,11 @@
{
public enum EncounterType
{
Any = -1,
Headbutt_Grass = -1, // None or TallGrass
Headbutt_Surf = -2, // None or Surfing_Fishing
Headbutt_GrassSurf = -3, // None, TallGrass or Surfing_Fishing
Headbutt_CitySurf = -4, // Building_EnigmaStone or Surfing_Fishing
Headbutt_CaveSurf = -5, // Cave_HallOfOrigin or Surfing_Fishing
None = 0,
RockSmash = 1,
TallGrass = 2,
@@ -15,4 +19,27 @@ public enum EncounterType
DistortionWorld_Pt = 23,
Starter_Fossil_Gift_Pt_DPTrio = 24,
}
public static class EncounterTypeExtension
{
public static bool Contains(this EncounterType g1, int g2)
{
return g1.Contains((EncounterType)g2);
}
public static bool Contains(this EncounterType g1, EncounterType g2)
{
if (g1 == EncounterType.Headbutt_Grass)
return g2 == EncounterType.None || g2 == EncounterType.TallGrass;
if (g1 == EncounterType.Headbutt_Surf)
return g2 == EncounterType.None || g2 == EncounterType.Surfing_Fishing;
if (g1 == EncounterType.Headbutt_GrassSurf)
return EncounterType.Headbutt_Grass.Contains(g2) || g2 == EncounterType.Surfing_Fishing;
if (g1 == EncounterType.Headbutt_CitySurf)
return g2 == EncounterType.Building_EnigmaStone || g2 == EncounterType.Surfing_Fishing;
if (g1 == EncounterType.Headbutt_CaveSurf)
return g2 == EncounterType.Cave_HallOfOrigin || g2 == EncounterType.Surfing_Fishing;
return g1 == g2;
}
}
}

View File

@@ -19,6 +19,7 @@ public enum SlotType
SOS,
Swarm,
Headbutt,
Headbutt_Special,
Pokeradar,
HoneyTree,
HiddenGrotto,

View File

@@ -110,6 +110,14 @@ public static partial class Legal
// new EncounterStatic { Species = 007, Level = 10, Version = GameVersion.YW }, // Squirtle (Vermillion City)
new EncounterStatic { Species = 054, Level = 15, Moves = new [] { 133, 10 }, Version = GameVersion.Stadium }, // Stadium Psyduck (Amnesia)
new EncounterStatic { Species = 001, Level = 05, Version = GameVersion.Stadium }, // Bulbasaur
new EncounterStatic { Species = 004, Level = 05, Version = GameVersion.Stadium }, // Charmander
new EncounterStatic { Species = 071, Level = 05, Version = GameVersion.Stadium }, // Squirtle
new EncounterStatic { Species = 106, Level = 20, Version = GameVersion.Stadium }, // Hitmonlee
new EncounterStatic { Species = 107, Level = 20, Version = GameVersion.Stadium }, // Hitmonchan
new EncounterStatic { Species = 133, Level = 25, Version = GameVersion.Stadium }, // Eevee
new EncounterStatic { Species = 138, Level = 20, Version = GameVersion.Stadium }, // Omanyte
new EncounterStatic { Species = 140, Level = 20, Version = GameVersion.Stadium }, // Kabuto
new EncounterStatic { Species = 151, Level = 5, IVs = new [] {15,15,15,15,15,15}, Version = GameVersion.VCEvents }, // Event Mew
};
internal static readonly EncounterTrade[] TradeGift_RBY_Common =
@@ -140,9 +148,9 @@ public static partial class Legal
new EncounterTrade { Species = 115, Generation = 1, Level = 42 }, // Kangaskhan - Evolve Rhydon (GSC: 30)
new EncounterTrade { Species = 128, Generation = 1, Level = 28 }, // Tauros - Evolve Persian (GSC: 18)
new EncounterTrade { Species = 093, Generation = 1, Level = 20 }, // Haunter - Trade Machoke (GSC: 10)
new EncounterTrade { Species = 075, Generation = 1, Level = 16 }, // Graveler - Evolve Kadabra (GSC: 15)
new EncounterTrade { Species = 098, Generation = 1, Level = 15 }, // Krabby - Wild Growlithe (GSC: 5)
new EncounterTradeCatchRate { Species = 093, Generation = 1, Level = 20, Catch_Rate = 45, EvolveOnTrade = true }, // Haunter - Trade Machoke (GSC: 10)
new EncounterTradeCatchRate { Species = 075, Generation = 1, Level = 16, Catch_Rate = 45, EvolveOnTrade = true }, // Graveler - Evolve Kadabra (GSC: 15)
new EncounterTradeCatchRate { Species = 098, Generation = 1, Level = 15, Catch_Rate = 204 }, // Krabby - Wild Growlithe (GSC: 5)
//new EncounterTrade { Species = 122, Generation = 1, Level = 08 }, // Mr. Mime - Wild Clefairy (GSC: 6)
new EncounterTrade { Species = 067, Generation = 1, Level = 20 }, // Machoke - Wild Cubone (GSC: 10)
@@ -159,9 +167,9 @@ public static partial class Legal
new EncounterTrade { Species = 115, Generation = 1, Level = 30 }, // Kangaskhan - Evolve Rhydon (RBY: 42)
new EncounterTrade { Species = 128, Generation = 1, Level = 18 }, // Tauros - Evolve Persian (RBY: 28)
new EncounterTrade { Species = 093, Generation = 1, Level = 10 }, // Haunter - Trade Machoke (RBY: 20)
new EncounterTrade { Species = 075, Generation = 1, Level = 15 }, // Graveler - Evolve Kadabra (RBY: 16)
new EncounterTrade { Species = 098, Generation = 1, Level = 05 }, // Krabby - Egg Growlithe (RBY: 15)
new EncounterTradeCatchRate { Species = 093, Generation = 1, Level = 10, Catch_Rate = 45, EvolveOnTrade = true }, // Haunter - Trade Machoke (RBY: 20)
new EncounterTradeCatchRate { Species = 075, Generation = 1, Level = 15, Catch_Rate = 45, EvolveOnTrade = true }, // Graveler - Evolve Kadabra (RBY: 16)
new EncounterTradeCatchRate { Species = 098, Generation = 1, Level = 05, Catch_Rate = 204 }, // Krabby - Egg Growlithe (RBY: 15)
//new EncounterTrade { Species = 122, Generation = 1, Level = 08 }, // Mr. Mime - Wild Clefairy (RBY: 6)
new EncounterTrade { Species = 067, Generation = 1, Level = 05 }, // Machoke - Egg Cubone (RBY: 20)
@@ -196,7 +204,31 @@ public static partial class Legal
};
internal static readonly int[] Species_NotAvailable_CatchRate =
{
12, 18, 31, 34, 36, 38, 45, 53, 59, 62, 65, 68, 71, 76, 78, 91, 94, 103, 121
12, 18, 31, 34, 36, 38, 45, 53, 59, 62, 65, 68, 71, 78, 91, 103, 121
};
internal static readonly int[] Stadium_CatchRate =
{
167, // Normal Box
168, // Gorgeous Box
};
internal static readonly int[] Stadium_GiftSpecies =
{
001, // Bulbasaur
004, // Charmander
007, // Squirtle
054, // Psyduck (Amnesia)
106, // Hitmonlee
107, // Hitmonchan
133, // Eevee
138, // Omanyte
140, // Kabuto
};
internal static readonly int[] Trade_Evolution1 =
{
064,
067,
075,
093
};
}
}

View File

@@ -719,9 +719,9 @@ public static partial class Legal
new EncounterStaticShadow { Species = 217, Level = 45, Gauge = 07000, Moves = new[] {185,313,122,163}, Location = 132 }, // Ursaring: Team Snagem Agrev @ Snagem Hideout
new EncounterStaticShadow { Species = 213, Level = 45, Gauge = 07000, Moves = new[] {219,227,156,117}, Location = 125 }, // Shuckle: Deep King Agnol @ Deep Colosseum
new EncounterStaticShadow { Species = 176, Level = 20, Gauge = 05000, Moves = new[] {118,204,186,281}, Location = 001 }, // Togetic: Cipher Peon Fein @ Outskirt Stand
new EncounterStaticShadow { Species = 175, Level = 20, Gauge = 00000, Moves = new[] {118,204,186,281}, IVs = new[] {0,0,0,0,0,0} }, // Togepi: Chaser ボデス @ Card e Room (Japanese games only)
new EncounterStaticShadow { Species = 179, Level = 37, Gauge = 00000, Moves = new[] {087,084,086,178}, IVs = new[] {0,0,0,0,0,0} }, // Mareep: Hunter ホル @ Card e Room (Japanese games only)
new EncounterStaticShadow { Species = 212, Level = 50, Gauge = 00000, Moves = new[] {210,232,014,163}, IVs = new[] {0,0,0,0,0,0} }, // Scizor: Bodybuilder ワーバン @ Card e Room (Japanese games only)
new EncounterStaticShadow { Species = 175, Level = 20, Gauge = 00000, Moves = new[] {118,204,186,281}, IVs = new[] {0,0,0,0,0,0}, EReader = true }, // Togepi: Chaser ボデス @ Card e Room (Japanese games only)
new EncounterStaticShadow { Species = 179, Level = 37, Gauge = 00000, Moves = new[] {087,084,086,178}, IVs = new[] {0,0,0,0,0,0}, EReader = true }, // Mareep: Hunter ホル @ Card e Room (Japanese games only)
new EncounterStaticShadow { Species = 212, Level = 50, Gauge = 00000, Moves = new[] {210,232,014,163}, IVs = new[] {0,0,0,0,0,0}, EReader = true }, // Scizor: Bodybuilder ワーバン @ Card e Room (Japanese games only)
};
#endregion

View File

@@ -220,6 +220,17 @@ public static partial class Legal
69, // Iron Island
84, // Stark Mountain
};
internal static readonly int[] DPPt_MixInteriorExteriorLocations =
{
24, // Route 209 (Lost Tower)
50, // Mt Coronet
70, // Old Chateau
84, // Stark Mountain
};
internal static readonly int[] DPPt_MtCoronetExteriorEncounters =
{
4, 5
};
internal static readonly int[] HGSS_CaveLocations =
{
197, // DIGLETT's Cave
@@ -245,9 +256,105 @@ public static partial class Legal
228, // Cliff Cave
234, // Cliff Edge Gate
};
internal static readonly int[] HGSS_CityLocations =
{
126, // New Bark Town
127, // Cherrygrove City
128, // Violet City
129, // Azalea Town
130, // Cianwood City
131, // Goldenrod City
132, // Olivine City
133, // Ecruteak City
134, // Mahogany Town
136, // Blackthorn City
138, // Pallet Town
139, // Viridian City
140, // Pewter City
141, // Cerulean City
142, // Lavender Town
143, // Vermilion City
144, // Celadon City
145, // Fuchsia City
146, // Cinnabar Island
147, // Indigo Plateau
148, // Saffron City
227, // Safari Zone Gate
};
internal static readonly int[] HGSS_SurfingHeadbutt_Locations =
{ // Locations with headbutt trees adjacent to water tiles
126, // New Bark Town
128, // Violet City
133, // Ecruteak City
135, // Lake of Rage
138, // Pallet Town
139, // Viridian City
160, // Route 12
169, // Route 21
170, // Route 22
174, // Route 26
175, // Route 27
176, // Route 28
178, // Route 30
179, // Route 31
180, // Route 32
182, // Route 34
183, // Route 35
190, // Route 42
191, // Route 43
192, // Route 44
214, // Ilex Forest
};
internal static readonly int[] HGSS_GrassHeadbutt_Locations =
{ // Locations with headbutt trees adjacent to tall grass tiles
137, // Mt. Silver
149, // Route 1
150, // Route 2
151, // Route 3
152, // Route 4
153, // Route 5
154, // Route 6
155, // Route 7
159, // Route 11
161, // Route 13
163, // Route 15
164, // Route 16
169, // Route 21
170, // Route 22
174, // Route 26
175, // Route 27
176, // Route 28
177, // Route 29
178, // Route 30
179, // Route 31
180, // Route 32
181, // Route 33
182, // Route 34
183, // Route 35
184, // Route 36
185, // Route 37
186, // Route 38
187, // Route 39
191, // Route 43
192, // Route 44
194, // Route 46
195, // Route 47
196, // Route 48
219, // Mt. Silver Cave
224, // Viridian Forest
};
internal static readonly int[] HGSS_MtSilverCaveExteriorEncounters =
{
2, 3
};
internal static readonly int[] HGSS_MixInteriorExteriorLocations =
{
209, // Ruins of Alph
219, // Mt. Silver Cave
};
#endregion
#region Pokéwalker Encounter
// all pkm are in Poke Ball and have a met location of "PokeWalker"
// all pkm are in Poke Ball and have a met location of "PokeWalker"
internal static readonly EncounterStatic[] Encounter_PokeWalker =
{
// Some pkm has a pre-level move, an egg move or even a special move, it might be also available via HM/TM/Tutor

View File

@@ -299,7 +299,7 @@ public static partial class Legal
new EncounterTrade { Species = 761, Form = 0, Level = 16, Ability = 1, TID = 20683, SID = 00009, OTGender = 0, Gender = 1, Nature = Nature.Adamant, }, // Bounsweet
new EncounterTrade { Species = 061, Form = 0, Level = 22, Ability = 2, TID = 01092, SID = 00009, OTGender = 1, Gender = 1, Nature = Nature.Naughty, }, // Poliwhirl
new EncounterTrade { Species = 440, Form = 0, Level = 27, Ability = 2, TID = 10913, SID = 00000, OTGender = 1, Gender = 1, Nature = Nature.Calm, }, // Happiny
new EncounterTrade { Species = 075, Form = 1, Level = 32, Ability = 1, TID = 20778, SID = 00009, OTGender = 0, Gender = 0, Nature = Nature.Impish, }, // Graveler-1
new EncounterTrade { Species = 075, Form = 1, Level = 32, Ability = 1, TID = 20778, SID = 00009, OTGender = 0, Gender = 0, Nature = Nature.Impish, EvolveOnTrade = true }, // Graveler-1
new EncounterTrade { Species = 762, Form = 0, Level = 43, Ability = 1, TID = 20679, SID = 00009, OTGender = 1, Gender = 1, Nature = Nature.Careful, }, // Steenee
new EncounterTrade { Species = 663, Form = 0, Level = 59, Ability = 4, TID = 56734, SID = 00008, OTGender = 0, Gender = 0, Nature = Nature.Jolly, }, // Talonflame
};

View File

@@ -40,6 +40,8 @@ V392 = Valid Type A, match species type.
V393 = Valid Type B, match species type.
V394 = Catch rate match a valid held item from generation 2.
V398 = Catch Rate match any species from pokemon evolution chain.
V403 = Valid International Stadium OT.
V404 = Valid Japanese Stadium OT.
V203 = Genderless Pokémon should not have a gender.
V201 = Encryption Constant is not set.
V204 = Held item is unreleased.
@@ -328,4 +330,9 @@ V390 = Invalid Type B, does not match species type.
V395 = Catch rate does not match a valid held item from generation 2.
V396 = Catch rate match species without encounters. Expected a preevolution catch rate.
V397 = Catch rate does not match any species from pokemon evolution chain.
V399 = Catch rate does not match any species from pokemon evolution chain or any generation 2 held items.
V399 = Catch rate does not match any species from pokemon evolution chain or any generation 2 held items.
V400 = Unable to match encounter conditions to a possible RNG frame.
V401 = In-game trade {0} should have evolved into {1}.
V402 = Incorrect Stadium OT.
V405 = Outsider {0} should have evolved into {1}.
V406 = Non japanese Shadow E-reader Pokémon. Unreleased encounter.

View File

@@ -41,6 +41,8 @@ V392 = Valid Type A, match species type.
V393 = Valid Type B, match species type.
V394 = Catch rate match a valid held item from generation 2.
V398 = Catch rate match any species from pokemon evolution chain.
V403 = Valid International Stadium OT.
V404 = Valid Japanese Stadium OT.
V203 = 무성 포켓몬은 성별을 가질 수 없습니다.
V201 = 암호화 상수가 설정되어 있지 않습니다.
V204 = 지닌 물건이 배포되지 않은 물건입니다.
@@ -329,4 +331,9 @@ V390 = Invalid Type B, does not match species type.
V395 = Catch rate does not match a valid held item from generation 2.
V396 = Catch rate match species without encounters. Expected a preevolution catch rate.
V397 = Catch rate does not match any species from pokemon evolution chain.
V399 = Catch rate does not match any species from pokemon evolution chain or any generation 2 held items.
V399 = Catch rate does not match any species from pokemon evolution chain or any generation 2 held items.
V400 = Unable to match encounter conditions to a possible RNG frame.
V401 = In-game trade {0} should have evolved into {1}.
V402 = Incorrect Stadium OT.
V405 = Outsider {0} should have evolved into {1}.
V406 = Non japanese Shadow E-reader Pokémon. Unreleased encounter.

View File

@@ -41,6 +41,8 @@ V392 = Valid Type A, match species type.
V393 = Valid Type B, match species type.
V394 = Catch rate match a valid held item from generation 2
V398 = Catch rate match any species from pokemon evolution chain.
V403 = Valid International Stadium OT.
V404 = Valid Japanese Stadium OT.
V203 = 无性别宝可梦不能有性别。
V201 = 未设置加密常数。
V204 = 持有物未解禁。
@@ -329,4 +331,9 @@ V390 = Invalid Type B, does not match species type.
V395 = Catch rate does not match a valid held item from generation 2.
V396 = Catch rate match species without encounters. Expected a preevolution catch rate.
V397 = Catch rate does not match any species from pokemon evolution chain.
V399 = Catch rate does not match any species from pokemon evolution chain or any generation 2 held items.
V399 = Catch rate does not match any species from pokemon evolution chain or any generation 2 held items.
V400 = Unable to match encounter conditions to a possible RNG frame.
V401 = In-game trade {0} should have evolved into {1}.
V402 = Incorrect Stadium OT.
V405 = Outsider {0} should have evolved into {1}.
V406 = Non japanese Shadow E-reader Pokémon. Unreleased encounter.