mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-18 14:28:33 +00:00
Generation 1/2 Legal improvements (#1310)
* Added location to encounter slot to make verification againts the location of the encounter when the pokemon has lost met location, like generation 2 heabutt tree, jhoto surfing in route 45 and in the future generation 4 munchlax tree Added version to generation 1 and 2 encounter locations to filter by catch rate based of the version of the encounter and check initial moves of the encounter only for the game that match the encounter Filter generation 2 pokemon for crystal who have met location based of the time of day when it was captured Completed version to static and traded encounters for gen 1 pokemon, to avoid check a red encounter with yellow initial moves, if an encounter is possible in both games with diferent moves it is duplicated (like eevee), if it is possible in both games with the same moves is left as RBY, the encounter will only use red/blue moveset Verify some invalid gen 2 encounters. Crystall heabutt encounters based on the TID, using the tree selection algorithm of the game to determine if the encounter is possible for the TID (implemented base on https://bulbapedia.bulbagarden.net/wiki/Headbutt_tree#Mechanics). Coordinates of Crystal trees obtained with the programa G2Map Added checks for fishing encounters for unreacheable water tiles in gen 2, route 14, national park and the beta safari zone. * Fix gen 1 static encounters and trade encounters filter by version * Missing strings
This commit is contained in:
parent
0a2245b55c
commit
461fb70f90
18 changed files with 835 additions and 436 deletions
|
@ -25,6 +25,7 @@
|
|||
/* VC2*/ GD = 39, SV = 40, C,
|
||||
|
||||
// Game Groupings (SaveFile type)
|
||||
RB = 97,
|
||||
RBY = 98,
|
||||
GSC = 99,
|
||||
RS = 100,
|
||||
|
@ -58,8 +59,10 @@
|
|||
|
||||
switch (g1)
|
||||
{
|
||||
case GameVersion.RB:
|
||||
return g2 == GameVersion.RD || g2 == GameVersion.BU || g2 == GameVersion.GN;
|
||||
case GameVersion.RBY:
|
||||
return g2 == GameVersion.RD || g2 == GameVersion.BU || g2 == GameVersion.YW || g2 == GameVersion.GN;
|
||||
return GameVersion.RB.Contains(g2) || g2 == GameVersion.YW;
|
||||
case GameVersion.Gen1:
|
||||
return GameVersion.RBY.Contains(g2) || g2 == GameVersion.Stadium || g2 == GameVersion.EventsGBGen1 || g2 == GameVersion.VCEvents;
|
||||
case GameVersion.Stadium:
|
||||
|
|
|
@ -61,6 +61,7 @@ namespace PKHeX.Core
|
|||
private static readonly EvolutionTree Evolves2;
|
||||
private static readonly EncounterArea[] SlotsGSC, SlotsGS, SlotsC;
|
||||
private static readonly EncounterStatic[] StaticGSC, StaticGS, StaticC;
|
||||
private static readonly TreesArea[] HeadbuttTreesC = TreesArea.GetArray(Data.UnpackMini(Util.GetBinaryResource("trees_h_c.pkl"), "ch"));
|
||||
|
||||
// Gen 3
|
||||
private static readonly Learnset[] LevelUpE = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_e.pkl"), "em"));
|
||||
|
@ -323,6 +324,12 @@ namespace PKHeX.Core
|
|||
foreach (EncounterStatic Encounter in Encounters)
|
||||
Encounter.Generation = Generation;
|
||||
}
|
||||
private static void MarkEncountersVersion(ref EncounterArea[] Areas, GameVersion Version)
|
||||
{
|
||||
foreach (EncounterArea Area in Areas)
|
||||
foreach (EncounterSlot1 Slot in Area.Slots)
|
||||
Slot.Version = Version;
|
||||
}
|
||||
private static void MarkEncountersGeneration(ref EncounterArea[] Areas, int Generation)
|
||||
{
|
||||
foreach (EncounterArea Area in Areas)
|
||||
|
@ -338,6 +345,16 @@ namespace PKHeX.Core
|
|||
Slots = a.SelectMany(m => m.Slots).ToArray()
|
||||
}).ToArray();
|
||||
}
|
||||
private static void MarkSlotLocation(ref EncounterArea[] Areas)
|
||||
{
|
||||
foreach(EncounterArea Area in Areas)
|
||||
{
|
||||
foreach (EncounterSlot Slot in Area.Slots)
|
||||
{
|
||||
Slot.Location = Area.Location;
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void MarkG2Slots(ref EncounterArea[] Areas)
|
||||
{
|
||||
ReduceAreasSize(ref Areas);
|
||||
|
@ -717,6 +734,12 @@ namespace PKHeX.Core
|
|||
var rb_fish = EncounterArea.GetArray1_F(Util.GetBinaryResource("encounter_rb_f.pkl"));
|
||||
var ylw_fish = EncounterArea.GetArray1_FY(Util.GetBinaryResource("encounter_yellow_f.pkl"));
|
||||
|
||||
MarkEncountersVersion(ref red_gw, GameVersion.RD);
|
||||
MarkEncountersVersion(ref blu_gw, GameVersion.BW);
|
||||
MarkEncountersVersion(ref ylw_gw, GameVersion.YW);
|
||||
MarkEncountersVersion(ref rb_fish, GameVersion.RB);
|
||||
MarkEncountersVersion(ref ylw_fish, GameVersion.YW);
|
||||
|
||||
var table = AddExtraTableSlots(red_gw, blu_gw, ylw_gw, rb_fish, ylw_fish);
|
||||
Array.Resize(ref table, table.Length + 1);
|
||||
table[table.Length - 1] = FishOldGood_RBY;
|
||||
|
@ -728,6 +751,7 @@ namespace PKHeX.Core
|
|||
EncounterArea[] Slots = null;
|
||||
// Fishing
|
||||
var f = EncounterArea.GetArray2_F(Util.GetBinaryResource("encounter_gsc_f.pkl"));
|
||||
|
||||
if (Version == GameVersion.GS || Version == GameVersion.GSC)
|
||||
{
|
||||
// Grass/Water
|
||||
|
@ -736,8 +760,18 @@ namespace PKHeX.Core
|
|||
// Headbutt/Rock Smash
|
||||
var h_g = EncounterArea.GetArray2_H(Util.GetBinaryResource("encounter_gold_h.pkl"));
|
||||
var h_s = EncounterArea.GetArray2_H(Util.GetBinaryResource("encounter_silver_h.pkl"));
|
||||
var safari_gs = EncounterSafari_GSC;
|
||||
var bcc_gs = EncounterBCC_GSC;
|
||||
|
||||
Slots = AddExtraTableSlots(g, s, h_g, h_s, f, EncounterBCC_GSC);
|
||||
MarkEncountersVersion(ref bcc_gs, GameVersion.GS);
|
||||
MarkEncountersVersion(ref f, GameVersion.GS);
|
||||
MarkEncountersVersion(ref g, GameVersion.GD);
|
||||
MarkEncountersVersion(ref s, GameVersion.SV);
|
||||
MarkEncountersVersion(ref h_g, GameVersion.GD);
|
||||
MarkEncountersVersion(ref h_s, GameVersion.SV);
|
||||
MarkEncountersVersion(ref safari_gs, GameVersion.GS);
|
||||
|
||||
Slots = AddExtraTableSlots(g, s, h_g, h_s, f, bcc_gs, safari_gs);
|
||||
}
|
||||
if (Version == GameVersion.C || Version == GameVersion.GSC)
|
||||
{
|
||||
|
@ -745,8 +779,16 @@ namespace PKHeX.Core
|
|||
var c = EncounterArea.GetArray2_GW(Util.GetBinaryResource("encounter_crystal.pkl"));
|
||||
// Headbutt/Rock Smash
|
||||
var h_c = EncounterArea.GetArray2_H(Util.GetBinaryResource("encounter_crystal_h.pkl"));
|
||||
var safari_c= EncounterSafari_GSC;
|
||||
var bcc_c = EncounterBCC_GSC;
|
||||
|
||||
var extra = AddExtraTableSlots(c, h_c, f, EncounterBCC_GSC);
|
||||
MarkEncountersVersion(ref bcc_c, GameVersion.C);
|
||||
MarkEncountersVersion(ref safari_c, GameVersion.C);
|
||||
MarkEncountersVersion(ref f, GameVersion.C);
|
||||
MarkEncountersVersion(ref c, GameVersion.C);
|
||||
MarkEncountersVersion(ref h_c, GameVersion.C);
|
||||
|
||||
var extra = AddExtraTableSlots(c, h_c, f, bcc_c, safari_c);
|
||||
return Version == GameVersion.C ? extra : AddExtraTableSlots(Slots, extra);
|
||||
}
|
||||
|
||||
|
@ -776,6 +818,7 @@ namespace PKHeX.Core
|
|||
MarkG2Slots(ref SlotsGS);
|
||||
MarkG2Slots(ref SlotsC);
|
||||
MarkG2Slots(ref SlotsGSC);
|
||||
MarkSlotLocation(ref SlotsC);
|
||||
MarkEncountersGeneration(ref SlotsGS, 2);
|
||||
MarkEncountersGeneration(ref SlotsC, 2);
|
||||
MarkEncountersGeneration(ref SlotsGSC, 2);
|
||||
|
@ -821,6 +864,12 @@ namespace PKHeX.Core
|
|||
SlotsFR = AddExtraTableSlots(FR_Slots, SlotsFRLGAlt);
|
||||
SlotsLG = AddExtraTableSlots(LG_Slots, SlotsFRLGAlt);
|
||||
|
||||
MarkSlotLocation(ref SlotsR);
|
||||
MarkSlotLocation(ref SlotsS);
|
||||
MarkSlotLocation(ref SlotsE);
|
||||
MarkSlotLocation(ref SlotsFR);
|
||||
MarkSlotLocation(ref SlotsLG);
|
||||
|
||||
Evolves3 = new EvolutionTree(new[] { Util.GetBinaryResource("evos_g3.pkl") }, GameVersion.RS, PersonalTable.RS, MaxSpeciesID_3);
|
||||
|
||||
// Update Personal Entries with TM/Tutor Data
|
||||
|
@ -918,6 +967,12 @@ namespace PKHeX.Core
|
|||
MarkHGSSEncounterTypeSlots(ref SlotsHG);
|
||||
MarkHGSSEncounterTypeSlots(ref SlotsSS);
|
||||
|
||||
MarkSlotLocation(ref SlotsD);
|
||||
MarkSlotLocation(ref SlotsP);
|
||||
MarkSlotLocation(ref SlotsPt);
|
||||
MarkSlotLocation(ref SlotsHG);
|
||||
MarkSlotLocation(ref SlotsSS);
|
||||
|
||||
Evolves4 = new EvolutionTree(new[] { Util.GetBinaryResource("evos_g4.pkl") }, GameVersion.DP, PersonalTable.DP, MaxSpeciesID_4);
|
||||
|
||||
// Update Personal Entries with Tutor Data
|
||||
|
@ -1412,24 +1467,22 @@ namespace PKHeX.Core
|
|||
}
|
||||
|
||||
// Encounter
|
||||
internal static GameVersion[] GetGen2GameEncounter(PKM pkm)
|
||||
internal static GameVersion[] GetGen2GameEncounter(PKM pkm, LegalInfo Info)
|
||||
{
|
||||
return AllowGen2VCCrystal ? new[] { GameVersion.GS, GameVersion.C } : new[] { GameVersion.GS};
|
||||
if (AllowGen2Crystal && Info.Game == GameVersion.C)
|
||||
return new[] { GameVersion.C };
|
||||
// Any encounter marked with version GSC is for pokemon with the same moves in g/s and crystal, it is enought to check only g/s moves
|
||||
return new[] { GameVersion.GS };
|
||||
}
|
||||
internal static GameVersion[] GetGen1GameEncounter(PKM pkm)
|
||||
internal static GameVersion[] GetGen1GameEncounter(PKM pkm, LegalInfo Info)
|
||||
{
|
||||
if (!(pkm is PK1 pk) || !pkm.Gen1_NotTradeback)
|
||||
return new[] { GameVersion.RD, GameVersion.YW };
|
||||
if (25 <= pk.Species && pk.Species <= 26)
|
||||
// Yellow Pikachu detected by its special catch rate
|
||||
return new[] { pk.Catch_Rate == 163 ? GameVersion.YW : GameVersion.RD };
|
||||
if (64 <= pk.Species && pk.Species <= 65)
|
||||
// Yellow Kadabra detected by its special catch rate
|
||||
return new[] { pk.Catch_Rate == 96 ? GameVersion.YW : GameVersion.RD };
|
||||
if (148 <= pk.Species && pk.Species <= 149 && pk.Catch_Rate == 27)
|
||||
// Yellow Dragonair detected by its special catch rate, is have another catch rate could be red/blue dratini or yellow dratini
|
||||
if (Info.EncounterMatch.Species == 133 && Info.Game == GameVersion.Stadium)
|
||||
// Staidum eevee, check for red/blue and yellow initial moves
|
||||
return new[] { GameVersion.RB, GameVersion.YW };
|
||||
if (Info.Game == GameVersion.YW)
|
||||
return new[] { GameVersion.YW };
|
||||
return new[] { GameVersion.RD, GameVersion.YW };
|
||||
// Any encounter marked with version RBY is for pokemon with the same moves and catch rate in red/blue and yellow, it is enought to check only red/blue moves
|
||||
return new[] { GameVersion.RB };
|
||||
}
|
||||
internal static IEnumerable<int> GetInitialMovesGBEncounter(int species, int lvl, GameVersion ver)
|
||||
{
|
||||
|
@ -1442,6 +1495,7 @@ namespace PKHeX.Core
|
|||
case GameVersion.RD:
|
||||
case GameVersion.BU:
|
||||
case GameVersion.GN:
|
||||
case GameVersion.RB:
|
||||
{
|
||||
var LevelTable = ver == GameVersion.YW ? LevelUpY : LevelUpRB;
|
||||
int index = PersonalTable.RB.GetFormeIndex(species, 0);
|
||||
|
@ -1455,6 +1509,8 @@ namespace PKHeX.Core
|
|||
break;
|
||||
}
|
||||
case GameVersion.C:
|
||||
case GameVersion.GD:
|
||||
case GameVersion.SV:
|
||||
case GameVersion.GS:
|
||||
{
|
||||
if (species == 235)
|
||||
|
@ -2929,5 +2985,10 @@ namespace PKHeX.Core
|
|||
Outsider |= Savegame_Gender != pkm.OT_Gender || Savegame_Version != (GameVersion) pkm.Version;
|
||||
return Outsider;
|
||||
}
|
||||
|
||||
internal static TreesArea GetCrystalTreeArea(PKM pkm,EncounterSlot Slot)
|
||||
{
|
||||
return HeadbuttTreesC.FirstOrDefault(a => a.Location == Slot.Location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
bool PIDMatch = info.PIDIVMatches;
|
||||
var EncounterMatch = info.EncounterMatch = encounter.Current;
|
||||
var e = EncounterValidator(pkm, EncounterMatch);
|
||||
var e = EncounterValidator(pkm, info, EncounterMatch);
|
||||
if (!e.Valid && encounter.PeekIsNext())
|
||||
continue;
|
||||
info.Parse.Add(e);
|
||||
|
@ -81,7 +81,7 @@ namespace PKHeX.Core
|
|||
info.Moves = VerifyCurrentMoves.VerifyMoves(pkm, info);
|
||||
return info;
|
||||
}
|
||||
private static Func<PKM, IEncounterable, CheckResult> GetEncounterVerifierMethod(PKM pkm)
|
||||
private static Func<PKM, LegalInfo,IEncounterable, CheckResult> GetEncounterVerifierMethod(PKM pkm)
|
||||
{
|
||||
switch (pkm.GenNumber)
|
||||
{
|
||||
|
|
|
@ -416,7 +416,10 @@ namespace PKHeX.Core
|
|||
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)
|
||||
// Encounter with the different catch rate in yellow and redblue are duplicated with different gameverion
|
||||
else if (e.Version == GameVersion.YW && catch_rate != PersonalTable.Y[e.Species].CatchRate)
|
||||
continue;
|
||||
else if (e.Version != GameVersion.YW && catch_rate != PersonalTable.RB[e.Species].CatchRate)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -540,7 +543,8 @@ namespace PKHeX.Core
|
|||
// Get Valid levels
|
||||
IEnumerable<DexLevel> vs = GetValidPreEvolutions(pkm, maxspeciesorigin: maxspeciesorigin, lvl: ignoreLevel ? 100 : -1, skipChecks: ignoreLevel);
|
||||
|
||||
bool IsRGBKadabra = false;
|
||||
bool RBDragonair = false;
|
||||
GameVersion Gen1Version = GameVersion.RBY;
|
||||
if (pkm is PK1 pk1 && pkm.Gen1_NotTradeback)
|
||||
{
|
||||
// Pure gen 1, slots can be filter by catch rate
|
||||
|
@ -548,14 +552,31 @@ namespace PKHeX.Core
|
|||
// Yellow Pikachu, is not a wild encounter
|
||||
yield break;
|
||||
if ((pkm.Species == 64 || pkm.Species == 65) && pk1.Catch_Rate == 96)
|
||||
{
|
||||
// Yellow Kadabra, ignore Abra encounters
|
||||
vs = vs.Where(s => s.Species == 64);
|
||||
if ((pkm.Species == 148 || pkm.Species == 149) && pk1.Catch_Rate == 27)
|
||||
Gen1Version = GameVersion.YW;
|
||||
}
|
||||
if (pkm.Species == 148 || pkm.Species == 149)
|
||||
{
|
||||
if (pk1.Catch_Rate == 27)
|
||||
{
|
||||
// Yellow Dragonair, ignore Dratini encounters
|
||||
vs = vs.Where(s => s.Species == 148);
|
||||
Gen1Version = GameVersion.YW;
|
||||
}
|
||||
else
|
||||
// Red blue dragonair have the same catch rate as dratini, it could also be a dratini from any game
|
||||
RBDragonair = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsRGBKadabra = (pkm.Species == 64 || pkm.Species == 65) && pk1.Catch_Rate == 100;
|
||||
if((pkm.Species == 64 || pkm.Species == 65) && pk1.Catch_Rate == 100)
|
||||
{
|
||||
// Red Blue Kadabra
|
||||
vs = vs.Where(s => s.Species == 64);
|
||||
Gen1Version = GameVersion.RB;
|
||||
}
|
||||
vs = vs.Where(s => pk1.Catch_Rate == PersonalTable.RB[s.Species].CatchRate);
|
||||
}
|
||||
}
|
||||
|
@ -573,8 +594,21 @@ namespace PKHeX.Core
|
|||
|
||||
if (gen <= 2)
|
||||
{
|
||||
if (IsRGBKadabra) //Red Kadabra slots : Level 49 and 51 in RGB, but level 20 and 27 in Yellow
|
||||
encounterSlots = encounterSlots.Where(slot => slot.LevelMin >= 49).ToList();
|
||||
if (gen == 1 && Gen1Version != GameVersion.RBY)
|
||||
{
|
||||
encounterSlots = encounterSlots.Where(slot => Gen1Version.Contains(((EncounterSlot1)slot).Version)).ToList();
|
||||
}
|
||||
|
||||
if (gen == 1 && RBDragonair)
|
||||
{
|
||||
// Red Blue dragonair or dratini from any gen 1 games
|
||||
encounterSlots = encounterSlots.Where(slot => GameVersion.RB.Contains(((EncounterSlot1)slot).Version) || slot.Species == 147).ToList();
|
||||
}
|
||||
|
||||
if (gen == 2 && pkm is PK2 pk2 && pk2.Met_Day != 0)
|
||||
{
|
||||
encounterSlots = encounterSlots.Where(slot => ((EncounterSlot1)slot).Time.Contains(pk2.Met_Day)).ToList();
|
||||
}
|
||||
|
||||
foreach (var s in encounterSlots.OrderBy(slot => slot.LevelMin))
|
||||
yield return s;
|
||||
|
@ -746,10 +780,18 @@ namespace PKHeX.Core
|
|||
|
||||
// Even if the in game trade uses the tables with source pokemon allowing generation 2 games, the traded pokemon could be a non-tradeback pokemon
|
||||
var rate = (pkm as PK1)?.Catch_Rate;
|
||||
if (z is EncounterTradeCatchRate r && rate != r.Catch_Rate)
|
||||
if (z is EncounterTradeCatchRate r )
|
||||
{
|
||||
if (rate != r.Catch_Rate)
|
||||
continue;
|
||||
if (rate != PersonalTable.RB[z.Species].CatchRate && rate != PersonalTable.Y[z.Species].CatchRate)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (z.Version == GameVersion.YW && rate != PersonalTable.Y[z.Species].CatchRate)
|
||||
continue;
|
||||
if (z.Version != GameVersion.YW && rate != PersonalTable.RB[z.Species].CatchRate)
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return z;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
public static class EncounterVerifier
|
||||
{
|
||||
public static CheckResult VerifyEncounter(PKM pkm, IEncounterable encounter)
|
||||
public static CheckResult VerifyEncounter(PKM pkm, LegalInfo info, IEncounterable encounter)
|
||||
{
|
||||
if (encounter is EncounterEgg e)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ namespace PKHeX.Core
|
|||
if (encounter is EncounterTrade t)
|
||||
return VerifyEncounterTrade(pkm, t);
|
||||
if (encounter is EncounterSlot w)
|
||||
return VerifyEncounterWild(pkm, w);
|
||||
return VerifyEncounterWild(pkm, info, w);
|
||||
if (encounter is EncounterStatic s)
|
||||
return VerifyEncounterStatic(pkm, s, null);
|
||||
if (encounter is MysteryGift g)
|
||||
|
@ -25,7 +25,7 @@ namespace PKHeX.Core
|
|||
|
||||
return new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
|
||||
}
|
||||
public static CheckResult VerifyEncounterG12(PKM pkm, IEncounterable encounter)
|
||||
public static CheckResult VerifyEncounterG12(PKM pkm, LegalInfo info, IEncounterable encounter)
|
||||
{
|
||||
var EncounterMatch = encounter is GBEncounterData g ? g.Encounter : encounter;
|
||||
if (encounter.EggEncounter)
|
||||
|
@ -33,8 +33,12 @@ namespace PKHeX.Core
|
|||
pkm.WasEgg = true;
|
||||
return VerifyEncounterEgg(pkm, EncounterMatch);
|
||||
}
|
||||
if (EncounterMatch is EncounterSlot)
|
||||
if (EncounterMatch is EncounterSlot1 l)
|
||||
{
|
||||
if (info.Generation == 2)
|
||||
return VerifyWildEncounterGen2(pkm, l);
|
||||
return new CheckResult(Severity.Valid, V68, CheckIdentifier.Encounter);
|
||||
}
|
||||
if (EncounterMatch is EncounterStatic s)
|
||||
return VerifyEncounterStatic(pkm, s, null);
|
||||
if (EncounterMatch is EncounterTrade t)
|
||||
|
@ -43,6 +47,55 @@ namespace PKHeX.Core
|
|||
return new CheckResult(Severity.Invalid, V80, CheckIdentifier.Encounter);
|
||||
}
|
||||
|
||||
private static CheckResult VerifyWildEncounterGen2(PKM pkm, EncounterSlot1 encounter)
|
||||
{
|
||||
if (encounter.Type == SlotType.Old_Rod_Safari || encounter.Type == SlotType.Good_Rod_Safari || encounter.Type == SlotType.Super_Rod_Safari)
|
||||
// Fishing in the beta gen 2 safari zone
|
||||
return new CheckResult(Severity.Invalid, V609, CheckIdentifier.Encounter);
|
||||
|
||||
if (encounter.Version == GameVersion.C)
|
||||
return VerifyWildEncounterCrystal(pkm, encounter);
|
||||
|
||||
return new CheckResult(Severity.Valid, V68, CheckIdentifier.Encounter);
|
||||
}
|
||||
|
||||
private static CheckResult VerifyWildEncounterCrystal(PKM pkm, EncounterSlot1 encounter)
|
||||
{
|
||||
if(encounter.Type == SlotType.Headbutt || encounter.Type == SlotType.Headbutt_Special)
|
||||
{
|
||||
return VerifyWildEncounterCrystalHeadbutt(pkm, encounter);
|
||||
}
|
||||
if (encounter.Type == SlotType.Old_Rod || encounter.Type == SlotType.Good_Rod || encounter.Type == SlotType.Super_Rod)
|
||||
{
|
||||
if (encounter.Location == 19)
|
||||
// Fishing in National Park
|
||||
return new CheckResult(Severity.Invalid, V607, CheckIdentifier.Encounter);
|
||||
if (encounter.Location == 76)
|
||||
// Fishing in Route 14
|
||||
return new CheckResult(Severity.Invalid, V608, CheckIdentifier.Encounter);
|
||||
}
|
||||
|
||||
return new CheckResult(Severity.Valid, V68, CheckIdentifier.Encounter);
|
||||
}
|
||||
|
||||
private static CheckResult VerifyWildEncounterCrystalHeadbutt(PKM pkm, EncounterSlot1 encounter)
|
||||
{
|
||||
var Area = Legal.GetCrystalTreeArea(pkm, encounter);
|
||||
if (Area == null) // Failsafe, every area with headbutt encounters have a tree area
|
||||
return new CheckResult(Severity.Invalid, V605, CheckIdentifier.Encounter);
|
||||
var trainerpivot = pkm.TID % 10;
|
||||
var availabletree = encounter.Type == SlotType.Headbutt ? Area.TrainerModerateEncounterTree[trainerpivot] : Area.TrainerLowEncounterTree[trainerpivot];
|
||||
switch (availabletree)
|
||||
{
|
||||
case TreeEncounterAvailable.ValidTree:
|
||||
return new CheckResult(Severity.Valid, V604, CheckIdentifier.Encounter);
|
||||
case TreeEncounterAvailable.InvalidTree:
|
||||
return new CheckResult(Severity.Invalid, V604, CheckIdentifier.Encounter);
|
||||
default: //reeEncounterAvailable.Impossible
|
||||
return new CheckResult(Severity.Invalid, V605, CheckIdentifier.Encounter);
|
||||
}
|
||||
}
|
||||
|
||||
// Eggs
|
||||
private static CheckResult VerifyEncounterEgg(PKM pkm, IEncounterable egg)
|
||||
{
|
||||
|
@ -163,13 +216,13 @@ namespace PKHeX.Core
|
|||
}
|
||||
|
||||
// Etc
|
||||
private static CheckResult VerifyEncounterWild(PKM pkm, EncounterSlot slot)
|
||||
private static CheckResult VerifyEncounterWild(PKM pkm, LegalInfo info, EncounterSlot slot)
|
||||
{
|
||||
// Check for Unreleased Encounters / Collisions
|
||||
switch (pkm.GenNumber)
|
||||
{
|
||||
case 4:
|
||||
if (pkm.HasOriginalMetLocation && pkm.Met_Location == 193 && slot.Type == SlotType.Surf)
|
||||
if (slot.Location == 193 && slot.Type == SlotType.Surf)
|
||||
{
|
||||
// Pokemon surfing in Johto Route 45
|
||||
return new CheckResult(Severity.Invalid, V384, CheckIdentifier.Encounter);
|
||||
|
|
|
@ -182,7 +182,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, int[] Moves, LegalInfo info)
|
||||
{
|
||||
GameVersion[] games = (info.EncounterMatch as IGeneration)?.Generation == 1 ? Legal.GetGen1GameEncounter(pkm) : Legal.GetGen2GameEncounter(pkm);
|
||||
GameVersion[] games = (info.EncounterMatch as IGeneration)?.Generation == 1 ? Legal.GetGen1GameEncounter(pkm, info) : Legal.GetGen2GameEncounter(pkm, info);
|
||||
CheckMoveResult[] res = new CheckMoveResult[4];
|
||||
var G1Encounter = info.EncounterMatch;
|
||||
if (G1Encounter == null)
|
||||
|
|
|
@ -407,6 +407,12 @@ namespace PKHeX.Core
|
|||
public static string V601 { get; set; } = "Missing Ribbons: {0}";
|
||||
public static string V602 { get; set; } = "All ribbons accounted for.";
|
||||
public static string V603 { get; set; } = "Can't receive Ribbon(s) as an Egg.";
|
||||
public static string V604 { get; set; } = "Found a tree for crystal heabutt encounter that matches OTID";
|
||||
public static string V605 { get; set; } = "Found an unreacheable tree for crystal heabutt encounter that matches OTID.";
|
||||
public static string V606 { get; set; } = "Could not found a tree for crystal heabutt encounter that matches OTID.";
|
||||
public static string V607 { get; set; } = "Kanto Route 14 fishing encounter. Unreachable Water tiles.";
|
||||
public static string V608 { get; set; } = "National Park fishing encounter. Unreachable Water tiles.";
|
||||
public static string V609 { get; set; } = "Generation 2 safari zone fishing encounter. Unreachable zone.";
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
|
|
@ -67,6 +67,10 @@ namespace PKHeX.Core
|
|||
rates[i] = data[ofs++];
|
||||
|
||||
var slots = ReadSlots(data, ref ofs, slotSets * slotCount, t, rates[0]);
|
||||
for (int i = 0; i < slotCount; i++)
|
||||
{
|
||||
slots[i].Time = EncounterTime.Morning;
|
||||
}
|
||||
for (int r = 1; r < slotSets; r++)
|
||||
{
|
||||
for (int i = 0; i < slotCount; i++)
|
||||
|
@ -74,6 +78,7 @@ namespace PKHeX.Core
|
|||
int index = i + r*slotCount;
|
||||
slots[index].Rate = rates[r];
|
||||
slots[index].SlotNumber = i;
|
||||
slots[i].Time = r == 1 ? EncounterTime.Day : EncounterTime.Night;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,8 +116,11 @@ namespace PKHeX.Core
|
|||
// slot set ends in 0xFF
|
||||
var slots = new List<EncounterSlot1>();
|
||||
int tableCount = t == SlotType.Headbutt ? 2 : 1;
|
||||
SlotType slottype = t;
|
||||
while (tableCount != 0)
|
||||
{
|
||||
if (t == SlotType.Headbutt)
|
||||
slottype = tableCount == 2 ? SlotType.Headbutt_Special : SlotType.Headbutt;
|
||||
int rate = data[ofs++];
|
||||
if (rate == 0xFF) // end of table
|
||||
{
|
||||
|
@ -129,7 +137,7 @@ namespace PKHeX.Core
|
|||
Species = species,
|
||||
LevelMin = level,
|
||||
LevelMax = level,
|
||||
Type = t
|
||||
Type = slottype
|
||||
});
|
||||
}
|
||||
return slots.ToArray();
|
||||
|
@ -140,9 +148,10 @@ namespace PKHeX.Core
|
|||
var areas = new List<EncounterArea>();
|
||||
while (data[ofs] != 0xFF) // end
|
||||
{
|
||||
int _Location = data[ofs++] << 8 | data[ofs++];
|
||||
areas.Add(new EncounterArea
|
||||
{
|
||||
Location = data[ofs++] << 8 | data[ofs++],
|
||||
Location = _Location,
|
||||
Slots = GetSlots2_GW(data, ref ofs, t, slotSets, slotCount),
|
||||
});
|
||||
}
|
||||
|
@ -175,7 +184,6 @@ namespace PKHeX.Core
|
|||
var slot = slots[i];
|
||||
if (slot.Type != SlotType.Special)
|
||||
continue;
|
||||
|
||||
Array.Resize(ref slots, slots.Length + 1);
|
||||
Array.Copy(slots, i, slots, i+1, slots.Length - i - 1); // shift slots down
|
||||
slots[i+1] = slot.Clone(); // differentiate copied slot
|
||||
|
@ -183,10 +191,11 @@ namespace PKHeX.Core
|
|||
int index = slot.LevelMin*2;
|
||||
for (int j = 0; j < 2; j++) // load special slot info
|
||||
{
|
||||
var s = slots[i + j];
|
||||
var s = slots[i + j] as EncounterSlot1;
|
||||
s.Species = dl[index + j].Species;
|
||||
s.LevelMin = s.LevelMax = dl[index + j].Level;
|
||||
s.Type = slots[i - 1].Type; // special slots are never first in a set, so copy previous type
|
||||
s.Time = j == 0 ? EncounterTime.MorningDay : EncounterTime.Night;
|
||||
}
|
||||
}
|
||||
area.Slots = slots;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
}
|
||||
public class EncounterSlot : IEncounterable, IGeneration
|
||||
{
|
||||
public int Location { get; set; } = -1;
|
||||
public int Species { get; set; }
|
||||
public int Form { get; set; }
|
||||
public int LevelMin { get; set; }
|
||||
|
@ -54,6 +55,8 @@
|
|||
public class EncounterSlot1 : EncounterSlot
|
||||
{
|
||||
public int Rate;
|
||||
public EncounterTime Time = EncounterTime.Any;
|
||||
public GameVersion Version = GameVersion.Any;
|
||||
public override EncounterSlot Clone()
|
||||
{
|
||||
return new EncounterSlot1
|
||||
|
@ -64,7 +67,9 @@
|
|||
Type = Type,
|
||||
SlotNumber = SlotNumber,
|
||||
_perm = _perm,
|
||||
Rate = Rate
|
||||
Rate = Rate,
|
||||
Time = Time,
|
||||
Generation = Generation,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
32
PKHeX.Core/Legality/Structures/EncounterTime.cs
Normal file
32
PKHeX.Core/Legality/Structures/EncounterTime.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public enum EncounterTime
|
||||
{
|
||||
Any = -1,
|
||||
MorningDay = -2,
|
||||
Morning = 1,
|
||||
Day = 2,
|
||||
Night = 3
|
||||
}
|
||||
|
||||
public static class EncounterTimeExtension
|
||||
{
|
||||
public static bool Contains(this EncounterTime t1, int t2)
|
||||
{
|
||||
return t1.Contains((EncounterTime)t2);
|
||||
}
|
||||
private static bool Contains(this EncounterTime t1, EncounterTime t2)
|
||||
{
|
||||
if (t1 == t2 || t1 == EncounterTime.Any || t2 == EncounterTime.Any)
|
||||
return true;
|
||||
|
||||
if (t1 == EncounterTime.MorningDay)
|
||||
return (t2 == EncounterTime.Morning || t2 == EncounterTime.Day);
|
||||
|
||||
if (t2 == EncounterTime.MorningDay)
|
||||
return (t1 == EncounterTime.Morning || t1 == EncounterTime.Day);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
146
PKHeX.Core/Legality/Structures/TreesArea.cs
Normal file
146
PKHeX.Core/Legality/Structures/TreesArea.cs
Normal file
|
@ -0,0 +1,146 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
// Pokemon Crystal Headbutt tree encounters by trainer id, base on mechanics described in
|
||||
// https://bulbapedia.bulbagarden.net/wiki/Headbutt_tree#Mechanics
|
||||
|
||||
public enum TreeEncounterAvailable
|
||||
{
|
||||
ValidTree, // Encounter is possible a reacheable tree
|
||||
InvalidTree, // Encounter is only possible a tree reacheable only with walk-trought walls cheats
|
||||
Impossible // Encounter is not possible in any tree
|
||||
}
|
||||
|
||||
public class TreeCoordinates
|
||||
{
|
||||
internal int X { get; set; }
|
||||
internal int Y { get; set; }
|
||||
internal int Index => ((X * Y + X + Y) / 5) % 10;
|
||||
}
|
||||
|
||||
public class TreesArea
|
||||
{
|
||||
public int Location { get; private set; }
|
||||
public TreeEncounterAvailable[] TrainerModerateEncounterTree { get; private set; }
|
||||
public TreeEncounterAvailable[] TrainerLowEncounterTree { get; private set; }
|
||||
|
||||
private int[] ValidTreeIndex { get; set; }
|
||||
private int[] InvalidTreeIndex { get; set; }
|
||||
|
||||
private TreeCoordinates[] ValidTrees { get; set; }
|
||||
private TreeCoordinates[] InvalidTrees { get; set; }
|
||||
private static int[][] TrainerModerateTreeIndex { get; set; }
|
||||
|
||||
internal static TreesArea[] GetArray(byte[][] entries)
|
||||
{
|
||||
if (entries == null)
|
||||
return null;
|
||||
TrainerModerateTreeIndex = GenerateTrainersTreeIndex();
|
||||
var Areas = new TreesArea[entries.Length];
|
||||
for(int i = 0; i < entries.Length; i++)
|
||||
{
|
||||
Areas[i] = GetArea(entries[i]);
|
||||
}
|
||||
return Areas;
|
||||
}
|
||||
|
||||
private static int[][] GenerateTrainersTreeIndex()
|
||||
{
|
||||
// A tree have a low encounter or moderate encounter base on the TID Pivot Index ( TID % 10)
|
||||
// Calculate for every Trainer Pivot Index the 5 tree index for low encounters
|
||||
int[][] TrainersIndex = new int[10][];
|
||||
for (int pivotindex = 0; pivotindex < 10; pivotindex++)
|
||||
{
|
||||
int[] ModerateEncounterTreeIndex = new int[5];
|
||||
for(int index = 0; index <= 4; index++)
|
||||
ModerateEncounterTreeIndex[index] = (pivotindex + index) % 10;
|
||||
TrainersIndex[pivotindex] = ModerateEncounterTreeIndex.OrderBy(x => x).ToArray();
|
||||
}
|
||||
return TrainersIndex;
|
||||
}
|
||||
|
||||
private static TreesArea GetArea(byte[] entrie)
|
||||
{
|
||||
var Area = new TreesArea();
|
||||
|
||||
Area.ReadAreaRawData(entrie);
|
||||
Area.GenerateAreaTreeIndex();
|
||||
Area.GenerateAreaTrainerEncounters();
|
||||
return Area;
|
||||
}
|
||||
|
||||
private void ReadAreaRawData(byte[] entrie)
|
||||
{
|
||||
// Coordinates of trees for every are obtained with programa G2Map
|
||||
// ValidTrees are those accesible from the player
|
||||
// Invalid tress are trees that the player can not reach without cheating devices, like a tree beyond other trees
|
||||
Location = entrie[0];
|
||||
ValidTrees = new TreeCoordinates[entrie[1]];
|
||||
|
||||
var ofs = 2;
|
||||
for (int i = 0; i < ValidTrees.Length; i++)
|
||||
{
|
||||
ValidTrees[i] = new TreeCoordinates()
|
||||
{
|
||||
X = entrie[ofs],
|
||||
Y = entrie[ofs + 1]
|
||||
};
|
||||
ofs += 2;
|
||||
}
|
||||
InvalidTrees = new TreeCoordinates[entrie[ofs]];
|
||||
ofs += 1;
|
||||
for (int i = 0; i < InvalidTrees.Length; i++)
|
||||
{
|
||||
InvalidTrees[i] = new TreeCoordinates()
|
||||
{
|
||||
X = entrie[ofs],
|
||||
Y = entrie[ofs + 1]
|
||||
};
|
||||
ofs += 2;
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateAreaTreeIndex()
|
||||
{
|
||||
// For legallity purpose only the tree index is needed, group the trees data by their index, trees with the same index are indistinguible
|
||||
ValidTreeIndex = ValidTrees.Select(t => t.Index).Distinct().OrderBy(i => i).ToArray();
|
||||
InvalidTreeIndex = InvalidTrees.Select(t => t.Index).Distinct().OrderBy(i => i).Except(ValidTreeIndex).ToArray();
|
||||
}
|
||||
|
||||
private void GenerateAreaTrainerEncounters()
|
||||
{
|
||||
// Check for every trainer pivot index if there is trees with low encounter and moderate encounter available in the area
|
||||
TrainerModerateEncounterTree = new TreeEncounterAvailable[10];
|
||||
TrainerLowEncounterTree = new TreeEncounterAvailable[10];
|
||||
for (int pivotindex = 0; pivotindex < 10; pivotindex++)
|
||||
{
|
||||
var TrainerModerateTrees = TrainerModerateTreeIndex[pivotindex];
|
||||
|
||||
var ModerateValid = ValidTreeIndex.Any(t => TrainerModerateTrees.Contains(t));
|
||||
var ModerateInvalid = InvalidTreeIndex.Any(t => TrainerModerateTrees.Contains(t));
|
||||
if (ModerateValid)
|
||||
// There is a valid tree with an index for moderate encounters
|
||||
TrainerModerateEncounterTree[pivotindex] = TreeEncounterAvailable.ValidTree;
|
||||
else if (ModerateInvalid)
|
||||
// There is a tree with an index for moderate encounters but is invalid
|
||||
TrainerModerateEncounterTree[pivotindex] = TreeEncounterAvailable.InvalidTree;
|
||||
else
|
||||
// No trees for moderate encounters
|
||||
TrainerModerateEncounterTree[pivotindex] = TreeEncounterAvailable.Impossible;
|
||||
|
||||
var LowValid = ValidTreeIndex.Except(TrainerModerateTrees).Any();
|
||||
var LowInvalid = InvalidTreeIndex.Except(TrainerModerateTrees).Any();
|
||||
if (LowValid)
|
||||
// There is a valid tree with an index for low encounters
|
||||
TrainerLowEncounterTree[pivotindex] = TreeEncounterAvailable.ValidTree;
|
||||
else if (LowInvalid)
|
||||
// There is a tree with an index for low encounters but is invalid
|
||||
TrainerLowEncounterTree[pivotindex] = TreeEncounterAvailable.InvalidTree;
|
||||
else
|
||||
// No trees for low encounters
|
||||
TrainerLowEncounterTree[pivotindex] = TreeEncounterAvailable.Impossible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,14 +52,16 @@ namespace PKHeX.Core
|
|||
|
||||
internal static readonly EncounterStatic[] Encounter_RBY =
|
||||
{
|
||||
// Gameversion is RBY for pokemon with the same catch rate and initial moves in all games
|
||||
// If there are differents in moves or catch rate they will have different encounters defined
|
||||
new EncounterStatic { Species = 001, Level = 05, Version = GameVersion.RBY }, // Bulbasaur
|
||||
new EncounterStatic { Species = 004, Level = 05, Version = GameVersion.RBY }, // Charmander
|
||||
new EncounterStatic { Species = 007, Level = 05, Version = GameVersion.RBY }, // Squirtle
|
||||
new EncounterStatic { Species = 025, Level = 05, Version = GameVersion.YW }, // Pikachu
|
||||
|
||||
// Game Corner
|
||||
new EncounterStatic { Species = 030, Level = 17, Version = GameVersion.RBY }, // Nidorina (Red Game Corner)
|
||||
new EncounterStatic { Species = 033, Level = 17, Version = GameVersion.RBY }, // Nidorino (Blue[EN] / Green[JP] Game Corner)
|
||||
new EncounterStatic { Species = 030, Level = 17, Version = GameVersion.RB }, // Nidorina (Red Game Corner)
|
||||
new EncounterStatic { Species = 033, Level = 17, Version = GameVersion.BU }, // Nidorino (Blue[EN] / Green[JP] Game Corner)
|
||||
new EncounterStatic { Species = 035, Level = 08, Version = GameVersion.RBY }, // Clefairy (Red Game Corner)
|
||||
new EncounterStatic { Species = 036, Level = 24, Version = GameVersion.RBY }, // Clefable (Blue[JP] Game Corner)
|
||||
new EncounterStatic { Species = 037, Level = 18, Version = GameVersion.RBY }, // Vulpix (Yellow Game Corner)
|
||||
|
@ -67,19 +69,20 @@ namespace PKHeX.Core
|
|||
new EncounterStatic { Species = 063, Level = 06, Version = GameVersion.RBY }, // Abra (Blue[EN] / Green[JP] Game Corner)
|
||||
new EncounterStatic { Species = 116, Level = 18, Version = GameVersion.RBY }, // Horsea (Blue[JP] Game Corner)
|
||||
new EncounterStatic { Species = 123, Level = 25, Version = GameVersion.RBY }, // Scyther (Red Game Corner)
|
||||
new EncounterStatic { Species = 127, Level = 20, Version = GameVersion.RBY }, // Pinsir (Blue[EN] / Green[JP] Game Corner)
|
||||
new EncounterStatic { Species = 127, Level = 20, Version = GameVersion.BU }, // Pinsir (Blue[EN] / Green[JP] Game Corner)
|
||||
new EncounterStatic { Species = 127, Level = 30, Version = GameVersion.YW }, // Pinsir (Yellow Game Corner) (Different initial moves)
|
||||
new EncounterStatic { Species = 137, Level = 18, Version = GameVersion.RBY }, // Porygon (Blue[EN] / Green[JP] Game Corner)
|
||||
new EncounterStatic { Species = 147, Level = 18, Version = GameVersion.RBY }, // Dratini (Red Game Corner)
|
||||
new EncounterStatic { Species = 148, Level = 30, Version = GameVersion.RBY }, // Dragonair (Blue[JP] Game Corner)
|
||||
new EncounterStatic { Species = 148, Level = 30, Version = GameVersion.BU }, // Dragonair (Blue[JP] Game Corner)
|
||||
new EncounterStatic { Species = 025, Level = 12, Version = GameVersion.BU }, // Pikachu (Blue[JP] Game Corner) (Different catch rate)
|
||||
|
||||
|
||||
// Lower level less ideal matches; best match is from above.
|
||||
// new EncounterStatic { Species = 025, Level = 12 }, // Pikachu (Blue[JP] Game Corner)
|
||||
// new EncounterStatic { Species = 035, Level = 12 }, // Clefairy (Blue[EN] / Green[JP] Game Corner)
|
||||
// new EncounterStatic { Species = 063, Level = 09 }, // Abra (Red Game Corner)
|
||||
// new EncounterStatic { Species = 063, Level = 08 }, // Abra (Blue[JP] Game Corner)
|
||||
// new EncounterStatic { Species = 063, Level = 15 }, // Abra (Yellow Game Corner)
|
||||
// new EncounterStatic { Species = 123, Level = 30 }, // Scyther (Yellow Game Corner)
|
||||
// new EncounterStatic { Species = 127, Level = 30 }, // Pinsir (Yellow Game Corner)
|
||||
// new EncounterStatic { Species = 137, Level = 22 }, // Porygon (Blue[JP] Game Corner)
|
||||
// new EncounterStatic { Species = 137, Level = 26 }, // Porygon (Red Game Corner)
|
||||
// new EncounterStatic { Species = 137, Level = 26 }, // Porygon (Yellow Game Corner)
|
||||
|
@ -101,10 +104,10 @@ namespace PKHeX.Core
|
|||
|
||||
new EncounterStatic { Species = 150, Level = 70, Version = GameVersion.RBY }, // Mewtwo
|
||||
|
||||
new EncounterStatic { Species = 133, Level = 25, Version = GameVersion.RBY }, // Eevee
|
||||
new EncounterStatic { Species = 133, Level = 25, Version = GameVersion.RB }, // Eevee
|
||||
new EncounterStatic { Species = 133, Level = 25, Version = GameVersion.YW }, // Eevee (Different initial moves)
|
||||
|
||||
// Yellow Only -- duplicate encounters with a higher level
|
||||
// new EncounterStatic { Species = 133, Level = 25, Version = GameVersion.YW }, // Eevee (Celadon City)
|
||||
// new EncounterStatic { Species = 001, Level = 10, Version = GameVersion.YW }, // Bulbasaur (Cerulean City)
|
||||
// new EncounterStatic { Species = 004, Level = 10, Version = GameVersion.YW }, // Charmander (Route 24)
|
||||
// new EncounterStatic { Species = 007, Level = 10, Version = GameVersion.YW }, // Squirtle (Vermillion City)
|
||||
|
@ -124,64 +127,65 @@ namespace PKHeX.Core
|
|||
{
|
||||
// Species & Minimum level (legal) possible to acquire at.
|
||||
//new EncounterTrade { Species = 122, Generation = 1, Level = 06 }, // Mr. Mime - Game Corner Abra
|
||||
new EncounterTrade { Species = 032, Generation = 1, Level = 02 }, // Nidoran♂ - Wild Nidoran♀
|
||||
new EncounterTrade { Species = 029, Generation = 1, Level = 02 }, // Nidoran♀ - Wild Nidoran♂
|
||||
new EncounterTrade { Species = 030, Generation = 1, Level = 16 }, // Nidorina - Evolve Nidorino
|
||||
new EncounterTrade { Species = 108, Generation = 1, Level = 15 }, // Lickitung - Surf Slowbro
|
||||
new EncounterTrade { Species = 083, Generation = 1, Level = 02 }, // Farfetch’d - Wild Spearow
|
||||
new EncounterTrade { Species = 101, Generation = 1, Level = 03 }, // Electrode - Wild Raichu
|
||||
new EncounterTrade { Species = 032, Generation = 1, Level = 02, Version = GameVersion.RD }, // Nidoran♂ - Wild Nidoran♀
|
||||
new EncounterTrade { Species = 029, Generation = 1, Level = 02, Version = GameVersion.BU }, // Nidoran♀ - Wild Nidoran♂
|
||||
new EncounterTrade { Species = 030, Generation = 1, Level = 16, Version = GameVersion.RB }, // Nidorina - Evolve Nidorino
|
||||
new EncounterTrade { Species = 030, Generation = 1, Level = 16, Version = GameVersion.YW }, // Nidorina - Evolve Nidorino (Different initial moves)
|
||||
new EncounterTrade { Species = 108, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Lickitung - Surf Slowbro
|
||||
new EncounterTrade { Species = 083, Generation = 1, Level = 02, Version = GameVersion.RBY }, // Farfetch’d - Wild Spearow
|
||||
new EncounterTrade { Species = 101, Generation = 1, Level = 03, Version = GameVersion.RBY }, // Electrode - Wild Raichu
|
||||
|
||||
new EncounterTrade { Species = 122, Generation = 1, Level = 03 }, // Mr. Mime - Wild Jigglypuff
|
||||
new EncounterTrade { Species = 060, Generation = 1, Level = 02 }, // Poliwag - Wild Rattata
|
||||
new EncounterTrade { Species = 122, Generation = 1, Level = 03, Version = GameVersion.RBY }, // Mr. Mime - Wild Jigglypuff
|
||||
new EncounterTrade { Species = 060, Generation = 1, Level = 02, Version = GameVersion.RBY }, // Poliwag - Wild Rattata
|
||||
//new EncounterTrade { Species = 083, Generation = 1, Level = 02 }, // Farfetch’d - Wild Pidgey
|
||||
new EncounterTrade { Species = 079, Generation = 1, Level = 22 }, // Slowpoke - Wild Seel
|
||||
new EncounterTrade { Species = 079, Generation = 1, Level = 22, Version = GameVersion.RBY }, // Slowpoke - Wild Seel
|
||||
|
||||
new EncounterTrade { Species = 051, Generation = 1, Level = 15 }, // Dugtrio - Trade Lickitung
|
||||
new EncounterTrade { Species = 047, Generation = 1, Level = 13 }, // Parasect - Trade Tangela
|
||||
new EncounterTrade { Species = 051, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Dugtrio - Trade Lickitung
|
||||
new EncounterTrade { Species = 047, Generation = 1, Level = 13, Version = GameVersion.RBY }, // Parasect - Trade Tangela
|
||||
};
|
||||
internal static readonly EncounterTrade[] TradeGift_RBY_NoTradeback = TradeGift_RBY_Common.Concat(new[]
|
||||
{
|
||||
// Species & Minimum level (legal) possible to acquire at.
|
||||
new EncounterTrade { Species = 124, Generation = 1, Level = 15 }, // Jynx - Fish Poliwhirl (GSC: 10)
|
||||
new EncounterTrade { Species = 114, Generation = 1, Level = 13 }, // Tangela - Wild Venonat (GSC: 5)
|
||||
new EncounterTrade { Species = 086, Generation = 1, Level = 28 }, // Seel - Wild Ponyta (GSC: 6)
|
||||
new EncounterTrade { Species = 124, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Jynx - Fish Poliwhirl (GSC: 10)
|
||||
new EncounterTrade { Species = 114, Generation = 1, Level = 13, Version = GameVersion.RBY }, // Tangela - Wild Venonat (GSC: 5) No different moves at level 13
|
||||
new EncounterTrade { Species = 086, Generation = 1, Level = 28, Version = GameVersion.RBY }, // Seel - Wild Ponyta (GSC: 6)
|
||||
|
||||
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 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 = 115, Generation = 1, Level = 42, Version = GameVersion.RBY }, // Kangaskhan - Evolve Rhydon (GSC: 30)
|
||||
new EncounterTrade { Species = 128, Generation = 1, Level = 28, Version = GameVersion.RBY }, // Tauros - Evolve Persian (GSC: 18)
|
||||
new EncounterTradeCatchRate { Species = 093, Generation = 1, Level = 20, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Haunter - Trade Machoke (GSC: 10)
|
||||
new EncounterTradeCatchRate { Species = 075, Generation = 1, Level = 16, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Graveler - Evolve Kadabra (GSC: 15)
|
||||
new EncounterTradeCatchRate { Species = 098, Generation = 1, Level = 15, Catch_Rate = 204, Version = GameVersion.RBY }, // 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)
|
||||
new EncounterTrade { Species = 112, Generation = 1, Level = 15 }, // Rhydon - Surf Golduck (GSC: 10)
|
||||
new EncounterTrade { Species = 087, Generation = 1, Level = 15 }, // Dewgong - Wild Growlithe (GSC: 5)
|
||||
new EncounterTrade { Species = 089, Generation = 1, Level = 25 }, // Muk - Wild Kangaskhan (GSC: 14)
|
||||
new EncounterTradeCatchRate { Species = 067, Generation = 1, Level = 20, Catch_Rate = 180, EvolveOnTrade = true, Version = GameVersion.RBY }, // Machoke - Wild Cubone (GSC: 10)
|
||||
new EncounterTrade { Species = 112, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Rhydon - Surf Golduck (GSC: 10)
|
||||
new EncounterTrade { Species = 087, Generation = 1, Level = 15, Version = GameVersion.RBY }, // Dewgong - Wild Growlithe (GSC: 5)
|
||||
new EncounterTrade { Species = 089, Generation = 1, Level = 25, Version = GameVersion.RBY }, // Muk - Wild Kangaskhan (GSC: 14)
|
||||
}).ToArray();
|
||||
internal static readonly EncounterTrade[] TradeGift_RBY_Tradeback = TradeGift_RBY_Common.Concat(new[]
|
||||
{
|
||||
// Trade gifts that can be obtained at a lower level due to the requested Pokémon being a lower level in GSC
|
||||
new EncounterTrade { Species = 124, Generation = 1, Level = 10 }, // Jynx - Fish Poliwhirl (RBY: 15)
|
||||
new EncounterTrade { Species = 114, Generation = 1, Level = 05 }, // Tangela - Wild Venonat (RBY: 13)
|
||||
new EncounterTrade { Species = 086, Generation = 1, Level = 05 }, // Seel - Egg Ponyta (RBY: 28)
|
||||
new EncounterTrade { Species = 124, Generation = 1, Level = 10, Version = GameVersion.RBY }, // Jynx - Fish Poliwhirl (RBY: 15)
|
||||
new EncounterTrade { Species = 114, Generation = 1, Level = 05, Version = GameVersion.RBY }, // Tangela - Wild Venonat (RBY: 13)
|
||||
new EncounterTrade { Species = 086, Generation = 1, Level = 05, Version = GameVersion.RBY }, // Seel - Egg Ponyta (RBY: 28)
|
||||
|
||||
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 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 = 115, Generation = 1, Level = 30, Version = GameVersion.RBY }, // Kangaskhan - Evolve Rhydon (RBY: 42)
|
||||
new EncounterTrade { Species = 128, Generation = 1, Level = 18, Version = GameVersion.RBY }, // Tauros - Evolve Persian (RBY: 28)
|
||||
new EncounterTradeCatchRate { Species = 093, Generation = 1, Level = 10, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Haunter - Trade Machoke (RBY: 20)
|
||||
new EncounterTradeCatchRate { Species = 075, Generation = 1, Level = 15, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Graveler - Evolve Kadabra (RBY: 16)
|
||||
new EncounterTradeCatchRate { Species = 098, Generation = 1, Level = 05, Catch_Rate = 204, Version = GameVersion.RBY }, // 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)
|
||||
new EncounterTrade { Species = 112, Generation = 1, Level = 10 }, // Rhydon - Surf Golduck (RBY: 15)
|
||||
new EncounterTrade { Species = 087, Generation = 1, Level = 05 }, // Dewgong - Egg Growlithe (RBY: 15)
|
||||
new EncounterTrade { Species = 089, Generation = 1, Level = 05 }, // Muk - Egg Kangaskhan (RBY: 25)
|
||||
new EncounterTradeCatchRate { Species = 067, Generation = 1, Level = 05, Catch_Rate = 180, EvolveOnTrade = true, Version = GameVersion.RBY }, // Machoke - Egg Cubone (RBY: 20)
|
||||
new EncounterTrade { Species = 112, Generation = 1, Level = 10, Version = GameVersion.RBY }, // Rhydon - Surf Golduck (RBY: 15)
|
||||
new EncounterTrade { Species = 087, Generation = 1, Level = 05, Version = GameVersion.RBY }, // Dewgong - Egg Growlithe (RBY: 15)
|
||||
new EncounterTrade { Species = 089, Generation = 1, Level = 05, Version = GameVersion.RBY }, // Muk - Egg Kangaskhan (RBY: 25)
|
||||
}).ToArray();
|
||||
internal static readonly EncounterArea FishOldGood_RBY = new EncounterArea { Location = -1, Slots = new EncounterSlot[]
|
||||
{
|
||||
new EncounterSlot1 {Species = 129, LevelMin = 05, LevelMax = 05, Type = SlotType.Old_Rod, Rate = -1, }, // Magikarp
|
||||
new EncounterSlot1 {Species = 118, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, }, // Goldeen
|
||||
new EncounterSlot1 {Species = 060, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, }, // Poliwag
|
||||
new EncounterSlot1 {Species = 129, LevelMin = 05, LevelMax = 05, Type = SlotType.Old_Rod, Rate = -1, Version = GameVersion.RBY }, // Magikarp
|
||||
new EncounterSlot1 {Species = 118, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, Version = GameVersion.RBY }, // Goldeen
|
||||
new EncounterSlot1 {Species = 060, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, Version = GameVersion.RBY }, // Poliwag
|
||||
}};
|
||||
|
||||
internal static readonly int[] FutureEvolutionsGen1 =
|
||||
|
|
|
@ -69,6 +69,24 @@ namespace PKHeX.Core
|
|||
new EncounterSlot1 {Species = 127, LevelMin = 13, LevelMax = 14, Rate = 05, SlotNumber = 9}, // Pinsir
|
||||
}
|
||||
}};
|
||||
|
||||
internal static readonly EncounterArea[] EncounterSafari_GSC = { new EncounterArea {
|
||||
Location = 81,
|
||||
Slots = new EncounterSlot[]
|
||||
{
|
||||
new EncounterSlot1 {Species = 129, LevelMin = 10, LevelMax = 10, Type = SlotType.Old_Rod_Safari}, // Magikarp
|
||||
new EncounterSlot1 {Species = 098, LevelMin = 10, LevelMax = 10, Type = SlotType.Old_Rod_Safari}, // Krabby
|
||||
new EncounterSlot1 {Species = 098, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod_Safari}, // Krabby
|
||||
new EncounterSlot1 {Species = 129, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod_Safari}, // Magikarp
|
||||
new EncounterSlot1 {Species = 222, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod_Safari}, // Corsola
|
||||
new EncounterSlot1 {Species = 120, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod_Safari}, // Staryu
|
||||
new EncounterSlot1 {Species = 098, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod_Safari}, // Krabby
|
||||
new EncounterSlot1 {Species = 222, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod_Safari}, // Corsola
|
||||
new EncounterSlot1 {Species = 120, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod_Safari}, // Staryu
|
||||
new EncounterSlot1 {Species = 121, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod_Safari}, // Kingler
|
||||
}
|
||||
}};
|
||||
|
||||
internal static readonly EncounterStatic[] Encounter_GSC_Common =
|
||||
{
|
||||
new EncounterStatic { Species = 152, Level = 05, Location = 001, Version = GameVersion.GSC }, // Chikorita @ New Bark Town
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
<None Remove="Resources\byte\personal_xy" />
|
||||
<None Remove="Resources\byte\personal_y" />
|
||||
<None Remove="Resources\byte\pgf.pkl" />
|
||||
<None Remove="Resources\byte\trees_h_c.pkl" />
|
||||
<None Remove="Resources\byte\tutors_g3.pkl" />
|
||||
<None Remove="Resources\byte\tutors_g4.pkl" />
|
||||
<None Remove="Resources\byte\wc6.pkl" />
|
||||
|
@ -192,6 +193,7 @@
|
|||
<EmbeddedResource Include="Resources\byte\personal_xy" />
|
||||
<EmbeddedResource Include="Resources\byte\personal_y" />
|
||||
<EmbeddedResource Include="Resources\byte\pgf.pkl" />
|
||||
<EmbeddedResource Include="Resources\byte\trees_h_c.pkl" />
|
||||
<EmbeddedResource Include="Resources\byte\tutors_g3.pkl" />
|
||||
<EmbeddedResource Include="Resources\byte\tutors_g4.pkl" />
|
||||
<EmbeddedResource Include="Resources\byte\wc6.pkl" />
|
||||
|
|
BIN
PKHeX.Core/Resources/byte/trees_h_c.pkl
Normal file
BIN
PKHeX.Core/Resources/byte/trees_h_c.pkl
Normal file
Binary file not shown.
|
@ -344,3 +344,9 @@ V602 = All ribbons accounted for.
|
|||
V600 = Missing Ribbons: {0}
|
||||
V601 = Invalid Ribbons: {0}
|
||||
V603 = Can't receive Ribbon(s) as an Egg.
|
||||
V604 = Found a tree for crystal heabutt encounter that matches OTID.
|
||||
V605 = Found an unreacheable tree for crystal heabutt encounter that matches OTID.
|
||||
V606 = Could not found a tree for crystal heabutt encounter that matches OTID.
|
||||
V607 = Kanto Route 14 fishing encounter. Unreachable Water tiles.
|
||||
V608 = National Park fishing encounter. Unreachable Water tiles.
|
||||
V609 = Generation 2 safari zone fishing encounter. Unreachable zone.
|
||||
|
|
|
@ -344,3 +344,9 @@ V602 = 모든 리본이 채워졌습니다.
|
|||
V600 = 없는 리본: {0}
|
||||
V601 = 사용할 수 없는 리본: {0}
|
||||
V603 = 알은 리본을 얻을 수 없습니다.
|
||||
V604 = Found a tree for crystal heabutt encounter that matches OTID.
|
||||
V605 = Found an unreacheable tree for crystal heabutt encounter that matches OTID.
|
||||
V606 = Could not found a tree for crystal heabutt encounter that matches OTID.
|
||||
V607 = Kanto Route 14 fishing encounter. Unreachable Water tiles.
|
||||
V608 = National Park fishing encounter. Unreachable Water tiles.
|
||||
V609 = Generation 2 safari zone fishing encounter. Unreachable zone.
|
|
@ -344,3 +344,9 @@ V602 = 所有奖章合法。
|
|||
V600 = 缺失奖章: {0}
|
||||
V601 = 不合法奖章: {0}
|
||||
V603 = 蛋不能接受奖章。
|
||||
V604 = Found a tree for crystal heabutt encounter that matches OTID.
|
||||
V605 = Found an unreacheable tree for crystal heabutt encounter that matches OTID.
|
||||
V606 = Could not found a tree for crystal heabutt encounter that matches OTID.
|
||||
V607 = Kanto Route 14 fishing encounter. Unreachable Water tiles.
|
||||
V608 = National Park fishing encounter. Unreachable Water tiles.
|
||||
V609 = Generation 2 safari zone fishing encounter. Unreachable zone.
|
Loading…
Add table
Reference in a new issue