diff --git a/PKHeX.Core/Editing/Applicators/CatchRateApplicator.cs b/PKHeX.Core/Editing/Applicators/CatchRateApplicator.cs
new file mode 100644
index 000000000..f0cd809d4
--- /dev/null
+++ b/PKHeX.Core/Editing/Applicators/CatchRateApplicator.cs
@@ -0,0 +1,40 @@
+namespace PKHeX.Core
+{
+ ///
+ /// Logic for applying a value.
+ ///
+ public static class CatchRateApplicator
+ {
+ public static int GetSuggestedCatchRate(PK1 pk1, SaveFile sav)
+ {
+ var la = new LegalityAnalysis(pk1);
+ return GetSuggestedCatchRate(pk1, sav, la);
+ }
+
+ public static int GetSuggestedCatchRate(PK1 pk1, SaveFile sav, LegalityAnalysis la)
+ {
+ if (la.Valid)
+ return pk1.Catch_Rate;
+
+ if (la.Info.Generation == 2)
+ return 0;
+
+ var v = la.EncounterOriginal;
+ switch (v)
+ {
+ case EncounterTrade1 c:
+ return c.GetInitialCatchRate();
+ case EncounterStatic s when s.Version == GameVersion.Stadium && s.Species == (int)Species.Psyduck:
+ return pk1.Japanese ? 167 : 168; // Amnesia Psyduck has different catch rates depending on language
+ default:
+ {
+ if (sav.Version.Contains(v.Version) || v.Version.Contains(sav.Version))
+ return sav.Personal[v.Species].CatchRate;
+ if (!GameVersion.RB.Contains(v.Version))
+ return PersonalTable.Y[v.Species].CatchRate;
+ return PersonalTable.RB[v.Species].CatchRate;
+ }
+ }
+ }
+ }
+}
diff --git a/PKHeX.Core/Legality/Encounters/Data/EncounterUtil.cs b/PKHeX.Core/Legality/Encounters/Data/EncounterUtil.cs
index 424c18228..f130982a5 100644
--- a/PKHeX.Core/Legality/Encounters/Data/EncounterUtil.cs
+++ b/PKHeX.Core/Legality/Encounters/Data/EncounterUtil.cs
@@ -252,7 +252,7 @@ namespace PKHeX.Core
return result;
}
- internal static void MarkEncounterTradeStrings(EncounterTrade[] table, string[][] strings)
+ internal static void MarkEncounterTradeStrings(T[] table, string[][] strings) where T : EncounterTrade
{
int half = strings[1].Length / 2;
for (int i = 0; i < half; i++)
diff --git a/PKHeX.Core/Legality/Encounters/Data/Encounters1.cs b/PKHeX.Core/Legality/Encounters/Data/Encounters1.cs
index 39b827d38..981964dcc 100644
--- a/PKHeX.Core/Legality/Encounters/Data/Encounters1.cs
+++ b/PKHeX.Core/Legality/Encounters/Data/Encounters1.cs
@@ -1,5 +1,4 @@
using System;
-using System.Linq;
using static PKHeX.Core.EncounterUtil;
namespace PKHeX.Core
@@ -19,7 +18,7 @@ namespace PKHeX.Core
MarkEncountersGeneration(1, SlotsRBY);
MarkEncountersGeneration(1, StaticRBY, TradeGift_RBY_NoTradeback, TradeGift_RBY_Tradeback);
- var trades = TradeGift_RBY_Common.Concat(TradeGift_RBY_NoTradeback).Concat(TradeGift_RBY_Tradeback);
+ var trades = ArrayUtil.ConcatAll(TradeGift_RBY_Common, TradeGift_RBY_NoTradeback, TradeGift_RBY_Tradeback);
foreach (var t in trades)
{
t.TrainerNames = TradeOTG1;
@@ -136,74 +135,73 @@ namespace PKHeX.Core
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 =
+ internal static readonly EncounterTrade1[] TradeGift_RBY_Common =
{
// Species & Minimum level (legal) possible to acquire at.
//new EncounterTrade { Species = 122, Level = 06 }, // Mr. Mime - Game Corner Abra
- new EncounterTrade { Species = 032, Level = 02, Version = GameVersion.RD }, // Nidoran♂ - Wild Nidoran♀
- new EncounterTrade { Species = 029, Level = 02, Version = GameVersion.BU }, // Nidoran♀ - Wild Nidoran♂
- new EncounterTrade { Species = 030, Level = 16, Version = GameVersion.RB }, // Nidorina - Evolve Nidorino
- new EncounterTrade { Species = 030, Level = 16, Version = GameVersion.YW }, // Nidorina - Evolve Nidorino (Different initial moves)
- new EncounterTrade { Species = 108, Level = 15, Version = GameVersion.RBY }, // Lickitung - Surf Slowbro
- new EncounterTrade { Species = 083, Level = 02, Version = GameVersion.RBY }, // Farfetch’d - Wild Spearow
- new EncounterTrade { Species = 101, Level = 03, Version = GameVersion.RBY }, // Electrode - Wild Raichu
+ new EncounterTrade1(032, 02) { Version = GameVersion.RD }, // Nidoran♂ - Wild Nidoran♀
+ new EncounterTrade1(029, 02) { Version = GameVersion.BU }, // Nidoran♀ - Wild Nidoran♂
+ new EncounterTrade1(030, 16) { Version = GameVersion.RB }, // Nidorina - Evolve Nidorino
+ new EncounterTrade1(030, 16) { Version = GameVersion.YW }, // Nidorina - Evolve Nidorino (Different initial moves)
+ new EncounterTrade1(108, 15) { Version = GameVersion.RBY }, // Lickitung - Surf Slowbro
+ new EncounterTrade1(083, 02) { Version = GameVersion.RBY }, // Farfetch’d - Wild Spearow
+ new EncounterTrade1(101, 03) { Version = GameVersion.RBY }, // Electrode - Wild Raichu
- new EncounterTrade { Species = 122, Level = 03, Version = GameVersion.RBY }, // Mr. Mime - Wild Jigglypuff
- new EncounterTrade { Species = 060, Level = 02, Version = GameVersion.RBY }, // Poliwag - Wild Rattata
+ new EncounterTrade1(122, 03) { Version = GameVersion.RBY }, // Mr. Mime - Wild Jigglypuff
+ new EncounterTrade1(060, 02) { Version = GameVersion.RBY }, // Poliwag - Wild Rattata
//new EncounterTrade { Species = 083, Level = 02 }, // Farfetch’d - Wild Pidgey
- new EncounterTradeCatchRate { Species = 093, Level = 28, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Haunter - Evolve Machop->Machoke
- new EncounterTradeCatchRate { Species = 075, Level = 16, Catch_Rate = 45, EvolveOnTrade = true, Version = GameVersion.RBY }, // Graveler - Evolve Abra->Kadabra
+ new EncounterTrade1(093, 28, 45) { EvolveOnTrade = true, Version = GameVersion.RBY }, // Haunter - Evolve Machop->Machoke
+ new EncounterTrade1(075, 16, 45) { EvolveOnTrade = true, Version = GameVersion.RBY }, // Graveler - Evolve Abra->Kadabra
};
- internal static readonly EncounterTrade[] TradeGift_RBY_NoTradeback = TradeGift_RBY_Common.Concat(new[]
+ internal static readonly EncounterTrade1[] TradeGift_RBY_NoTradeback = ArrayUtil.ConcatAll(TradeGift_RBY_Common, new[]
{
// Species & Minimum level (legal) possible to acquire at.
- new EncounterTrade { Species = 124, Level = 15, Version = GameVersion.RBY }, // Jynx - Fish Poliwhirl (GSC: 10)
- new EncounterTrade { Species = 114, Level = 13, Version = GameVersion.RBY }, // Tangela - Wild Venonat (GSC: 5) No different moves at level 13
- new EncounterTrade { Species = 086, Level = 28, Version = GameVersion.RBY }, // Seel - Wild Ponyta (GSC: 5)
+ new EncounterTrade1(124, 15) { Version = GameVersion.RBY }, // Jynx - Fish Poliwhirl (GSC: 10)
+ new EncounterTrade1(114, 13) { Version = GameVersion.RBY }, // Tangela - Wild Venonat (GSC: 5) No different moves at level 13
+ new EncounterTrade1(086, 28) { Version = GameVersion.RBY }, // Seel - Wild Ponyta (GSC: 5)
- new EncounterTrade { Species = 115, Level = 15, Version = GameVersion.RBY }, // Kangaskhan - Trade Rhydon (GSC: 10)
- new EncounterTrade { Species = 128, Level = 28, Version = GameVersion.RBY }, // Tauros - Evolve Persian (GSC: 18)
- new EncounterTradeCatchRate { Species = 098, Level = 15, Catch_Rate = 204, Version = GameVersion.RBY }, // Krabby - Wild Growlithe (GSC: 5)
+ new EncounterTrade1(115, 15) { Version = GameVersion.RBY }, // Kangaskhan - Trade Rhydon (GSC: 10)
+ new EncounterTrade1(128, 28) { Version = GameVersion.RBY }, // Tauros - Evolve Persian (GSC: 18)
+ new EncounterTrade1(098, 15, 204) { Version = GameVersion.RBY }, // Krabby - Wild Growlithe (GSC: 5)
//new EncounterTrade { Species = 122, Level = 08 }, // Mr. Mime - Wild Clefairy (GSC: 6)
- new EncounterTrade { Species = 067, Level = 16, Version = GameVersion.RBY, EvolveOnTrade = true }, // Machoke - Wild Cubone (GSC: 5)
- new EncounterTrade { Species = 112, Level = 15, Version = GameVersion.RBY }, // Rhydon - Surf Golduck (GSC: 10)
- new EncounterTrade { Species = 087, Level = 15, Version = GameVersion.RBY }, // Dewgong - Wild Growlithe (GSC: 5)
- new EncounterTrade { Species = 089, Level = 25, Version = GameVersion.RBY }, // Muk - Wild Kangaskhan (GSC: 5)
+ new EncounterTrade1(067, 16) { Version = GameVersion.RBY, EvolveOnTrade = true }, // Machoke - Wild Cubone (GSC: 5)
+ new EncounterTrade1(112, 15) { Version = GameVersion.RBY }, // Rhydon - Surf Golduck (GSC: 10)
+ new EncounterTrade1(087, 15) { Version = GameVersion.RBY }, // Dewgong - Wild Growlithe (GSC: 5)
+ new EncounterTrade1(089, 25) { Version = GameVersion.RBY }, // Muk - Wild Kangaskhan (GSC: 5)
+ new EncounterTrade1(079, 22) { Version = GameVersion.RBY }, // Slowpoke - Wild Seel (GSC 5)
+ new EncounterTrade1(051, 15) { Version = GameVersion.RBY }, // Dugtrio - Trade Lickitung (GSC 5)
+ new EncounterTrade1(047, 13) { Version = GameVersion.RBY }, // Parasect - Trade Tangela (GSC 5)
+ });
- new EncounterTrade { Species = 079, Level = 22, Version = GameVersion.RBY }, // Slowpoke - Wild Seel (GSC 5)
- new EncounterTrade { Species = 051, Level = 15, Version = GameVersion.RBY }, // Dugtrio - Trade Lickitung (GSC 5)
- new EncounterTrade { Species = 047, Level = 13, Version = GameVersion.RBY }, // Parasect - Trade Tangela (GSC 5)
- }).ToArray();
-
- internal static readonly EncounterTrade[] TradeGift_RBY_Tradeback = TradeGift_RBY_Common.Concat(new[]
+ internal static readonly EncounterTrade1[] TradeGift_RBY_Tradeback = ArrayUtil.ConcatAll(TradeGift_RBY_Common, 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, Level = 10, Version = GameVersion.RBY }, // Jynx - Fish Poliwhirl (RBY: 15)
- new EncounterTrade { Species = 114, Level = 05, Version = GameVersion.RBY }, // Tangela - Wild Venonat (RBY: 13)
- new EncounterTrade { Species = 086, Level = 05, Version = GameVersion.RBY }, // Seel - Egg Ponyta (RBY: 28)
+ new EncounterTrade1(124, 10) { Version = GameVersion.RBY }, // Jynx - Fish Poliwhirl (RBY: 15)
+ new EncounterTrade1(114, 05) { Version = GameVersion.RBY }, // Tangela - Wild Venonat (RBY: 13)
+ new EncounterTrade1(086, 05) { Version = GameVersion.RBY }, // Seel - Egg Ponyta (RBY: 28)
- new EncounterTrade { Species = 115, Level = 10, Version = GameVersion.RBY }, // Kangaskhan - Trade Rhydon (RBY: 42)
- new EncounterTrade { Species = 128, Level = 18, Version = GameVersion.RBY }, // Tauros - Evolve Persian (RBY: 28)
- new EncounterTradeCatchRate { Species = 098, Level = 05, Catch_Rate = 204, Version = GameVersion.RBY }, // Krabby - Egg Growlithe (RBY: 15)
+ new EncounterTrade1(115, 10) { Version = GameVersion.RBY }, // Kangaskhan - Trade Rhydon (RBY: 42)
+ new EncounterTrade1(128, 18) { Version = GameVersion.RBY }, // Tauros - Evolve Persian (RBY: 28)
+ new EncounterTrade1(098, 05, 204) { Version = GameVersion.RBY }, // Krabby - Egg Growlithe (RBY: 15)
- //new EncounterTrade { Species = 122, Level = 08 }, // Mr. Mime - Wild Clefairy (RBY: 6)
- new EncounterTrade { Species = 067, Level = 05, Version = GameVersion.RBY, EvolveOnTrade = true }, // Machoke - Egg Cubone (RBY: 20)
- new EncounterTrade { Species = 112, Level = 10, Version = GameVersion.RBY }, // Rhydon - Surf Golduck (RBY: 15)
- new EncounterTrade { Species = 087, Level = 05, Version = GameVersion.RBY }, // Dewgong - Egg Growlithe (RBY: 15)
- new EncounterTrade { Species = 089, Level = 05, Version = GameVersion.RBY }, // Muk - Egg Kangaskhan (RBY: 25)
+ //new EncounterTrade1(122, 08), // Mr. Mime - Wild Clefairy (RBY: 6)
+ new EncounterTrade1(067, 05) { Version = GameVersion.RBY, EvolveOnTrade = true }, // Machoke - Egg Cubone (RBY: 20)
+ new EncounterTrade1(112, 10) { Version = GameVersion.RBY }, // Rhydon - Surf Golduck (RBY: 15)
+ new EncounterTrade1(087, 05) { Version = GameVersion.RBY }, // Dewgong - Egg Growlithe (RBY: 15)
+ new EncounterTrade1(089, 05) { Version = GameVersion.RBY }, // Muk - Egg Kangaskhan (RBY: 25)
- new EncounterTrade { Species = 079, Level = 05, Version = GameVersion.RBY }, // Slowpoke - Wild Seel (GSC 5)
- new EncounterTrade { Species = 051, Level = 05, Version = GameVersion.RBY }, // Dugtrio - Trade Lickitung (GSC 5)
- new EncounterTrade { Species = 047, Level = 05, Version = GameVersion.RBY }, // Parasect - Trade Tangela (GSC 5)
- }).ToArray();
+ new EncounterTrade1(079, 05) { Version = GameVersion.RBY }, // Slowpoke - Wild Seel (GSC 5)
+ new EncounterTrade1(051, 05) { Version = GameVersion.RBY }, // Dugtrio - Trade Lickitung (GSC 5)
+ new EncounterTrade1(047, 05) { Version = GameVersion.RBY }, // Parasect - Trade Tangela (GSC 5)
+ });
private static readonly EncounterArea1 FishOldGood_RBY = new EncounterArea1
{
Location = -1,
- Slots = new[]
+ Slots = new EncounterSlot[]
{
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
diff --git a/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs b/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs
index 061a26b3f..4f5374c0c 100644
--- a/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs
+++ b/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs
@@ -10,7 +10,7 @@ namespace PKHeX.Core
internal static class Encounters2
{
internal static readonly EncounterArea2[] SlotsGSC, SlotsGS, SlotsC;
- internal static readonly EncounterStatic[] StaticGSC, StaticGS, StaticC;
+ internal static readonly EncounterStatic2[] StaticGSC, StaticGS, StaticC;
private static readonly TreesArea[] HeadbuttTreesC = TreesArea.GetArray(BinLinker.Unpack(Util.GetBinaryResource("trees_h_c.pkl"), "ch"));
static Encounters2()
@@ -94,13 +94,6 @@ namespace PKHeX.Core
return extra;
}
- private static readonly int[] Roaming_MetLocation_GSC_Grass =
- {
- // Routes 29, 30-31, 33, 34, 35, 36-37, 38-39, 42, 43, 44, 45-46 can be encountered in grass
- 2, 4, 5, 8, 11, 15, 18, 20, 21,
- 25, 26, 34, 37, 39, 43, 45,
- };
-
private static readonly EncounterArea2[] EncounterBCC_GSC = { new EncounterArea2 {
Location = 19,
Slots = new EncounterSlot[]
@@ -135,84 +128,84 @@ namespace PKHeX.Core
}
}};
- private static readonly EncounterStatic[] Encounter_GSC_Common =
+ private static readonly EncounterStatic2[] Encounter_GSC_Common =
{
- new EncounterStatic { Species = 152, Level = 05, Location = 001, Version = GameVersion.GSC }, // Chikorita @ New Bark Town
- new EncounterStatic { Species = 155, Level = 05, Location = 001, Version = GameVersion.GSC }, // Cyndaquil @ New Bark Town
- new EncounterStatic { Species = 158, Level = 05, Location = 001, Version = GameVersion.GSC }, // Totodile @ New Bark Town
+ new EncounterStatic2(152, 05) { Location = 001, Version = GameVersion.GSC }, // Chikorita @ New Bark Town
+ new EncounterStatic2(155, 05) { Location = 001, Version = GameVersion.GSC }, // Cyndaquil @ New Bark Town
+ new EncounterStatic2(158, 05) { Location = 001, Version = GameVersion.GSC }, // Totodile @ New Bark Town
- new EncounterStatic { Species = 175, Level = 05, Version = GameVersion.GSC, EggLocation = 256 }, // Togepi
- new EncounterStatic { Species = 131, Level = 20, Location = 010, Version = GameVersion.GSC }, // Lapras @ Union Cave
- new EncounterStatic { Species = 133, Level = 20, Location = 016, Version = GameVersion.GSC }, // Eevee @ Goldenrod City
+ new EncounterStatic2(175, 05) { Version = GameVersion.GSC, EggLocation = 256 }, // Togepi
+ new EncounterStatic2(131, 20) { Location = 010, Version = GameVersion.GSC }, // Lapras @ Union Cave
+ new EncounterStatic2(133, 20) { Location = 016, Version = GameVersion.GSC }, // Eevee @ Goldenrod City
- new EncounterStatic { Species = 185, Level = 20, Location = 020, Version = GameVersion.GSC }, // Sudowoodo @ Route 36
- new EncounterStatic { Species = 236, Level = 10, Location = 035, Version = GameVersion.GSC }, // Tyrogue @ Mt. Mortar
+ new EncounterStatic2(185, 20) { Location = 020, Version = GameVersion.GSC }, // Sudowoodo @ Route 36
+ new EncounterStatic2(236, 10) { Location = 035, Version = GameVersion.GSC }, // Tyrogue @ Mt. Mortar
- new EncounterStatic { Species = 130, Level = 30, Location = 038, Version = GameVersion.GSC, Shiny = Shiny.Always, }, // Gyarados @ Lake of Rage
- new EncounterStatic { Species = 074, Level = 21, Location = 036, Version = GameVersion.GSC }, // Geodude @ Rocket Hideout (Mahogany Town)
- new EncounterStatic { Species = 109, Level = 21, Location = 036, Version = GameVersion.GSC }, // Koffing @ Rocket Hideout (Mahogany Town)
- new EncounterStatic { Species = 100, Level = 23, Location = 036, Version = GameVersion.GSC }, // Voltorb @ Rocket Hideout (Mahogany Town)
- new EncounterStatic { Species = 101, Level = 23, Location = 036, Version = GameVersion.GSC }, // Electrode @ Rocket Hideout (Mahogany Town)
- new EncounterStatic { Species = 143, Level = 50, Location = 061, Version = GameVersion.GSC }, // Snorlax @ Vermillion City
+ new EncounterStatic2(130, 30) { Location = 038, Version = GameVersion.GSC, Shiny = Shiny.Always, }, // Gyarados @ Lake of Rage
+ new EncounterStatic2(074, 21) { Location = 036, Version = GameVersion.GSC }, // Geodude @ Rocket Hideout (Mahogany Town)
+ new EncounterStatic2(109, 21) { Location = 036, Version = GameVersion.GSC }, // Koffing @ Rocket Hideout (Mahogany Town)
+ new EncounterStatic2(100, 23) { Location = 036, Version = GameVersion.GSC }, // Voltorb @ Rocket Hideout (Mahogany Town)
+ new EncounterStatic2(101, 23) { Location = 036, Version = GameVersion.GSC }, // Electrode @ Rocket Hideout (Mahogany Town)
+ new EncounterStatic2(143, 50) { Location = 061, Version = GameVersion.GSC }, // Snorlax @ Vermillion City
- new EncounterStatic { Species = 211, Level = 05, Location = 008, Version = GameVersion.GSC }, // Qwilfish Swarm @ Route 32 (Old Rod)
- new EncounterStatic { Species = 211, Level = 20, Location = 008, Version = GameVersion.GSC }, // Qwilfish Swarm @ Route 32 (Good Rod)
- new EncounterStatic { Species = 211, Level = 40, Location = 008, Version = GameVersion.GSC }, // Qwilfish Swarm @ Route 32 (Super Rod)
+ new EncounterStatic2(211, 05) { Location = 008, Version = GameVersion.GSC }, // Qwilfish Swarm @ Route 32 (Old Rod)
+ new EncounterStatic2(211, 20) { Location = 008, Version = GameVersion.GSC }, // Qwilfish Swarm @ Route 32 (Good Rod)
+ new EncounterStatic2(211, 40) { Location = 008, Version = GameVersion.GSC }, // Qwilfish Swarm @ Route 32 (Super Rod)
- new EncounterStatic { Species = 083, Level = 05, Moves = new [] { 226, 14, 97, 163 }, Version = GameVersion.Stadium2 }, // Stadium 2 Baton Pass Farfetch'd
- new EncounterStatic { Species = 207, Level = 05, Moves = new [] { 89, 68, 17 }, Version = GameVersion.Stadium2 }, // Stadium 2 Earthquake Gligar
+ new EncounterStatic2(083, 05) { Moves = new [] { 226, 14, 97, 163 }, Version = GameVersion.Stadium2 }, // Stadium 2 Baton Pass Farfetch'd
+ new EncounterStatic2(207, 05) { Moves = new [] { 89, 68, 17 }, Version = GameVersion.Stadium2 }, // Stadium 2 Earthquake Gligar
// Gen2 Events
// Pokémon Center Mystery Egg #1 (December 15, 2001 to January 14, 2002)
- new EncounterStatic { Species = 152, Level = 05, Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Chikorita Petal Dance
- new EncounterStatic { Species = 173, Level = 05, Moves = new [] { 129 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Cleffa Swift
- new EncounterStatic { Species = 194, Level = 05, Moves = new [] { 187 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Wooper Belly Drum
- new EncounterStatic { Species = 231, Level = 05, Moves = new [] { 227 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Phanpy Encore
- new EncounterStatic { Species = 238, Level = 05, Moves = new [] { 118 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Smoochum Metronome
+ new EncounterStatic2(152, 05) { Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Chikorita Petal Dance
+ new EncounterStatic2(173, 05) { Moves = new [] { 129 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Cleffa Swift
+ new EncounterStatic2(194, 05) { Moves = new [] { 187 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Wooper Belly Drum
+ new EncounterStatic2(231, 05) { Moves = new [] { 227 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Phanpy Encore
+ new EncounterStatic2(238, 05) { Moves = new [] { 118 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Smoochum Metronome
// Pokémon Center Mystery Egg #2 (March 16 to April 7, 2002)
- new EncounterStatic { Species = 047, Level = 05, Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Psyduck Petal Dance
- // new EncounterStatic { Species = 152, Level = 05, Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Chikorita Petal Dance
- new EncounterStatic { Species = 172, Level = 05, Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Pichu Petal Dance
- new EncounterStatic { Species = 173, Level = 05, Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Cleffa Petal Dance
- new EncounterStatic { Species = 174, Level = 05, Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Igglybuff Petal Dance
- new EncounterStatic { Species = 238, Level = 05, Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Smoochum Petal Dance
+ new EncounterStatic2(047, 05) { Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Psyduck Petal Dance
+ // new EncounterStatic(152, 05, Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Chikorita Petal Dance
+ new EncounterStatic2(172, 05) { Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Pichu Petal Dance
+ new EncounterStatic2(173, 05) { Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Cleffa Petal Dance
+ new EncounterStatic2(174, 05) { Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Igglybuff Petal Dance
+ new EncounterStatic2(238, 05) { Moves = new [] { 080 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Smoochum Petal Dance
// Pokémon Center Mystery Egg #3 (April 27 to May 12, 2002)
- new EncounterStatic { Species = 001, Level = 05, Moves = new [] { 246 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Bulbasaur Ancientpower
- new EncounterStatic { Species = 004, Level = 05, Moves = new [] { 242 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Charmander Crunch
- new EncounterStatic { Species = 158, Level = 05, Moves = new [] { 066 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Totodile Submission
- new EncounterStatic { Species = 163, Level = 05, Moves = new [] { 101 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Hoot-Hoot Night Shade
- new EncounterStatic { Species = 158, Level = 05, Moves = new [] { 047 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Pichu Sing
+ new EncounterStatic2(001, 05) { Moves = new [] { 246 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Bulbasaur Ancientpower
+ new EncounterStatic2(004, 05) { Moves = new [] { 242 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Charmander Crunch
+ new EncounterStatic2(158, 05) { Moves = new [] { 066 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Totodile Submission
+ new EncounterStatic2(163, 05) { Moves = new [] { 101 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Hoot-Hoot Night Shade
+ new EncounterStatic2(158, 05) { Moves = new [] { 047 }, Version = GameVersion.EventsGBGen2, EggLocation = 256 }, // Pichu Sing
};
- private static readonly EncounterStatic[] Encounter_GS_Exclusive =
+ private static readonly EncounterStatic2[] Encounter_GS_Exclusive =
{
- new EncounterStatic { Species = 245, Level = 40, Version = GameVersion.GS }, // Suicune
+ new EncounterStatic2(245, 40) { Version = GameVersion.GS }, // Suicune
- new EncounterStatic { Species = 249, Level = 70, Version = GameVersion.GD }, // Lugia @ Whirl Islands
- new EncounterStatic { Species = 249, Level = 40, Version = GameVersion.SV }, // Lugia @ Whirl Islands
+ new EncounterStatic2(249, 70) { Version = GameVersion.GD }, // Lugia @ Whirl Islands
+ new EncounterStatic2(249, 40) { Version = GameVersion.SV }, // Lugia @ Whirl Islands
- new EncounterStatic { Species = 250, Level = 40, Version = GameVersion.GD }, // Ho-Oh @ Tin Tower
- new EncounterStatic { Species = 250, Level = 70, Version = GameVersion.SV }, // Ho-Oh @ Tin Tower
+ new EncounterStatic2(250, 40) { Version = GameVersion.GD }, // Ho-Oh @ Tin Tower
+ new EncounterStatic2(250, 70) { Version = GameVersion.SV }, // Ho-Oh @ Tin Tower
- new EncounterStatic { Species = 137, Level = 15, Version = GameVersion.GS }, // Porygon @ Celadon Game Corner
- new EncounterStatic { Species = 133, Level = 15, Version = GameVersion.GS }, // Eevee @ Celadon Game Corner
- new EncounterStatic { Species = 122, Level = 15, Version = GameVersion.GS }, // Mr. Mime @ Celadon Game Corner
+ new EncounterStatic2(137, 15) { Version = GameVersion.GS }, // Porygon @ Celadon Game Corner
+ new EncounterStatic2(133, 15) { Version = GameVersion.GS }, // Eevee @ Celadon Game Corner
+ new EncounterStatic2(122, 15) { Version = GameVersion.GS }, // Mr. Mime @ Celadon Game Corner
- new EncounterStatic { Species = 063, Level = 10, Version = GameVersion.GS }, // Abra @ Goldenrod City (Game Corner)
- new EncounterStatic { Species = 147, Level = 10, Version = GameVersion.GS }, // Dratini @ Goldenrod City (Game Corner)
- new EncounterStatic { Species = 023, Level = 10, Version = GameVersion.GS }, // Ekans @ Goldenrod City (Game Corner) (Gold)
- new EncounterStatic { Species = 027, Level = 10, Version = GameVersion.GS }, // Sandshrew @ Goldenrod City (Game Corner) (Silver)
+ new EncounterStatic2(063, 10) { Version = GameVersion.GS }, // Abra @ Goldenrod City (Game Corner)
+ new EncounterStatic2(147, 10) { Version = GameVersion.GS }, // Dratini @ Goldenrod City (Game Corner)
+ new EncounterStatic2(023, 10) { Version = GameVersion.GS }, // Ekans @ Goldenrod City (Game Corner) (Gold)
+ new EncounterStatic2(027, 10) { Version = GameVersion.GS }, // Sandshrew @ Goldenrod City (Game Corner) (Silver)
- new EncounterStatic { Species = 223, Level = 05, Version = GameVersion.GS }, // Remoraid Swarm @ Route 44 (Old Rod)
- new EncounterStatic { Species = 223, Level = 20, Version = GameVersion.GS }, // Remoraid Swarm @ Route 44 (Good Rod)
- new EncounterStatic { Species = 223, Level = 40, Version = GameVersion.GS }, // Remoraid Swarm @ Route 44 (Super Rod)
+ new EncounterStatic2(223, 05) { Version = GameVersion.GS }, // Remoraid Swarm @ Route 44 (Old Rod)
+ new EncounterStatic2(223, 20) { Version = GameVersion.GS }, // Remoraid Swarm @ Route 44 (Good Rod)
+ new EncounterStatic2(223, 40) { Version = GameVersion.GS }, // Remoraid Swarm @ Route 44 (Super Rod)
};
- private static readonly EncounterStatic[] Encounter_C_Exclusive =
+ private static readonly EncounterStatic2[] Encounter_C_Exclusive =
{
- new EncounterStatic { Species = 245, Level = 40, Location = 023, Version = GameVersion.C }, // Suicune @ Tin Tower
+ new EncounterStatic2(245, 40) { Location = 023, Version = GameVersion.C }, // Suicune @ Tin Tower
new EncounterStatic2Odd(172), // Pichu Dizzy Punch
new EncounterStatic2Odd(173), // Cleffa Dizzy Punch
@@ -222,48 +215,48 @@ namespace PKHeX.Core
new EncounterStatic2Odd(239), // Elekid Dizzy Punch
new EncounterStatic2Odd(240), // Magby Dizzy Punch
- new EncounterStatic { Species = 147, Level = 15, Location = 042, Version = GameVersion.C, Moves = new [] {245} }, // Dratini ExtremeSpeed
+ new EncounterStatic2(147, 15) { Location = 042, Version = GameVersion.C, Moves = new [] {245} }, // Dratini ExtremeSpeed
- new EncounterStatic { Species = 249, Level = 60, Location = 031, Version = GameVersion.C }, // Lugia @ Whirl Islands
- new EncounterStatic { Species = 250, Level = 60, Location = 023, Version = GameVersion.C }, // Ho-Oh @ Tin Tower
- new EncounterStatic { Species = 251, Level = 30, Location = 014, Version = GameVersion.C }, // Celebi @ Ilex Forest (VC)
- new EncounterStatic { Species = 251, Level = 30, Location = 014, Version = GameVersion.EventsGBGen2 }, // Celebi @ Ilex Forest (GBC)
+ new EncounterStatic2(249, 60) { Location = 031, Version = GameVersion.C }, // Lugia @ Whirl Islands
+ new EncounterStatic2(250, 60) { Location = 023, Version = GameVersion.C }, // Ho-Oh @ Tin Tower
+ new EncounterStatic2(251, 30) { Location = 014, Version = GameVersion.C }, // Celebi @ Ilex Forest (VC)
+ new EncounterStatic2(251, 30) { Location = 014, Version = GameVersion.EventsGBGen2 }, // Celebi @ Ilex Forest (GBC)
- new EncounterStatic { Species = 137, Level = 15, Location = 071, Version = GameVersion.C }, // Porygon @ Celadon Game Corner
- new EncounterStatic { Species = 025, Level = 25, Location = 071, Version = GameVersion.C }, // Pikachu @ Celadon Game Corner
- new EncounterStatic { Species = 246, Level = 40, Location = 071, Version = GameVersion.C }, // Larvitar @ Celadon Game Corner
+ new EncounterStatic2(137, 15) { Location = 071, Version = GameVersion.C }, // Porygon @ Celadon Game Corner
+ new EncounterStatic2(025, 25) { Location = 071, Version = GameVersion.C }, // Pikachu @ Celadon Game Corner
+ new EncounterStatic2(246, 40) { Location = 071, Version = GameVersion.C }, // Larvitar @ Celadon Game Corner
- new EncounterStatic { Species = 063, Level = 05, Location = 016, Version = GameVersion.C }, // Abra @ Goldenrod City (Game Corner)
- new EncounterStatic { Species = 104, Level = 15, Location = 016, Version = GameVersion.C }, // Cubone @ Goldenrod City (Game Corner)
- new EncounterStatic { Species = 202, Level = 15, Location = 016, Version = GameVersion.C }, // Wobbuffet @ Goldenrod City (Game Corner)
+ new EncounterStatic2(063, 05) { Location = 016, Version = GameVersion.C }, // Abra @ Goldenrod City (Game Corner)
+ new EncounterStatic2(104, 15) { Location = 016, Version = GameVersion.C }, // Cubone @ Goldenrod City (Game Corner)
+ new EncounterStatic2(202, 15) { Location = 016, Version = GameVersion.C }, // Wobbuffet @ Goldenrod City (Game Corner)
};
- private static readonly EncounterStatic[] Encounter_GSC_Roam =
+ private static readonly EncounterStatic2[] Encounter_GSC_Roam =
{
- new EncounterStatic { Species = 243, Level = 40, Roaming = true }, // Raikou
- new EncounterStatic { Species = 244, Level = 40, Roaming = true }, // Entei
- new EncounterStatic { Species = 245, Level = 40, Roaming = true, Version = GameVersion.GS }, // Suicune
+ new EncounterStatic2Roam(243, 40) { Version = GameVersion.GSC }, // Raikou
+ new EncounterStatic2Roam(244, 40) { Version = GameVersion.GSC }, // Entei
+ new EncounterStatic2Roam(245, 40) { Version = GameVersion.GS }, // Suicune
};
- private static readonly EncounterStatic[] Encounter_GS = Encounter_GSC_Common.Concat(Encounter_GS_Exclusive).Concat(Encounter_GSC_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_GSC_Grass))).ToArray();
- private static readonly EncounterStatic[] Encounter_C = Encounter_GSC_Common.Concat(Encounter_C_Exclusive).Concat(Encounter_GSC_Roam.Take(2).SelectMany(e => e.Clone(Roaming_MetLocation_GSC_Grass))).ToArray();
- private static readonly EncounterStatic[] Encounter_GSC = Encounter_GSC_Common.Concat(Encounter_GS_Exclusive).Concat(Encounter_C_Exclusive).Concat(Encounter_GSC_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_GSC_Grass))).ToArray();
+ private static readonly EncounterStatic2[] Encounter_GS = Encounter_GSC_Common.Concat(Encounter_GS_Exclusive).Concat(Encounter_GSC_Roam).ToArray();
+ private static readonly EncounterStatic2[] Encounter_C = Encounter_GSC_Common.Concat(Encounter_C_Exclusive).Concat(Encounter_GSC_Roam.Slice(0, 2)).ToArray();
+ private static readonly EncounterStatic2[] Encounter_GSC = Encounter_GSC_Common.Concat(Encounter_GS_Exclusive).Concat(Encounter_C_Exclusive).Concat(Encounter_GSC_Roam).ToArray();
- internal static readonly EncounterTrade[] TradeGift_GSC =
+ internal static readonly EncounterTradeGB[] TradeGift_GSC =
{
- new EncounterTrade { Species = 095, Level = 03, Gender = 0, TID = 48926, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Onix @ Violet City for Bellsprout [wild]
- new EncounterTrade { Species = 066, Level = 05, Gender = 1, TID = 37460, IVs = new[] {12, 03, 07, 06, 06, 06} }, // Machop @ Goldenrod City for Drowzee [wild 9, hatched egg 5]
- new EncounterTrade { Species = 100, Level = 05, Gender = 2, TID = 29189, IVs = new[] {08, 09, 08, 08, 08, 08} }, // Voltorb @ Olivine City for Krabby [egg]
- new EncounterTrade { Species = 112, Level = 10, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Rhydon @ Blackthorn City for Dragonair [wild]
- new EncounterTrade { Species = 142, Level = 05, Gender = 0, TID = 26491, IVs = new[] {08, 09, 06, 06, 06, 06}, OTGender = 1}, // Aerodactyl @ Route 14 for Chansey [egg]
- new EncounterTrade { Species = 078, Level = 14, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Rapidash @ Pewter City for Gloom [wild]
+ new EncounterTrade2(095, 03, 48926) { Gender = 0, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Onix @ Violet City for Bellsprout [wild]
+ new EncounterTrade2(066, 05, 37460) { Gender = 1, IVs = new[] {12, 03, 07, 06, 06, 06} }, // Machop @ Goldenrod City for Drowzee [wild 9, hatched egg 5]
+ new EncounterTrade2(100, 05, 29189) { Gender = 2, IVs = new[] {08, 09, 08, 08, 08, 08} }, // Voltorb @ Olivine City for Krabby [egg]
+ new EncounterTrade2(112, 10, 00283) { Gender = 1, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Rhydon @ Blackthorn City for Dragonair [wild]
+ new EncounterTrade2(142, 05, 26491) { Gender = 0, IVs = new[] {08, 09, 06, 06, 06, 06}, OTGender = 1}, // Aerodactyl @ Route 14 for Chansey [egg]
+ new EncounterTrade2(078, 14, 15616) { Gender = 0, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Rapidash @ Pewter City for Gloom [wild]
- new EncounterTrade { Species = 085, Level = 10, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06}, OTGender = 1}, // Dodrio @ Blackthorn City for Dragonair [wild]
- new EncounterTrade { Species = 178, Level = 15, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 08, 06, 06} }, // Xatu @ Pewter City for Haunter [wild]
- new EncounterTrade { Species = 082, Level = 05, Gender = 2, TID = 50082, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Magneton @ Power Plant for Dugtrio [traded for Lickitung]
+ new EncounterTrade2(085, 10, 00283) { Gender = 1, IVs = new[] {12, 07, 07, 06, 06, 06}, OTGender = 1}, // Dodrio @ Blackthorn City for Dragonair [wild]
+ new EncounterTrade2(178, 15, 15616) { Gender = 0, IVs = new[] {08, 09, 06, 08, 06, 06} }, // Xatu @ Pewter City for Haunter [wild]
+ new EncounterTrade2(082, 05, 50082) { Gender = 2, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Magneton @ Power Plant for Dugtrio [traded for Lickitung]
- new EncounterTrade { Species = 021, Level = 10, TID = 01001, Moves = new[] {64,45,43} }, // Spearow @ Goldenrod City for free
- new EncounterTrade { Species = 213, Level = 15, TID = 00518 }, // Shuckle @ Cianwood City for free
+ new EncounterTrade2(021, 10, 01001) { Moves = new[] {64,45,43} }, // Spearow @ Goldenrod City for free
+ new EncounterTrade2(213, 15, 00518), // Shuckle @ Cianwood City for free
};
private const string tradeGSC = "tradegsc";
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs
index 8b9055e86..5549dcb50 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic.cs
@@ -156,18 +156,15 @@ namespace PKHeX.Core
pk.EggMetDate = today;
}
- private void SetMetData(PKM pk, int level, DateTime today)
+ protected virtual void SetMetData(PKM pk, int level, DateTime today)
{
- if (pk.Format > 2 || Version == GameVersion.C)
- {
- pk.Met_Location = Location;
- pk.Met_Level = level;
- if (Version == GameVersion.C && pk is PK2 pk2)
- pk2.Met_TimeOfDay = EncounterTime.Any.RandomValidTime();
+ if (pk.Format <= 2)
+ return;
- if (pk.Format >= 4)
- pk.MetDate = today;
- }
+ pk.Met_Location = Location;
+ pk.Met_Level = level;
+ if (pk.Format >= 4)
+ pk.MetDate = today;
}
private void SetEncounterMoves(PKM pk, GameVersion version, int level)
@@ -297,43 +294,13 @@ namespace PKHeX.Core
return Form == pkm.AltForm || Legal.IsFormChangeable(pkm, Species, Form);
}
- private bool IsMatchEggLocation(PKM pkm, ref int lvl)
+ protected virtual bool IsMatchEggLocation(PKM pkm, ref int lvl)
{
if (Generation == 3 && EggLocation != 0) // Gen3 Egg
{
if (pkm.Format == 3 && pkm.IsEgg && EggLocation != pkm.Met_Location)
return false;
}
- else if (Generation <= 2 && EggLocation != 0) // Gen2 Egg
- {
- if (pkm.Format > 2)
- return true;
-
- if (pkm.IsEgg)
- {
- if (pkm.Met_Location != 0 && pkm.Met_Level != 0)
- return false;
- if (pkm.OT_Friendship > EggCycles) // Dizzy Punch eggs start with below-normal hatch counters.
- return false;
- }
- else
- {
- switch (pkm.Met_Level)
- {
- case 0 when pkm.Met_Location != 0:
- return false;
- case 1 when pkm.Met_Location == 0:
- return false;
- default:
- if (pkm.Met_Location == 0 && pkm.Met_Level != 0)
- return false;
- break;
- }
- }
-
- if (pkm.Met_Level == 1) // Gen2 Eggs are met at 1, and hatch at level 5.
- lvl = 5;
- }
else if (EggLocation != pkm.Egg_Location)
{
if (pkm.IsEgg) // unhatched
@@ -353,7 +320,7 @@ namespace PKHeX.Core
if (!Locations.IsPtHGSSLocationEgg(EggLocation)) // non-Pt/HGSS egg gift
return false;
// transferring 4->5 clears pt/hgss location value and keeps Faraway Place
- if (pkm.Egg_Location != 3002) // Faraway Place
+ if (pkm.Egg_Location != Locations.Faraway4) // Faraway Place
return false;
}
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2.cs
new file mode 100644
index 000000000..fa114f889
--- /dev/null
+++ b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Linq;
+
+namespace PKHeX.Core
+{
+ public class EncounterStatic2 : EncounterStatic
+ {
+ public sealed override int Level { get; set; }
+
+ public EncounterStatic2(int species, int level)
+ {
+ Species = species;
+ Level = level;
+ }
+
+ protected override bool IsMatchEggLocation(PKM pkm, ref int lvl)
+ {
+ if (pkm.Format > 2)
+ return true;
+
+ if (pkm.IsEgg)
+ {
+ if (pkm.Met_Location != 0 && pkm.Met_Level != 0)
+ return false;
+ if (pkm.OT_Friendship > EggCycles) // Dizzy Punch eggs start with below-normal hatch counters.
+ return false;
+ }
+ else
+ {
+ switch (pkm.Met_Level)
+ {
+ case 0 when pkm.Met_Location != 0:
+ return false;
+ case 1 when pkm.Met_Location == 0:
+ return false;
+ default:
+ if (pkm.Met_Location == 0 && pkm.Met_Level != 0)
+ return false;
+ break;
+ }
+ }
+
+ if (pkm.Met_Level == 1) // Gen2 Eggs are met at 1, and hatch at level 5.
+ lvl = 5;
+
+ return true;
+ }
+
+ protected override void SetMetData(PKM pk, int level, DateTime today)
+ {
+ pk.Met_Location = Location;
+ pk.Met_Level = level;
+ if (Version == GameVersion.C && pk is PK2 pk2)
+ pk2.Met_TimeOfDay = EncounterTime.Any.RandomValidTime();
+ }
+ }
+
+ public sealed class EncounterStatic2Odd : EncounterStatic2
+ {
+ private const int Dizzy = 146;
+ private static readonly int[] _dizzy = { Dizzy };
+
+ public EncounterStatic2Odd(int species) : base(species, 5)
+ {
+ Version = GameVersion.C;
+ Moves = _dizzy;
+ EggLocation = 256;
+ EggCycles = 20;
+ }
+
+ public override bool IsMatch(PKM pkm, int lvl)
+ {
+ // Let it get picked up as regular EncounterEgg under other conditions.
+ if (pkm.Format > 2)
+ return false;
+ if (pkm.Move1 != Dizzy && pkm.Move2 != Dizzy && pkm.Move3 != Dizzy && pkm.Move4 != Dizzy)
+ return false;
+ if (pkm.IsEgg && pkm.EXP != 125)
+ return false;
+ return base.IsMatch(pkm, lvl);
+ }
+ }
+
+ public sealed class EncounterStatic2Roam : EncounterStatic2
+ {
+ private static readonly int[] Roaming_MetLocation_GSC_Grass =
+ {
+ // Routes 29, 30-31, 33, 34, 35, 36-37, 38-39, 42, 43, 44, 45-46 can be encountered in grass
+ 2, 4, 5, 8, 11, 15, 18, 20, 21,
+ 25, 26, 34, 37, 39, 43, 45,
+ };
+
+ public override int Location => Roaming_MetLocation_GSC_Grass[0];
+
+ public EncounterStatic2Roam(int species, int level) : base(species, level) { }
+
+ protected override bool IsMatchLocation(PKM pkm)
+ {
+ if (!pkm.HasOriginalMetLocation)
+ return true;
+ return Roaming_MetLocation_GSC_Grass.Contains(Location);
+ }
+ }
+}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2Odd.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2Odd.cs
deleted file mode 100644
index 0638f40ca..000000000
--- a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2Odd.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-namespace PKHeX.Core
-{
- public sealed class EncounterStatic2Odd : EncounterStatic
- {
- private const int Dizzy = 146;
- private static readonly int[] _dizzy = { Dizzy };
-
- public EncounterStatic2Odd(int species)
- {
- Species = species;
- Level = 5;
- Version = GameVersion.C;
- Moves = _dizzy;
- EggLocation = 256;
- EggCycles = 20;
- }
-
- public override bool IsMatch(PKM pkm, int lvl)
- {
- // Let it get picked up as regular EncounterEgg under other conditions.
- if (pkm.Format > 2)
- return false;
- if (pkm.Move1 != Dizzy && pkm.Move2 != Dizzy && pkm.Move3 != Dizzy && pkm.Move4 != Dizzy)
- return false;
- if (pkm.IsEgg && pkm.EXP != 125)
- return false;
- return base.IsMatch(pkm, lvl);
- }
- }
-}
\ No newline at end of file
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade.cs
index 3cc0ea30b..c0735ae26 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade.cs
@@ -130,9 +130,6 @@ namespace PKHeX.Core
if (EggLocation != 0)
SetEggMetData(pk, time);
- if (pk is PK1 pk1 && this is EncounterTradeCatchRate c)
- pk1.Catch_Rate = (int) c.Catch_Rate;
-
if (pk is IContestStats s)
this.CopyContestStatsTo(s);
@@ -304,144 +301,5 @@ namespace PKHeX.Core
return true;
}
-
- public bool IsMatchVC1(PKM pkm)
- {
- if (Level > pkm.CurrentLevel) // minimum required level
- return false;
- if (!(pkm is PK1 pk1)|| !pkm.Gen1_NotTradeback)
- return true;
-
- // 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 = pk1.Catch_Rate;
- if (this is EncounterTradeCatchRate r)
- {
- if (rate != r.Catch_Rate)
- return false;
- }
- else
- {
- if (Version == GameVersion.YW && rate != PersonalTable.Y[Species].CatchRate)
- return false;
- if (Version != GameVersion.YW && rate != PersonalTable.RB[Species].CatchRate)
- return false;
- }
- return true;
- }
-
- public bool IsMatchVC2(PKM pkm)
- {
- if (Level > pkm.CurrentLevel) // minimum required level
- return false;
- if (TID != pkm.TID)
- return false;
- if (pkm.Format <= 2)
- {
- if (Gender >= 0 && Gender != pkm.Gender)
- return false;
- if (IVs.Count != 0 && !Legal.GetIsFixedIVSequenceValidNoRand(IVs, pkm))
- return false;
- }
- if (pkm.Met_Location != 0 && pkm.Format == 2 && pkm.Met_Location != 126)
- return false;
-
- if (!IsValidTradeOT12Gender(pkm))
- return false;
- return IsValidTradeOT12(pkm);
- }
-
- private bool IsValidTradeOT12Gender(PKM pkm)
- {
- if (OTGender == 1)
- {
- // Female, can be cleared if traded to RBY (clears met location)
- if (pkm.Format <= 2)
- return pkm.OT_Gender == (pkm.Met_Location != 0 ? 1 : 0);
- return pkm.OT_Gender == 0 || !pkm.VC1; // require male except if transferred from GSC
- }
- return pkm.OT_Gender == 0;
- }
-
- private bool IsValidTradeOT12(PKM pkm)
- {
- var OT = pkm.OT_Name;
- if (pkm.Japanese)
- return TrainerNames[(int)LanguageID.Japanese] == OT;
- if (pkm.Korean)
- return TrainerNames[(int)LanguageID.Korean] == OT;
-
- if (pkm.Format >= 7)
- {
- switch (Species)
- {
- case (int)Core.Species.Voltorb:
- // Spanish FALCÁN trade loses the accented A on transfer
- if (OT == "FALCÁN")
- return false;
- if (OT == "FALC N")
- return true;
- break;
- case (int)Core.Species.Shuckle:
- // Spanish MANÍA trade loses the accented I on transfer
- if (OT == "MANÍA")
- return false;
- if (OT == "MAN A")
- return true;
- break;
- }
- }
-
- const int start = (int)LanguageID.English;
- const int end = (int)LanguageID.Spanish;
-
- for (int i = start; i <= end; i++)
- {
- if (TrainerNames[i] == OT)
- return true;
- }
- return false;
- }
- }
-
- public sealed class EncounterTrade6 : EncounterTrade, IMemoryOT
- {
- public int OT_Memory { get; }
- public int OT_Intensity { get; }
- public int OT_Feeling { get; }
- public int OT_TextVar { get; }
-
- public EncounterTrade6(int m, int i, int f, int v)
- {
- OT_Memory = m;
- OT_Intensity = i;
- OT_Feeling = f;
- OT_TextVar = v;
- }
-
- protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk)
- {
- base.ApplyDetails(sav, criteria, pk);
- pk.OT_Memory = OT_Memory;
- pk.OT_Intensity = OT_Intensity;
- pk.OT_Feeling = OT_Feeling;
- pk.OT_TextVar = OT_TextVar;
- }
- }
-
- public sealed class EncounterTrade7 : EncounterTrade, IMemoryOT
- {
- public int OT_Memory => 1;
- public int OT_Intensity => 3;
- public int OT_Feeling => 5;
- public int OT_TextVar => 40;
-
- protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk)
- {
- base.ApplyDetails(sav, criteria, pk);
- pk.OT_Memory = OT_Memory;
- pk.OT_Intensity = OT_Intensity;
- pk.OT_Feeling = OT_Feeling;
- pk.OT_TextVar = OT_TextVar;
- }
}
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade1.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade1.cs
new file mode 100644
index 000000000..6c53c6839
--- /dev/null
+++ b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade1.cs
@@ -0,0 +1,52 @@
+namespace PKHeX.Core
+{
+ ///
+ /// Trade Encounter data with a fixed Catch Rate
+ ///
+ ///
+ /// Generation 1 specific value used in detecting unmodified/untraded Generation 1 Trade Encounter data.
+ ///
+ public sealed class EncounterTrade1 : EncounterTradeGB
+ {
+ ///
+ /// value the encounter is found with.
+ ///
+ ///
+ /// Gen1 Pokémon have a Catch Rate value when created by the game; depends on the origin version.
+ /// Few encounters use a value not from the game's Personal data.
+ ///
+ private readonly byte Catch_Rate;
+
+ private bool HasOddCatchRate => Catch_Rate != 0;
+
+ public EncounterTrade1(int species, int level, byte rate) : this(species, level) => Catch_Rate = rate;
+ public EncounterTrade1(int species, int level) : base(species, level) { }
+
+ public byte GetInitialCatchRate()
+ {
+ if (HasOddCatchRate)
+ return Catch_Rate;
+
+ var pt = Version == GameVersion.YW ? PersonalTable.Y : PersonalTable.RB;
+ return (byte)pt[Species].CatchRate;
+ }
+
+ protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk)
+ {
+ base.ApplyDetails(sav, criteria, pk);
+ var pk1 = (PK1)pk;
+ pk1.Catch_Rate = GetInitialCatchRate();
+ }
+
+ public override bool IsMatch(PKM pkm)
+ {
+ if (Level > pkm.CurrentLevel) // minimum required level
+ return false;
+ if (!(pkm is PK1 pk1) || !pkm.Gen1_NotTradeback)
+ return true;
+
+ var req = GetInitialCatchRate();
+ return req == pk1.Catch_Rate;
+ }
+ }
+}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade2.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade2.cs
new file mode 100644
index 000000000..3564bd4c1
--- /dev/null
+++ b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade2.cs
@@ -0,0 +1,86 @@
+using static PKHeX.Core.Species;
+
+namespace PKHeX.Core
+{
+ public sealed class EncounterTrade2 : EncounterTradeGB
+ {
+ public EncounterTrade2(int species, int level, int tid) : base(species, level)
+ {
+ TID = tid;
+ }
+
+ public override bool IsMatch(PKM pkm)
+ {
+ if (Level > pkm.CurrentLevel) // minimum required level
+ return false;
+ if (TID != pkm.TID)
+ return false;
+
+ if (pkm.Format <= 2)
+ {
+ if (Gender >= 0 && Gender != pkm.Gender)
+ return false;
+ if (IVs.Count != 0 && !Legal.GetIsFixedIVSequenceValidNoRand(IVs, pkm))
+ return false;
+ if (pkm.Format == 2 && pkm.Met_Location != 0 && pkm.Met_Location != 126)
+ return false;
+ }
+
+ if (!IsValidTradeOTGender(pkm))
+ return false;
+ return IsValidTradeOTName(pkm);
+ }
+
+ private bool IsValidTradeOTGender(PKM pkm)
+ {
+ if (OTGender == 1)
+ {
+ // Female, can be cleared if traded to RBY (clears met location)
+ if (pkm.Format <= 2)
+ return pkm.OT_Gender == (pkm.Met_Location != 0 ? 1 : 0);
+ return pkm.OT_Gender == 0 || !pkm.VC1; // require male except if transferred from GSC
+ }
+ return pkm.OT_Gender == 0;
+ }
+
+ private bool IsValidTradeOTName(PKM pkm)
+ {
+ var OT = pkm.OT_Name;
+ if (pkm.Japanese)
+ return GetOT((int)LanguageID.Japanese) == OT;
+ if (pkm.Korean)
+ return GetOT((int)LanguageID.Korean) == OT;
+
+ if (pkm.Format >= 7)
+ {
+ switch (Species)
+ {
+ case (int)Voltorb:
+ // Spanish FALCÁN trade loses the accented A on transfer
+ if (OT == "FALCÁN")
+ return false;
+ if (OT == "FALC N")
+ return true;
+ break;
+ case (int)Shuckle:
+ // Spanish MANÍA trade loses the accented I on transfer
+ if (OT == "MANÍA")
+ return false;
+ if (OT == "MAN A")
+ return true;
+ break;
+ }
+ }
+
+ const int start = (int)LanguageID.English;
+ const int end = (int)LanguageID.Spanish;
+
+ for (int i = start; i <= end; i++)
+ {
+ if (TrainerNames[i] == OT)
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade6.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade6.cs
new file mode 100644
index 000000000..8d423d9b5
--- /dev/null
+++ b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade6.cs
@@ -0,0 +1,27 @@
+namespace PKHeX.Core
+{
+ public sealed class EncounterTrade6 : EncounterTrade, IMemoryOT
+ {
+ public int OT_Memory { get; }
+ public int OT_Intensity { get; }
+ public int OT_Feeling { get; }
+ public int OT_TextVar { get; }
+
+ public EncounterTrade6(int m, int i, int f, int v)
+ {
+ OT_Memory = m;
+ OT_Intensity = i;
+ OT_Feeling = f;
+ OT_TextVar = v;
+ }
+
+ protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk)
+ {
+ base.ApplyDetails(sav, criteria, pk);
+ pk.OT_Memory = OT_Memory;
+ pk.OT_Intensity = OT_Intensity;
+ pk.OT_Feeling = OT_Feeling;
+ pk.OT_TextVar = OT_TextVar;
+ }
+ }
+}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade7.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade7.cs
new file mode 100644
index 000000000..7e86a4782
--- /dev/null
+++ b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTrade7.cs
@@ -0,0 +1,19 @@
+namespace PKHeX.Core
+{
+ public sealed class EncounterTrade7 : EncounterTrade, IMemoryOT
+ {
+ public int OT_Memory => 1;
+ public int OT_Intensity => 3;
+ public int OT_Feeling => 5;
+ public int OT_TextVar => 40;
+
+ protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk)
+ {
+ base.ApplyDetails(sav, criteria, pk);
+ pk.OT_Memory = OT_Memory;
+ pk.OT_Intensity = OT_Intensity;
+ pk.OT_Feeling = OT_Feeling;
+ pk.OT_TextVar = OT_TextVar;
+ }
+ }
+}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTradeCatchRate.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTradeCatchRate.cs
deleted file mode 100644
index 52b530cab..000000000
--- a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTradeCatchRate.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace PKHeX.Core
-{
- ///
- /// Trade Encounter data with a fixed Catch Rate
- ///
- ///
- /// Generation 1 specific value used in detecting unmodified/untraded Generation 1 Trade Encounter data.
- ///
- public sealed class EncounterTradeCatchRate : EncounterTrade
- {
- ///
- /// value the encounter is found with.
- ///
- public uint Catch_Rate;
- }
-}
\ No newline at end of file
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTradeGB.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTradeGB.cs
new file mode 100644
index 000000000..3725ebece
--- /dev/null
+++ b/PKHeX.Core/Legality/Encounters/EncounterTrade/EncounterTradeGB.cs
@@ -0,0 +1,13 @@
+namespace PKHeX.Core
+{
+ public abstract class EncounterTradeGB : EncounterTrade
+ {
+ public EncounterTradeGB(int species, int level)
+ {
+ Species = species;
+ Level = level;
+ }
+
+ public abstract bool IsMatch(PKM pkm);
+ }
+}
diff --git a/PKHeX.Core/Legality/Encounters/Generator/EncounterTradeGenerator.cs b/PKHeX.Core/Legality/Encounters/Generator/EncounterTradeGenerator.cs
index 60cf53fbf..514a55112 100644
--- a/PKHeX.Core/Legality/Encounters/Generator/EncounterTradeGenerator.cs
+++ b/PKHeX.Core/Legality/Encounters/Generator/EncounterTradeGenerator.cs
@@ -36,7 +36,7 @@ namespace PKHeX.Core
int lvl = IsNotTrade(pkm);
if (lvl <= 0)
- return Enumerable.Empty();
+ return Array.Empty();
var poss = GetPossibleNonVC(pkm, chain, gameSource);
return poss.Where(z => z.IsMatch(pkm, lvl));
@@ -47,26 +47,26 @@ namespace PKHeX.Core
if (gameSource == GameVersion.Any)
gameSource = (GameVersion)pkm.Version;
- if (pkm.VC || pkm.Format <= 2)
+ if (GetIsFromGB(pkm))
return GetValidEncounterTradesVC(pkm, chain, gameSource);
var table = GetEncounterTradeTable(pkm);
return table.Where(f => chain.Any(r => r.Species == f.Species));
}
- private static IEnumerable GetPossibleVC(IReadOnlyList chain, GameVersion gameSource = GameVersion.Any)
+ private static IEnumerable GetPossibleVC(IReadOnlyList chain, GameVersion gameSource = GameVersion.Any)
{
var table = GetEncounterTradeTableVC(gameSource);
- return table.Where(f => chain.Any(r => r.Species == f.Species));
+ return table.Where(f => chain.Any(r => r.Species == f.Species && r.Form == 0));
}
- private static IEnumerable GetEncounterTradeTableVC(GameVersion gameSource)
+ private static IEnumerable GetEncounterTradeTableVC(GameVersion gameSource)
{
if (GameVersion.RBY.Contains(gameSource))
return !ParseSettings.AllowGen1Tradeback ? Encounters1.TradeGift_RBY_NoTradeback : Encounters1.TradeGift_RBY_Tradeback;
if (GameVersion.GSC.Contains(gameSource))
return Encounters2.TradeGift_GSC;
- return Array.Empty();
+ return Array.Empty();
}
private static IEnumerable GetEncounterTradeTable(PKM pkm)
@@ -83,12 +83,10 @@ namespace PKHeX.Core
};
}
- private static IEnumerable GetValidEncounterTradesVC(PKM pkm, IReadOnlyList chain, GameVersion gameSource)
+ private static IEnumerable GetValidEncounterTradesVC(PKM pkm, IReadOnlyList chain, GameVersion gameSource)
{
var poss = GetPossibleVC(chain, gameSource);
- if (gameSource == GameVersion.RBY)
- return poss.Where(z => z.IsMatchVC1(pkm));
- return poss.Where(z => z.IsMatchVC2(pkm));
+ return poss.Where(z => z.IsMatch(pkm));
}
private static bool GetIsFromGB(PKM pkm) => pkm.VC || pkm.Format <= 2;
diff --git a/PKHeX.Core/Legality/Verifiers/MiscVerifier.cs b/PKHeX.Core/Legality/Verifiers/MiscVerifier.cs
index cccf27b7f..ad0065ce4 100644
--- a/PKHeX.Core/Legality/Verifiers/MiscVerifier.cs
+++ b/PKHeX.Core/Legality/Verifiers/MiscVerifier.cs
@@ -135,7 +135,7 @@ namespace PKHeX.Core
CheckResult GetWasNotTradeback()
{
- if ((e is EncounterStatic s && s.Version == GameVersion.Stadium) || e is EncounterTradeCatchRate)
+ if ((e is EncounterStatic s && s.Version == GameVersion.Stadium) || e is EncounterTrade1)
return GetValid(LG1CatchRateMatchPrevious); // Encounters detected by the catch rate, cant be invalid if match this encounters
if ((pk1.Species == 149 && catch_rate == PersonalTable.Y[149].CatchRate) || (GBRestrictions.Species_NotAvailable_CatchRate.Contains(pk1.Species) && catch_rate == PersonalTable.RB[pk1.Species].CatchRate))
return GetInvalid(LG1CatchRateEvo);
diff --git a/PKHeX.WinForms/Controls/PKM Editor/CatchRate.cs b/PKHeX.WinForms/Controls/PKM Editor/CatchRate.cs
index 842195355..3fc705f3d 100644
--- a/PKHeX.WinForms/Controls/PKM Editor/CatchRate.cs
+++ b/PKHeX.WinForms/Controls/PKM Editor/CatchRate.cs
@@ -16,36 +16,7 @@ namespace PKHeX.WinForms.Controls
private void Reset(object sender, EventArgs e)
{
var sav = WinFormsUtil.FindFirstControlOfType(this).RequestSaveFile;
- NUD_CatchRate.Value = GetSuggestedPKMCatchRate(pk1, sav);
- }
-
- private static int GetSuggestedPKMCatchRate(PK1 pk1, SaveFile sav)
- {
- var la = new LegalityAnalysis(pk1);
- if (la.Valid)
- return pk1.Catch_Rate;
-
- if (la.Info.Generation == 2)
- return 0;
-
- var enc = la.EncounterOriginal;
- switch (enc)
- {
- case EncounterTradeCatchRate c:
- return (int)c.Catch_Rate;
- case EncounterStatic s when s.Version == GameVersion.Stadium && s.Species == (int)Species.Psyduck:
- return pk1.Japanese ? 167 : 168; // Amnesia Psyduck has different catch rates depending on language
- case IVersion v:
- {
- if (sav.Version.Contains(v.Version) || v.Version.Contains(sav.Version))
- return sav.Personal[enc.Species].CatchRate;
- if (!GameVersion.RB.Contains(v.Version))
- return PersonalTable.Y[enc.Species].CatchRate;
- return PersonalTable.RB[enc.Species].CatchRate;
- }
- default:
- return sav.Personal[enc.Species].CatchRate;
- }
+ NUD_CatchRate.Value = CatchRateApplicator.GetSuggestedPKMCatchRate(pk1, sav);
}
}
}