Abstract some gen1/2 encounter types from their parent class

This commit is contained in:
Kurt 2020-07-18 15:36:30 -05:00
parent 8fae396b76
commit 705822c965
17 changed files with 491 additions and 411 deletions

View file

@ -0,0 +1,40 @@
namespace PKHeX.Core
{
/// <summary>
/// Logic for applying a <see cref="PK1.Catch_Rate"/> value.
/// </summary>
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;
}
}
}
}
}

View file

@ -252,7 +252,7 @@ namespace PKHeX.Core
return result;
}
internal static void MarkEncounterTradeStrings(EncounterTrade[] table, string[][] strings)
internal static void MarkEncounterTradeStrings<T>(T[] table, string[][] strings) where T : EncounterTrade
{
int half = strings[1].Length / 2;
for (int i = 0; i < half; i++)

View file

@ -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 }, // Farfetchd - 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 }, // Farfetchd - 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 }, // Farfetchd - 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

View file

@ -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";

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}
}

View file

@ -0,0 +1,52 @@
namespace PKHeX.Core
{
/// <summary>
/// Trade Encounter data with a fixed Catch Rate
/// </summary>
/// <remarks>
/// Generation 1 specific value used in detecting unmodified/untraded Generation 1 Trade Encounter data.
/// </remarks>
public sealed class EncounterTrade1 : EncounterTradeGB
{
/// <summary>
/// <see cref="PK1.Catch_Rate"/> value the encounter is found with.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
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;
}
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}

View file

@ -1,16 +0,0 @@
namespace PKHeX.Core
{
/// <summary>
/// Trade Encounter data with a fixed Catch Rate
/// </summary>
/// <remarks>
/// Generation 1 specific value used in detecting unmodified/untraded Generation 1 Trade Encounter data.
/// </remarks>
public sealed class EncounterTradeCatchRate : EncounterTrade
{
/// <summary>
/// <see cref="PK1.Catch_Rate"/> value the encounter is found with.
/// </summary>
public uint Catch_Rate;
}
}

View file

@ -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);
}
}

View file

@ -36,7 +36,7 @@ namespace PKHeX.Core
int lvl = IsNotTrade(pkm);
if (lvl <= 0)
return Enumerable.Empty<EncounterTrade>();
return Array.Empty<EncounterTrade>();
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<EncounterTrade> GetPossibleVC(IReadOnlyList<DexLevel> chain, GameVersion gameSource = GameVersion.Any)
private static IEnumerable<EncounterTradeGB> GetPossibleVC(IReadOnlyList<DexLevel> 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<EncounterTrade> GetEncounterTradeTableVC(GameVersion gameSource)
private static IEnumerable<EncounterTradeGB> 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<EncounterTrade>();
return Array.Empty<EncounterTradeGB>();
}
private static IEnumerable<EncounterTrade> GetEncounterTradeTable(PKM pkm)
@ -83,12 +83,10 @@ namespace PKHeX.Core
};
}
private static IEnumerable<EncounterTrade> GetValidEncounterTradesVC(PKM pkm, IReadOnlyList<DexLevel> chain, GameVersion gameSource)
private static IEnumerable<EncounterTradeGB> GetValidEncounterTradesVC(PKM pkm, IReadOnlyList<DexLevel> 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;

View file

@ -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);

View file

@ -16,36 +16,7 @@ namespace PKHeX.WinForms.Controls
private void Reset(object sender, EventArgs e)
{
var sav = WinFormsUtil.FindFirstControlOfType<IMainEditor>(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);
}
}
}